diff --git a/packages/livedata/livedata_server.js b/packages/livedata/livedata_server.js
index 769b99ada0..62273ecfb6 100644
--- a/packages/livedata/livedata_server.js
+++ b/packages/livedata/livedata_server.js
@@ -765,7 +765,7 @@ _.extend(Meteor._LivedataServer.prototype, {
var invocation = new Meteor._MethodInvocation(false /* is_simulation */);
try {
var ret = Meteor._CurrentInvocation.withValue(invocation, function () {
- return handler.apply(invocation, args)
+ return handler.apply(invocation, args);
});
} catch (e) {
var exception = e;
diff --git a/packages/madewith/madewith.css b/packages/madewith/madewith.css
new file mode 100644
index 0000000000..4257396e81
--- /dev/null
+++ b/packages/madewith/madewith.css
@@ -0,0 +1,43 @@
+/* CSS declarations go here */
+a.madewith_badge {
+ text-decoration: none;
+ z-index: 10000;
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+ display: block;
+ position: absolute;
+ top: 0;
+ right: 0;
+ width: 280px;
+ height: 32px;
+ background-repeat: no-repeat;
+ background-position: left top;
+ font-weight: bold;
+}
+
+.madewith_upvote {
+ position: absolute;
+ top: 2px;
+ bottom: 2px;
+ left: 205px;
+ width: 26px;
+ cursor: pointer;
+ background-repeat: no-repeat;
+ background-position: 100px 100px; /* hidden */
+}
+
+.madewith_upvote:hover {
+ background-position: 5px 3px;
+}
+
+.madewith_vote_count {
+ position: absolute;
+ top: 2px;
+ bottom: 2px;
+ right: 2px;
+ width: 52px;
+ text-align: center;
+ overflow: visible;
+ color: #fff;
+ line-height: 28px;
+ font-size: 18px;
+}
\ No newline at end of file
diff --git a/packages/madewith/madewith.html b/packages/madewith/madewith.html
new file mode 100644
index 0000000000..8bae7acd66
--- /dev/null
+++ b/packages/madewith/madewith.html
@@ -0,0 +1,12 @@
+
+ {{> madewith}}
+
+
+
+
+
+
+
diff --git a/packages/madewith/madewith.js b/packages/madewith/madewith.js
new file mode 100644
index 0000000000..f3f6bddd67
--- /dev/null
+++ b/packages/madewith/madewith.js
@@ -0,0 +1,41 @@
+(function () {
+// automatically capture this app's hostname
+ var hostname = window.location.host;
+ var match = hostname.match(/(.*)\.meteor.com$/);
+ var shortname = match ? match[1] : hostname;
+
+ // connect to madewith and subscribe to my app's record
+ var server = Meteor.connect("http://madewith.meteor.com/sockjs");
+ var sub = server.subscribe("myApp", hostname);
+
+ // minimongo collection to hold my singleton app record.
+ var apps = new Meteor.Collection('madewith_apps', server);
+
+ server.methods({
+ vote: function (hostname) {
+ apps.update({name: hostname}, {$inc: {vote_count: 1}});
+ }
+ });
+
+ Template.madewith.vote_count = function() {
+ var app = apps.findOne();
+ return app ? app.vote_count : '???';
+ };
+
+ Template.madewith.shortname = function () {
+ return shortname;
+ };
+
+ Template.madewith.events = {
+ 'click .madewith_upvote': function(event) {
+ var app = apps.findOne();
+ if (app) {
+ server.call('vote', hostname);
+ // stop these so you don't click through the link to go to the
+ // app.
+ event.stopPropagation();
+ event.preventDefault();
+ }
+ }
+ };
+})();
\ No newline at end of file
diff --git a/packages/madewith/madewith_badge.css b/packages/madewith/madewith_badge.css
new file mode 100644
index 0000000000..43f70b4a32
--- /dev/null
+++ b/packages/madewith/madewith_badge.css
@@ -0,0 +1,7 @@
+.madewith_badge {
+ background-image:url(data:image/png;base64,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);
+}
+
+.madewith_upvote {
+ background-image:url(data:image/png;base64,R0lGODlhEQAXALMAACFogkiDcvL2CZe4TLnQLzR1d8zcJdXjG8zcHmiYdGOVXOHrFf3+AS9yoP//AAtZjyH5BAAAAAAALAAAAAARABcAAASO8LVHaRil0im1Es6RVRz3fE4qklLjJmCaGoHrdsEi7wTQSQXdjvcLIIbIwQQwQCIZg0cg5twZpAyZIJuiOgyAhPAw4H4HMUIDQAgVCmYEQJGNPhKrQNynQCQ2FXoyciw/WIM+gIaCKYSKJowOjh02L2YHNZWLZmCFkDuTJRVwMp2PGk0OAgoaoh4DARodEQA7);
+}
diff --git a/packages/madewith/package.js b/packages/madewith/package.js
new file mode 100644
index 0000000000..2e5eb8e4df
--- /dev/null
+++ b/packages/madewith/package.js
@@ -0,0 +1,13 @@
+Package.describe({
+ summary: "Made With Meteor badge"
+});
+
+Package.on_use(function (api) {
+ api.use(['livedata', 'underscore', 'liveui', 'templating'], 'client');
+
+ api.add_files([
+ 'madewith.css',
+ 'madewith_badge.css',
+ 'madewith.html',
+ 'madewith.js'], 'client');
+});