Advertisement
SimaKyr

base.js in scratch

Oct 15th, 2018
181
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. function setCue(a, b, c) {
  2.   $.withCSRF(function(d) {
  3.     $.ajax({url:"/site-api/users/set-template-cue/", type:"POST", data:JSON.stringify({cue:a, value:b, csrftoken:d})}).done(c).error(function(d, e, f) {
  4.       document.cookie = "cue_" + a + "=" + b;
  5.       c(d, e, f);
  6.     });
  7.   });
  8. }
  9. function openDialogue(a, b) {
  10.   $(a).dialog(b);
  11. }
  12. function openResendDialogue() {
  13.   var a = {title:gettext("Want to share on Scratch?"), open:function(a, c) {
  14.     var b = this;
  15.     $("#close-resend-dialog").off();
  16.     $("#close-resend-dialog").click(function() {
  17.       $(b).dialog("close");
  18.     });
  19.     $("#email-resend-box form").submit(function(a) {
  20.       a.preventDefault();
  21.       $.ajax({url:"/accounts/email_resend/", type:"POST", data:{email_address:$("#hidden-email-address").val()}, success:function(a) {
  22.         $("#submit-resend", b).attr("disabled", "disabled");
  23.         $("#submit-resend", b).val("Resent");
  24.       }});
  25.     });
  26.     $("#email-resend-box :link").blur();
  27.   }, close:function(a, c) {
  28.     $(this).dialog("destroy");
  29.     $(".ui-widget-overlay.ui-front").remove();
  30.   }, show:{effect:"clip", duration:250}, hide:{effect:"clip", duration:250}};
  31.   0 < $("#email-resend-box").length ? openDialogue("#email-resend-box", a) : $.ajax({url:"/accounts/email_resend/"}).done(function(b) {
  32.     b = $(_.template(b)());
  33.     openDialogue(b, a);
  34.   });
  35. }
  36. !function(a) {
  37.   var b = function(a, b) {
  38.     this.init("tooltip", a, b);
  39.   };
  40.   b.prototype = {constructor:b, init:function(b, c, e) {
  41.     var d, g;
  42.     this.type = b;
  43.     this.$element = a(c);
  44.     this.options = this.getOptions(e);
  45.     this.enabled = !0;
  46.     b = this.options.trigger.split(" ");
  47.     for (e = b.length; e--;) {
  48.       c = b[e], "click" == c ? this.$element.on("click." + this.type, this.options.selector, a.proxy(this.toggle, this)) : "manual" != c && (d = "hover" == c ? "mouseenter" : "focus", g = "hover" == c ? "mouseleave" : "blur", this.$element.on(d + "." + this.type, this.options.selector, a.proxy(this.enter, this)), this.$element.on(g + "." + this.type, this.options.selector, a.proxy(this.leave, this)));
  49.     }
  50.     this.options.selector ? this._options = a.extend({}, this.options, {trigger:"manual", selector:""}) : this.fixTitle();
  51.   }, getOptions:function(b) {
  52.     return b = a.extend({}, a.fn[this.type].defaults, this.$element.data(), b), b.delay && "number" == typeof b.delay && (b.delay = {show:b.delay, hide:b.delay}), b;
  53.   }, enter:function(b) {
  54.     var d = a.fn[this.type].defaults, c = {};
  55.     this._options && a.each(this._options, function(a, b) {
  56.       d[a] != b && (c[a] = b);
  57.     }, this);
  58.     var f = a(b.currentTarget)[this.type](c).data(this.type);
  59.     if (!f.options.delay || !f.options.delay.show) {
  60.       return f.show();
  61.     }
  62.     clearTimeout(this.timeout);
  63.     f.hoverState = "in";
  64.     this.timeout = setTimeout(function() {
  65.       "in" == f.hoverState && f.show();
  66.     }, f.options.delay.show);
  67.   }, leave:function(b) {
  68.     var d = a(b.currentTarget)[this.type](this._options).data(this.type);
  69.     this.timeout && clearTimeout(this.timeout);
  70.     if (!d.options.delay || !d.options.delay.hide) {
  71.       return d.hide();
  72.     }
  73.     d.hoverState = "out";
  74.     this.timeout = setTimeout(function() {
  75.       "out" == d.hoverState && d.hide();
  76.     }, d.options.delay.hide);
  77.   }, show:function() {
  78.     var b = a.Event("show");
  79.     if (this.hasContent() && this.enabled && (this.$element.trigger(b), !b.isDefaultPrevented())) {
  80.       var c = this.tip();
  81.       this.setContent();
  82.       this.options.animation && c.addClass("fade");
  83.       var e = "function" == typeof this.options.placement ? this.options.placement.call(this, c[0], this.$element[0]) : this.options.placement;
  84.       c.detach().css({top:0, left:0, display:"block"});
  85.       this.options.container ? c.appendTo(this.options.container) : c.insertAfter(this.$element);
  86.       b = this.getPosition();
  87.       var f = c[0].offsetWidth;
  88.       c = c[0].offsetHeight;
  89.       switch(e) {
  90.         case "bottom":
  91.           var h = {top:b.top + b.height, left:b.left + b.width / 2 - f / 2};
  92.           break;
  93.         case "top":
  94.           h = {top:b.top - c, left:b.left + b.width / 2 - f / 2};
  95.           break;
  96.         case "left":
  97.           h = {top:b.top + b.height / 2 - c / 2, left:b.left - f};
  98.           break;
  99.         case "right":
  100.           h = {top:b.top + b.height / 2 - c / 2, left:b.left + b.width};
  101.       }
  102.       this.applyPlacement(h, e);
  103.       this.$element.trigger("shown");
  104.     }
  105.   }, applyPlacement:function(a, b) {
  106.     var c = this.tip(), d = c[0].offsetWidth, g = c[0].offsetHeight, k, n;
  107.     c.offset(a).addClass(b).addClass("in");
  108.     var m = c[0].offsetWidth;
  109.     var l = c[0].offsetHeight;
  110.     "top" == b && l != g && (a.top = a.top + g - l, n = !0);
  111.     "bottom" == b || "top" == b ? (k = 0, 0 > a.left && (k = -2 * a.left, a.left = 0, c.offset(a), m = c[0].offsetWidth), this.replaceArrow(k - d + m, m, "left")) : this.replaceArrow(l - g, l, "top");
  112.     n && c.offset(a);
  113.   }, replaceArrow:function(a, b, c) {
  114.     this.arrow().css(c, a ? 50 * (1 - a / b) + "%" : "");
  115.   }, setContent:function() {
  116.     var a = this.tip(), b = this.getTitle();
  117.     a.find(".tooltip-inner")[this.options.html ? "html" : "text"](b);
  118.     a.removeClass("fade in top bottom left right");
  119.   }, hide:function() {
  120.     function b() {
  121.       var b = setTimeout(function() {
  122.         c.off(a.support.transition.end).detach();
  123.       }, 500);
  124.       c.one(a.support.transition.end, function() {
  125.         clearTimeout(b);
  126.         c.detach();
  127.       });
  128.     }
  129.     var c = this.tip(), e = a.Event("hide");
  130.     this.$element.trigger(e);
  131.     if (!e.isDefaultPrevented()) {
  132.       return c.removeClass("in"), a.support.transition && this.$tip.hasClass("fade") ? b() : c.detach(), this.$element.trigger("hidden"), this;
  133.     }
  134.   }, fixTitle:function() {
  135.     var a = this.$element;
  136.     (a.attr("title") || "string" != typeof a.attr("data-original-title")) && a.attr("data-original-title", a.attr("title") || "").attr("title", "");
  137.   }, hasContent:function() {
  138.     return this.getTitle();
  139.   }, getPosition:function() {
  140.     var b = this.$element[0];
  141.     return a.extend({}, "function" == typeof b.getBoundingClientRect ? b.getBoundingClientRect() : {width:b.offsetWidth, height:b.offsetHeight}, this.$element.offset());
  142.   }, getTitle:function() {
  143.     var a, b = this.$element, c = this.options;
  144.     return a = b.attr("data-original-title") || ("function" == typeof c.title ? c.title.call(b[0]) : c.title), a;
  145.   }, tip:function() {
  146.     return this.$tip = this.$tip || a(this.options.template);
  147.   }, arrow:function() {
  148.     return this.$arrow = this.$arrow || this.tip().find(".tooltip-arrow");
  149.   }, validate:function() {
  150.     this.$element[0].parentNode || (this.hide(), this.$element = null, this.options = null);
  151.   }, enable:function() {
  152.     this.enabled = !0;
  153.   }, disable:function() {
  154.     this.enabled = !1;
  155.   }, toggleEnabled:function() {
  156.     this.enabled = !this.enabled;
  157.   }, toggle:function(b) {
  158.     b = b ? a(b.currentTarget)[this.type](this._options).data(this.type) : this;
  159.     b.tip().hasClass("in") ? b.hide() : b.show();
  160.   }, destroy:function() {
  161.     this.hide().$element.off("." + this.type).removeData(this.type);
  162.   }};
  163.   var c = a.fn.tooltip;
  164.   a.fn.tooltip = function(c) {
  165.     return this.each(function() {
  166.       var d = a(this), e = d.data("tooltip"), f = "object" == typeof c && c;
  167.       e || d.data("tooltip", e = new b(this, f));
  168.       "string" == typeof c && e[c]();
  169.     });
  170.   };
  171.   a.fn.tooltip.Constructor = b;
  172.   a.fn.tooltip.defaults = {animation:!0, placement:"top", selector:!1, template:'<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>', trigger:"hover focus", title:"", delay:0, html:!1, container:!1};
  173.   a.fn.tooltip.noConflict = function() {
  174.     return a.fn.tooltip = c, this;
  175.   };
  176. }(window.jQuery);
  177. !function(a) {
  178.   var b = function(a, b) {
  179.     this.init("popover", a, b);
  180.   };
  181.   b.prototype = a.extend({}, a.fn.tooltip.Constructor.prototype, {constructor:b, setContent:function() {
  182.     var a = this.tip(), b = this.getTitle(), c = this.getContent();
  183.     a.find(".popover-title")[this.options.html ? "html" : "text"](b);
  184.     a.find(".popover-content")[this.options.html ? "html" : "text"](c);
  185.     a.removeClass("fade top bottom left right in");
  186.   }, hasContent:function() {
  187.     return this.getTitle() || this.getContent();
  188.   }, getContent:function() {
  189.     var a, b = this.$element, c = this.options;
  190.     return a = ("function" == typeof c.content ? c.content.call(b[0]) : c.content) || b.attr("data-content"), a;
  191.   }, tip:function() {
  192.     return this.$tip || (this.$tip = a(this.options.template)), this.$tip;
  193.   }, destroy:function() {
  194.     this.hide().$element.off("." + this.type).removeData(this.type);
  195.   }});
  196.   var c = a.fn.popover;
  197.   a.fn.popover = function(c) {
  198.     return this.each(function() {
  199.       var d = a(this), e = d.data("popover"), f = "object" == typeof c && c;
  200.       e || d.data("popover", e = new b(this, f));
  201.       "string" == typeof c && e[c]();
  202.     });
  203.   };
  204.   a.fn.popover.Constructor = b;
  205.   a.fn.popover.defaults = a.extend({}, a.fn.tooltip.defaults, {placement:"right", trigger:"click", content:"", template:'<div class="popover"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'});
  206.   a.fn.popover.noConflict = function() {
  207.     return a.fn.popover = c, this;
  208.   };
  209. }(window.jQuery);
  210. Backbone.View.prototype.close = function(a) {
  211.   a = a || {};
  212.   a.persist || this.remove();
  213.   this.unbind();
  214.   this.undelegateEvents();
  215.   this.onClose && this.onClose();
  216. };
  217. Backbone.View.prototype.open = function(a) {
  218.   this.initialize();
  219.   this.model.fetch();
  220.   this.delegateEvents();
  221. };
  222. Backbone.View.prototype._super = function(a) {
  223.   var b = this.constructor.__super__[a];
  224.   return "function" == typeof b ? b.apply(this, _.rest(arguments)) : b;
  225. };
  226. var Scratch = Scratch || {};
  227. Scratch.Model = Backbone.Model.extend({initialize:function(a, b) {
  228.   _.bindAll(this, "report");
  229.   if (b && b.related) {
  230.     this.related = b.related;
  231.     var c = this;
  232.     $.each(this.related, function(a, b) {
  233.       b.parentModel = c;
  234.     });
  235.   }
  236.   this.init(b);
  237. }, url:function() {
  238.   return this.urlRoot + this.getId() + "/";
  239. }, getId:function() {
  240.   return this.slug ? this.get(this.slug) : this.id;
  241. }, init:function(a) {
  242. }, parse:function(a) {
  243.   return a.fields ? $.extend(a.fields, {id:a.pk}) : a;
  244. }, create:function(a) {
  245.   return a = a || {}, a.url = this.urlRoot + "create/", this.isNew() ? (a.error || (a.error = function() {
  246.     console.error && console.error("in model.create, error arguments:", arguments);
  247.   }), Backbone.sync("create", this, a), !0) : !1;
  248. }, fetchRelated:function(a) {
  249.   a ? this.related[a].fetch() : $.each(this.related, function(a, c) {
  250.     c.fetch();
  251.   });
  252. }, report:function(a, b) {
  253.   a || (a = {});
  254.   var c = this.url() + "report/";
  255.   $.ajax(c, {type:"POST", data:JSON.stringify(a), dataType:"json", success:b});
  256. }});
  257. Scratch.Collection = Backbone.Collection.extend({paginationData:{page:1, ascsort:"", descsort:""}, hasMore:!0, count:0, url:function() {
  258.   var a = this.urlRoot;
  259.   return a += this.options.collectionType ? this.options.collectionType + "/" : "", a += this.parentModel ? this.parentModel.getId() + "/" : "", a;
  260. }, addItems:function(a, b) {
  261.   b = b || {};
  262.   var c = this.slug ? this.slug + "s" : "pks", d = _.isArray(a) ? a.length : 1;
  263.   a = _.isArray(a) ? a.join(",") : a;
  264.   b.url = this.url() + "add/?" + c + "=" + a;
  265.   var g = b.success, e = this;
  266.   b.success = function(a, b, c) {
  267.     e.add(a);
  268.     g && g(this, a);
  269.     e.trigger("addItemsSuccess", d);
  270.   };
  271.   Backbone.sync("update", this.parentModel, b);
  272. }, removeItems:function(a, b) {
  273.   b = b || {};
  274.   var c = this.slug ? this.slug + "s" : "pks", d = _.isArray(a) ? a.length : 1;
  275.   a = _.isArray(a) ? a.join(",") : a;
  276.   b.url = this.url() + "remove/?" + c + "=" + a;
  277.   var g = b.success, e = this;
  278.   b.success = function(a, b, c) {
  279.     b = [];
  280.     for (i = 0; i < a.length; i++) {
  281.       b[i] = a[i].id;
  282.     }
  283.     e.remove(b);
  284.     g && g(this, a);
  285.     e.trigger("removeItemsSuccess", d);
  286.   };
  287.   Backbone.sync("update", this.parentModel, b);
  288. }, loadMore:function(a) {
  289.   if (!this.hasMore) {
  290.     return !1;
  291.   }
  292.   a = a || {};
  293.   this.paginationData.page += 1;
  294.   var b = this, c = a.error || {};
  295.   a.error = function(a, g, e) {
  296.     b.hasMore = !1;
  297.     c();
  298.   };
  299.   a.add = !0;
  300.   a.data = this.paginationData;
  301.   this.fetch(a);
  302. }, ajaxSort:function(a, b) {
  303.   b = b || {};
  304.   this.paginationData.page = 1;
  305.   $.extend(this.paginationData, a);
  306.   b.data = this.paginationData;
  307.   b.add = !1;
  308.   this.fetch(b);
  309. }, ajaxFilter:function(a, b) {
  310.   self.hasMore = !0;
  311.   b = b || {};
  312.   this.paginationData.page = 1;
  313.   this.options.collectionType = a;
  314.   b.data = this.paginationData;
  315.   b.add = !1;
  316.   this.fetch(b);
  317. }});
  318. Scratch = Scratch || {};
  319. Scratch.Utils = {};
  320. Scratch.Utils.viewMixin = function(a) {
  321.   var b = this.prototype;
  322.   _.defaults(b, a);
  323.   _.defaults(b.events, a.events);
  324.   Scratch.Utils.extendMethod(b, a, "initialize");
  325.   Scratch.Utils.extendMethod(b, a, "render");
  326. };
  327. Scratch.Utils.extendMethod = function(a, b, c) {
  328.   if (!_.isUndefined(b[c])) {
  329.     var d = a[c];
  330.     a[c] = function() {
  331.       var a = d.apply(this, arguments);
  332.       return b[c].apply(this, arguments), a;
  333.     };
  334.   }
  335. };
  336. Backbone.View.mixin = Scratch.Utils.viewMixin;
  337. Scratch.Mixins = Scratch.Mixins || {};
  338. Scratch.Mixins.Followable = {events:{'click [data-control="follow"]':"follow", 'click [data-control="unfollow"]':"unfollow"}, initialize:function() {
  339.   _.bindAll(this, "followed");
  340.   _.bindAll(this, "unfollowed");
  341. }, follow:function() {
  342.   this.model.related.followers.addItems(Scratch.LoggedInUser.get("username"), {success:this.followed, error:this.onFollowError});
  343. }, followed:function(a, b) {
  344.   this.$('[data-control="follow"]').removeClass("blue notfollowing").addClass("grey following").attr("data-control", "unfollow");
  345.   this.onFollowSuccess(a, b);
  346. }, onFollowSuccess:function(a, b) {
  347.   Scratch.AlertView.msg($("#alert-view"), {alert:"success", msg:Scratch.ALERT_MSGS.followed});
  348. }, onFollowError:function(a, b) {
  349.   Scratch.AlertView.msg($("#alert-view"), {alert:"error", msg:a.responseJSON[0].errors.join(",")});
  350. }, unfollow:function(a, b) {
  351.   this.model.related.followers.removeItems(Scratch.LoggedInUser.get("username"), {success:this.unfollowed});
  352. }, unfollowed:function(a, b) {
  353.   this.$('[data-control="unfollow"]').removeClass("grey following").addClass("blue notfollowing").attr("data-control", "follow");
  354.   this.onUnfollowSuccess(a, b);
  355. }, onUnfollowSuccess:function(a, b) {
  356.   Scratch.AlertView.msg($("#alert-view"), {alert:"success", msg:Scratch.ALERT_MSGS.unfollowed});
  357. }};
  358. Scratch.ModelView = Backbone.View.extend({initialize:function(a, b) {
  359.   this.model.bind("error", this.onError, this);
  360.   this.model.bind("changeSuccess", this.onChangeSuccess, this);
  361. }, onError:function(a) {
  362.   Scratch.AlertView.msg($("#alert-view"), {alert:"error", msg:Scratch.ALERT_MSGS.error});
  363. }, onChangeSuccess:function(a) {
  364.   Scratch.AlertView.msg($("#alert-view"), {alert:"success", msg:Scratch.ALERT_MSGS["changes-saved"]});
  365. }});
  366. Scratch.CollectionView = Backbone.View.extend({events:{'click [data-control="load-more"]':"loadMore", 'click [data-control="sort"]':"sort", 'click [data-control="filter"]':"filter", 'click [data-control="remove-item"]':"removeItem"}, initialize:function(a) {
  367.   this.options = a || {};
  368.   if (this.options.template || this.options.collectionTemplate) {
  369.     this.wrapperTemplate = this.options.template, this.listTemplate = this.options.collectionTemplate;
  370.   }
  371.   this.model.bind("add", this.render, this);
  372.   this.model.bind("remove", this.render, this);
  373.   this.model.bind("remove", this.onRemove, this);
  374.   this.model.bind("reset", this.render, this);
  375.   this.model.bind("addItemsSuccess", this.onAddSuccess, this);
  376.   this.model.bind("removeItemsSuccess", this.onRemoveSuccess, this);
  377.   this.model.bind("error", this.onError, this);
  378.   this.wrapperTemplate && $(this.el).html(this.wrapperTemplate({collection:[]}));
  379. }, onClose:function() {
  380.   this.model.unbind("add", this.render);
  381.   this.model.unbind("remove", this.render);
  382.   this.model.unbind("remove", this.onRemove);
  383.   this.model.unbind("reset", this.render);
  384.   this.model.unbind("addItemsSuccess", this.onAddSuccess);
  385.   this.model.unbind("removeItemsSuccess", this.onRemoveSuccess);
  386.   this.model.unbind("error", this.onError);
  387. }, render:function() {
  388.   return this.renderCollection(), this;
  389. }, renderCollection:function() {
  390.   this.$('[data-content="collection"]').html(this.listTemplate({collection:this.model.toJSON()}));
  391. }, removeItem:function(a) {
  392.   this.model.removeItems([$(a.currentTarget).parent(["data-id"]).data("id")]);
  393. }, loadMore:function(a) {
  394.   var b = this, c = $(a.currentTarget).addClass("loading");
  395.   b.model.loadMore({success:function() {
  396.     b.render();
  397.     c.removeClass("loading");
  398.   }, error:function(a) {
  399.     c.remove();
  400.   }});
  401. }, sort:function(a) {
  402.   a = {ascsort:$(a.target).data("ascsort") || "", descsort:$(a.target).data("descsort") || ""};
  403.   this.model.ajaxSort(a);
  404. }, filter:function(a) {
  405.   this.model.ajaxFilter($(a.target).data("filter"));
  406. }, onRemove:function(a) {
  407. }, onAdd:function(a) {
  408. }, onError:function(a) {
  409.   Scratch.AlertView.msg($("#alert-view"), {alert:"error", msg:Scratch.ALERT_MSGS.error});
  410. }});
  411. Scratch.ExploreBar = Scratch.CollectionView.extend({events:function() {
  412.   return _.extend({}, Scratch.CollectionView.prototype.events, {'click [data-control="open"]':"openBar", 'click [data-control="close"]':"closeBar", "click #explore-buttons":"stopEvent", 'click [data-control="next"]':"next", 'click [data-control="prev"]':"prev", 'click [data-control="draggable"]':"itemClicked", 'click [data-control="open-explore-bar"]':"openBar"});
  413. }, initialize:function(a) {
  414.   Scratch.CollectionView.prototype.initialize.apply(this, [a]);
  415.   this.model.unbind("add");
  416.   this.$scrollArea = this.$(".carousel-inner ul");
  417.   this.$arrowLeft = this.$(".arrow-left");
  418.   this.$arrowRight = this.$(".arrow-right");
  419.   _.bindAll(this, "openBar", "preLoadSuccess", "preLoadError");
  420.   Scratch.EventMgr = Scratch.EventMgr || _.extend({}, Backbone.Events);
  421.   Scratch.EventMgr.on("explore-open", this.openBar, this);
  422. }, render:function() {
  423.   Scratch.CollectionView.prototype.render.apply(this);
  424.   this.$items = this.$(".carousel-inner li");
  425.   this.$scrollArea.width(this.$items.outerWidth(!0) * this.model.length);
  426.   this.scrollPageWidth = this.$(".carousel-inner").width() + parseInt(this.$items.css("padding-right"), 10) - 10;
  427.   this.scrollMax = this.$scrollArea.width() - this.scrollPageWidth;
  428. }, next:function() {
  429.   if (!this.sliding) {
  430.     return this.slide("next");
  431.   }
  432. }, prev:function() {
  433.   if (!this.sliding) {
  434.     return this.slide("prev");
  435.   }
  436. }, toggleArrows:function(a) {
  437.   0 >= a ? this.$arrowLeft.addClass("off").removeClass("on") : a >= this.scrollMax ? this.$arrowRight.addClass("off").removeClass("on") : (this.$arrowRight.removeClass("off").addClass("on"), this.$arrowLeft.removeClass("off").addClass("on"));
  438. }, slide:function(a) {
  439.   var b = "start" == a ? 0 : this.$(".carousel-inner").scrollLeft() + ("next" == a ? this.scrollPageWidth : -this.scrollPageWidth);
  440.   return this.toggleArrows(b), this.sliding = !0, this.$(".carousel-inner").animate({scrollLeft:b}, 800, "swing", $.proxy(function() {
  441.     this.sliding = !1;
  442.     this.preLoad(b);
  443.   }, this)), this;
  444. }, preLoad:function(a) {
  445.   this.model.hasMore && a >= this.scrollMax - this.scrollPageWidth && (this.$(".carousel-inner").addClass("loading"), this.model.loadMore({success:this.preLoadSuccess, error:this.preLoadError}));
  446. }, preLoadSuccess:function(a, b, c) {
  447.   this.render();
  448.   this.$(".carousel-inner").removeClass("loading");
  449. }, preLoadError:function(a, b, c) {
  450.   this.$(".carousel-inner").removeClass("loading");
  451. }, openBar:function() {
  452.   $("body").addClass("explore-bar-visible");
  453.   this.$("#related-projects").animate({height:"160px"});
  454.   this.$("#explore-header").attr("data-control", "close");
  455.   this.$("#explore-header-open").removeClass("hidden");
  456.   this.$("#explore-header-closed").addClass("hidden");
  457.   this.$(".carousel-control").css("display", "inline");
  458.   this.model.fetch();
  459.   this.isOpenBar = !0;
  460. }, closeBar:function() {
  461.   $("body").removeClass("explore-bar-visible");
  462.   $("#related-projects").animate({height:"0px"});
  463.   this.$("#explore-header").attr("data-control", "open");
  464.   $("#explore-header-closed").removeClass("hidden");
  465.   $("#explore-header-open").addClass("hidden");
  466.   this.$(".carousel-control").css("display", "none");
  467.   this.isOpenBar = !1;
  468. }, stopEvent:function(a) {
  469.   a.stopPropagation();
  470. }, open:function() {
  471.   this.model.fetch();
  472.   this.delegateEvents();
  473. }, filter:function(a) {
  474.   Scratch.CollectionView.prototype.filter.apply(this, [a]);
  475.   this.$(".carousel-inner").scrollLeft(0);
  476. }, itemClicked:function(a) {
  477.   a.preventDefault();
  478.   Scratch.EventMgr.trigger("explore-item-clicked", $(a.currentTarget).data());
  479. }});
  480. Scratch.CollectionCountView = Backbone.View.extend({initialize:function(a) {
  481.   this.template = _.template($("#template-collection-count").html());
  482.   this.count = a.count || null;
  483.   this.model.bind("add", this.add, this);
  484.   this.model.bind("remove", this.remove, this);
  485.   this.model.bind("reset", this.render, this);
  486.   this.model.bind("change", this.render, this);
  487. }, render:function() {
  488.   count = this.count ? this.count : this.model.length;
  489.   this.$el.html(this.template({count:count}));
  490. }, add:function() {
  491.   count = this.count++ || this.model.length;
  492.   this.render();
  493. }, remove:function() {
  494.   count = this.count-- || this.model.length;
  495.   this.render();
  496. }});
  497. Scratch.ViewManager = Backbone.View.extend({initialize:function(a) {
  498.   this.views = a.views;
  499. }, swapView:function(a) {
  500.   this.currentView && this.currentView.close();
  501.   (this.currentView = this.views[a]) ? (this.currentView.open(), this.$('[data-content="view"]').html(this.currentView.el)) : this.$('[data-content="view"]').html("");
  502.   this.trigger("swapped", a);
  503. }});
  504. Scratch.TabsView = Scratch.ViewManager.extend({events:{'click [data-control="tab"]':"switchTab"}, switchTab:function(a) {
  505.   a = $(a.target.parentNode);
  506.   this.$('[data-control="tab"]').removeClass("active");
  507.   a.addClass("active");
  508.   this.swapView(a.data("tab"));
  509. }, selectTab:function(a) {
  510.   this.$("[data-tab]").removeClass("active");
  511.   this.$('[data-tab="' + a + '"]').addClass("active");
  512.   this.swapView(a);
  513. }});
  514. Scratch.LogoutView = Backbone.View.extend({events:{"submit form":"logout"}, logout:function(a) {
  515.   a.preventDefault();
  516.   $.ajax({type:"POST", url:"/accounts/logout/", success:function(a, c, d) {
  517.     window.location.href = "/";
  518.   }});
  519. }});
  520. Scratch.LoginView = Backbone.View.extend({initialize:function(a) {
  521.   _.bindAll(this, "onLoginSuccess", "onLoginError");
  522. }, events:{"submit form":"login", "click .dropdown-menu":"formClick"}, formClick:function(a) {
  523.   a.stopPropagation();
  524. }, login:function(a) {
  525.   a.preventDefault();
  526.   this.$("button").hide();
  527.   this.$(".ajax-loader").show();
  528.   if (this.$el.is("#login-dialog") && "undefined" != typeof this.recaptchaWidget) {
  529.     var b = !0, c = grecaptcha.getResponse();
  530.   } else {
  531.     b = !1, c = "";
  532.   }
  533.   $.withCSRF(function(a) {
  534.     this.model.login({username:this.$('[name="username"]').val(), password:this.$('[name="password"]').val(), "g-recaptcha-response":c, embed_captcha:b, timezone:jstz.determine().name(), csrfmiddlewaretoken:a}, {success:this.onLoginSuccess, error:this.onLoginError});
  535.   }.bind(this));
  536. }, onLoginSuccess:function(a, b) {
  537.   Scratch.LoggedInUser.set(this.model.attributes);
  538.   this.$el.is("#login-dialog") ? 0 > location.href.indexOf("editor") && 0 > location.href.indexOf("pathways") ? location.reload() : (this.$el.modal("hide"), setAccountNavFromJson()) : (this.$el.removeClass("open"), location.reload());
  539. }, onLoginError:function(a, b) {
  540.   if (400 === b.status) {
  541.     return this.onLoginSuccess(a, b);
  542.   }
  543.   var c = b.responseJSON[0] || {msg:"An unknown error occurred"};
  544.   "redirect" in c ? this.$el.is("#login-dialog") ? ("undefined" == typeof this.recaptchaWidget ? this.recaptchaWidget = grecaptcha.render("recaptcha-container") : grecaptcha.reset(this.recaptchaWidget), this.$(".error").html(c.msg).show(), this.$("button").show(), this.$(".ajax-loader").hide(), this.model.currentLoginUrl = this.model.loginRetryUrl) : window.location = c.redirect : (this.$(".error").html(c.msg).show(), this.$("button").show(), this.$(".ajax-loader").hide());
  545. }});
  546. Scratch.LanguageDropdownView = Backbone.View.extend({events:{"change #language-selection":"changeLanguage"}, changeLanguage:function(a) {
  547.   var b = this;
  548.   $.withCSRF(function(a) {
  549.     $("<input>").attr({type:"hidden", name:"csrfmiddlewaretoken", value:a}).prependTo(b.$el);
  550.     b.$el.submit();
  551.   });
  552. }});
  553. Scratch.AlertView = Backbone.View.extend({className:"alert fade in", alerts:["success", "error", "info"], template:_.template('<span class="close">&times;</span><%= message %>'), events:{"click .close":"closeAlert"}, initialize:function(a) {
  554.   var b = a.msg || "", c = a.hasOwnProperty("alert") ? a.alert : "info", d = void 0 === a.timer ? 3e3 : a.timer;
  555.   a = a.memory || !1;
  556.   if (-1 === _.indexOf(this.alerts, c)) {
  557.     throw Error("Invalid alert: [" + c + "] Must be one of:" + this.alerts.join(", "));
  558.   }
  559.   this.alert = c;
  560.   this.message = b;
  561.   this.timer = d;
  562.   this.memory = a;
  563.   _.bindAll(this, "closeAlert");
  564. }, render:function() {
  565.   var a = this.template({message:this.message});
  566.   a = this.$el.addClass("alert-" + this.alert).html(a).show();
  567.   return this.timer && a.delay(this.timer).fadeOut("slow"), this;
  568. }, closeAlert:function(a) {
  569.   this.$el.stop().fadeOut("fast");
  570. }});
  571. Scratch.AlertView.msg = function(a, b) {
  572.   var c = new Scratch.AlertView(b), d = a.html(c.render().el).width();
  573.   return a.css({marginLeft:-d / 2, left:"50%"}), c;
  574. };
  575. Scratch.Comments = Backbone.View.extend({page:0, events:{'click [data-control="load-more"]':"getNextPage", 'click [data-control="post"]':function(a) {
  576.   this.hideError(a);
  577.   this.postComment(a);
  578. }, 'click [data-control="reply-to"]':"showReplyForm", 'click [data-control="cancel"]':"cancel", 'click [data-control="delete"]':"deleteComment", 'click [data-control="undelete"]':"undeleteComment", 'click [data-control="report"]':"report", 'click [data-control="unreport"]':"unreport", "click .more-replies":"showMoreReplies", "focus #comments textarea":"hideError", "change #comments-enabled":"toggleComments", "hover .tenmil":"confetti"}, initialize:function(a) {
  579.   this.type = a.type;
  580.   this.typeId = a.typeId;
  581.   this.gaqType = "user" == this.type ? "profile" : "gallery" == this.type ? "studio" : this.type;
  582.   this.commentPostingAllowed = $("#main-post-form").is(":visible");
  583.   this.student_usernames = [];
  584.   if (Scratch.INIT_DATA.LOGGED_IN_USER.model && Scratch.INIT_DATA.LOGGED_IN_USER.model.is_educator) {
  585.     var b = new Scratch.UserThumbnailCollection([], {url:"/site-api/classrooms/students/of/" + Scratch.INIT_DATA.LOGGED_IN_USER.model.username, model:Scratch.UserThumbnail});
  586.     this.gotStudents = $.Deferred();
  587.     var c = function(a) {
  588.       return "undefined" == typeof a && (a = 1), b.fetch({url:b.options.url, data:{page:a}, add:!0}).then(function(b) {
  589.         return c(a + 1);
  590.       }.bind(this)).fail(function() {
  591.         this.student_usernames = b.models.map(function(a) {
  592.           return a.get("user").username;
  593.         });
  594.         this.gotStudents.resolve();
  595.       }.bind(this));
  596.     }.bind(this);
  597.     c();
  598.   } else {
  599.     this.gotStudents = $.Deferred(function(a) {
  600.       a.resolve();
  601.     });
  602.   }
  603.   this.commentReplyTemplate = _.template($("#template-comment-reply").html());
  604.   Scratch.INIT_DATA.IS_SOCIAL ? (this.$("#main-post-form textarea").limit("500", "#chars-left"), this.$("#main-post-form textarea").keydown(function(a) {
  605.     a.ctrlKey && (13 == a.keyCode || 10 == a.keyCode) && this.postComment(a);
  606.   })) : (this.$("#main-post-form textarea").limit("0"), this.$("#main-post-form textarea").focus(function() {
  607.     openResendDialogue();
  608.   }));
  609.   this.$commentContainer = $("<div>");
  610.   a.scrollTo ? (this.scrollTo(".comments"), this.getNextPage("#comments" + a.scrollTo)) : this.getNextPage();
  611. }, hideError:function() {
  612.   this.$(".control-group.tooltip").removeClass("error");
  613. }, render:function() {
  614.   var a = this.$('[data-content="comments"]');
  615.   a.find("#comments-loading").remove();
  616.   a.append(this.$commentContainer.html());
  617.   this.$commentContainer.html("");
  618.   "project" == this.type && (a = $("[data-control-comment-count]").attr("data-control-comment-count") || "", 0 == a.length && (a = "0"), $("#comment-count").text("(" + a + ")"));
  619. }, confetti:function(a) {
  620.   window.confettiRunning || (window.confettiRunning = !0, $("#content").confetti({x:a.pageX, y:a.pageY, complate:function() {
  621.     window.confettiRunning = !1;
  622.   }}));
  623. }, getNextPage:function(a) {
  624.   this.$('[data-control="load-more"]').remove();
  625.   var b = this, c = "";
  626.   return Scratch.INIT_DATA.ADMIN && (c = "with-deleted/"), b.page++, $.ajax({url:"/site-api/comments/" + c + this.type + "/" + this.typeId + "/?page=" + this.page}).done(function(c) {
  627.     if (40 < b.page) {
  628.       throw "more than 40 pages of comments shouldn't be happening";
  629.     }
  630.     b.$commentContainer.append(c);
  631.     !a || a instanceof $.Event ? (b.render(), b.$("span.time").timeago()) : -1 < c.indexOf(a.slice(1)) ? (b.render(), b.$("span.time").timeago(), setTimeout(function() {
  632.       b.scrollTo(a);
  633.     }, 0)) : (b.$commentContainer.find('[data-control="load-more"]').remove(), b.getNextPage(a));
  634.     b.showCommentOptions();
  635.   });
  636. }, showCommentOptions:function(a) {
  637.   if (Scratch.INIT_DATA.LOGGED_IN_USER.options.authenticated && !Scratch.INIT_DATA.ADMIN) {
  638.     a = a || this.$el;
  639.     var b = this, c = !1, d = !1;
  640.     Scratch.INIT_DATA.ADMIN && (c = !0);
  641.     "project" == b.type ? (Scratch.INIT_DATA.PROJECT.model.creator == Scratch.INIT_DATA.LOGGED_IN_USER.model.username && (c = !0), d = Scratch.INIT_DATA.PROJECT.model.comments_allowed) : "user" == b.type ? (Scratch.INIT_DATA.PROFILE.model.username == Scratch.INIT_DATA.LOGGED_IN_USER.model.username && (c = !0), d = Scratch.INIT_DATA.PROFILE.model.comments_allowed) : "gallery" == b.type && (Scratch.INIT_DATA.GALLERY.model.is_owner && (c = !0), d = Scratch.INIT_DATA.GALLERY.model.comments_allowed);
  642.     $.when(this.gotStudents).then(function() {
  643.       a.find("div.comment").each(function() {
  644.         var a = {can_delete:c, current_user:Scratch.INIT_DATA.LOGGED_IN_USER.model.username, comment_user:$(this).find("#comment-user").data("comment-user"), type:b.type, is_staff:Scratch.INIT_DATA.ADMIN};
  645.         a.student_of_educator = 0 <= b.student_usernames.indexOf(a.comment_user);
  646.         var e = _.template($("#template-comment-actions").html());
  647.         $(this).find(".actions-wrap").html(e(a));
  648.         $(this).find("a.reply").attr("data-control", "reply-to");
  649.         d && Scratch.INIT_DATA.comment_posting && b.commentPostingAllowed && $(this).find("a.reply").css("display", "inline");
  650.       });
  651.     });
  652.   }
  653. }, postComment:function(a) {
  654.   a.preventDefault();
  655.   var b = $(a.currentTarget), c = b.closest("form");
  656.   a = $.trim(c.find("textarea").val());
  657.   var d = {content:a, parent_id:b.data("parent-thread") || "", commentee_id:b.data("commentee-id") || ""}, g = !1, e = this;
  658.   d.parent_id && (g = !0);
  659.   var f = function(a) {
  660.     c.find('[data-control="error"] .text').html(a);
  661.     c.find('[data-control="info"]').hide();
  662.     c.find(".control-group").addClass("error");
  663.   };
  664.   Scratch.INIT_DATA.IS_IP_BANNED ? $("#ip-mute-ban").modal() : "" == a ? f(Scratch.ALERT_MSGS["empty-comment"]) : (b.removeAttr("data-control").addClass("posting"), $.ajax({type:"POST", dataType:"html", data:JSON.stringify(d), url:"/site-api/comments/" + this.type + "/" + this.typeId + "/add/"}).done(function(a) {
  665.     var c = $.trim(a);
  666.     if ("isBad" == c) {
  667.       f(Scratch.ALERT_MSGS["inappropriate-comment"]), _gaq.push(["_trackEvent", e.gaqType, "comment_rejected:bad_word"]);
  668.     } else {
  669.       if ("hasChatSite" == c) {
  670.         f(Scratch.ALERT_MSGS["comment-has-chat-site"]), _gaq.push(["_trackEvent", e.gaqType, "comment_rejected:chat_site"]);
  671.       } else {
  672.         if ("isSpam" == c) {
  673.           f(Scratch.ALERT_MSGS["comment-spam"]);
  674.         } else {
  675.           if ("isFlood" == c) {
  676.             f(Scratch.ALERT_MSGS["comment-flood"]);
  677.           } else {
  678.             if ("isMuted" == c) {
  679.               f(Scratch.ALERT_MSGS["comment-muted"]);
  680.             } else {
  681.               if ("isUnconstructive" == c) {
  682.                 f(Scratch.ALERT_MSGS["comment-unconstructive"]);
  683.               } else {
  684.                 if ("isDisallowed" == c) {
  685.                   f(Scratch.ALERT_MSGS["comment-disallowed"]);
  686.                 } else {
  687.                   if ("isIPMuted" == c) {
  688.                     $("#ip-mute-ban").modal();
  689.                   } else {
  690.                     if ("isEmpty" == c) {
  691.                       f(Scratch.ALERT_MSGS.error);
  692.                     } else {
  693.                       if ("isTooLong" == c) {
  694.                         return;
  695.                       }
  696.                     }
  697.                     _gaq.push(["_trackEvent", e.gaqType, "comment_add"]);
  698.                     c = $("<li></li>");
  699.                     g ? (e.$('[data-thread="' + d.parent_id + '"]').append(c.html(a)), b.closest('[data-content="reply-form"]').html("")) : (b.closest("form").find("textarea").val("").end().find("#chars-left").html("500"), e.$('[data-content="comments"]').prepend(c.html(a + '<ul class="replies" data-thread="' + $(a).data("comment-id") + '"></ul>')));
  700.                     e.scrollTo(null, c);
  701.                     e.$("span.time").timeago();
  702.                     e.showCommentOptions(c);
  703.                   }
  704.                 }
  705.               }
  706.             }
  707.           }
  708.         }
  709.       }
  710.     }
  711.   }).error(function(a) {
  712.     Scratch.AlertView.msg($("#alert-view"), {alert:"error", msg:Scratch.ALERT_MSGS.error});
  713.   }).always(function(a) {
  714.     b.attr("data-control", "post").removeClass("posting");
  715.   }));
  716. }, showReplyForm:function(a) {
  717.   if (this.commentPostingAllowed) {
  718.     var b = $(a.currentTarget), c = this, d = b.closest("li");
  719.     this.showMoreReplies({useAnimation:d.closest(".top-level-reply").find(".truncated").length, $elem:d, callback:function() {
  720.       var a = d.find('[data-content="reply-form"]:first').html(c.commentReplyTemplate({thread_id:b.data("parent-thread"), commentee_id:b.data("commentee-id"), comment_id:b.data("comment-id")}));
  721.       Scratch.INIT_DATA.IS_SOCIAL ? a.find("textarea").focus().limit("500", "#chars-left-" + b.data("comment-id")) : (a.find("textarea").limit("0"), a.find("textarea").focus(function() {
  722.         openResendDialogue();
  723.       }));
  724.     }});
  725.   }
  726. }, cancel:function(a) {
  727.   a.preventDefault();
  728.   $(a.currentTarget).parents("form:first").find("textarea")[0].value = "";
  729.   $(a.currentTarget).parents("form:first").find("#chars-left").html("500");
  730.   $(a.currentTarget).parents('[data-content="reply-form"]:first').empty();
  731. }, submitDelete:function(a) {
  732.   var b = $(a.currentTarget).closest("[data-comment-id]");
  733.   a = b.attr("data-comment-id");
  734.   $.ajax({url:"/site-api/comments/" + this.type + "/" + this.typeId + "/del/", type:"POST", dataType:"html", data:JSON.stringify({id:a})}).done(function(a) {
  735.     b.parent("li").remove();
  736.     _gaq.push(["_trackEvent", self.gaqType, "comment_deleted"]);
  737.   });
  738. }, deleteComment:function(a) {
  739.   var b = this;
  740.   if (Scratch.INIT_DATA.ADMIN) {
  741.     return b.submitDelete(a);
  742.   }
  743.   this.deleteDialogElem = this.deleteDialogElem || $(Scratch.ALERT_MSGS.delete_comment);
  744.   this.deleteDialogElem.dialog({buttons:{Cancel:function() {
  745.     $(this).dialog("close");
  746.   }, Delete:function() {
  747.     $(this).dialog("close");
  748.     b.submitDelete(a);
  749.   }, Report:function() {
  750.     $(this).dialog("close");
  751.     b.submitReport(a);
  752.   }}});
  753. }, undeleteComment:function(a) {
  754.   var b = $(a.currentTarget).closest("[data-comment-id]"), c = b.attr("data-comment-id"), d = this;
  755.   $.ajax({url:"/site-api/comments/" + this.type + "/" + this.typeId + "/undel/", type:"POST", dataType:"html", data:JSON.stringify({id:c})}).done(function(a) {
  756.     b.replaceWith(a);
  757.     $("#comments-" + c).removeClass("removed");
  758.     $("#comments-" + c).parents("li").removeClass("removed");
  759.     _gaq.push(["_trackEvent", d.gaqType, "comment_undelete"]);
  760.   });
  761. }, report:function(a) {
  762.   var b = this;
  763.   if (Scratch.INIT_DATA.ADMIN) {
  764.     return b.submitReport(a);
  765.   }
  766.   var c = $(a.currentTarget).closest("[data-comment-id]").find("#comment-user").data("comment-user"), d = {Cancel:function() {
  767.     $(this).dialog("close");
  768.   }, Report:function() {
  769.     $(this).dialog("close");
  770.     b.submitReport(a);
  771.   }};
  772.   0 <= b.student_usernames.indexOf(c) ? (this.educatorReportDialog = this.educatorReportDialog || $(Scratch.ALERT_MSGS.report_comment_educator), this.reportDialogElem = this.educatorReportDialog, d.Delete = d.Report, delete d.Report) : (this.reportDialog = this.reportDialog || $(Scratch.ALERT_MSGS.report_comment), this.reportDialogElem = this.reportDialog);
  773.   this.reportDialogElem.dialog({buttons:d});
  774. }, submitReport:function(a) {
  775.   var b = $(a.currentTarget).closest("[data-comment-id]");
  776.   a = b.attr("data-comment-id");
  777.   $.ajax({url:"/site-api/comments/" + this.type + "/" + this.typeId + "/rep/", type:"POST", dataType:"html", data:JSON.stringify({id:a})}).done(function(a) {
  778.     b.replaceWith(a);
  779.     _gaq.push(["_trackEvent", self.gaqType, "comment_report_add"]);
  780.   });
  781. }, unreport:function(a) {
  782.   var b = $(a.currentTarget).closest("[data-comment-id]"), c = b.attr("data-comment-id");
  783.   a = $(a.currentTarget).data("report-id");
  784.   var d = this;
  785.   $.ajax({url:"/site-api/comments/" + this.type + "/" + this.typeId + "/unrep/", type:"POST", dataType:"html", data:JSON.stringify({id:c, rid:a})}).done(function(a) {
  786.     b.replaceWith(a);
  787.     _gaq.push(["_trackEvent", d.gaqType, "comment_report_remove"]);
  788.   });
  789. }, scrollTo:function(a, b) {
  790.   if (a || b) {
  791.     var c = b || this.$(a);
  792.     if (0 === c.length) {
  793.       throw a + " is non-existent.";
  794.     }
  795.     var d = c.closest("li");
  796.     d.addClass("highlighted");
  797.     !c.is(":visible") && Scratch.INIT_DATA.ADMIN && $("#comments .removed").toggle();
  798.     d.hasClass("truncated") && this.showMoreReplies({$elem:d, useAnimation:!1});
  799.     d = $(window);
  800.     var g = d.height();
  801.     d = d.scrollTop();
  802.     var e = d + g, f = c.outerHeight(!0);
  803.     c = c.offset().top;
  804.     g = c - g / 2 + f / 2;
  805.     var h = g / 2;
  806.     if (c < d || c + f > e) {
  807.       return $("html,body").animate({scrollTop:g}, 1e3 < h ? 1e3 : h).promise();
  808.     }
  809.   }
  810. }, showMoreReplies:function(a) {
  811.   function b() {
  812.     e.first().prev().removeClass("lastvisible");
  813.     e.removeClass("truncated");
  814.     g.remove();
  815.     c.callback && c.callback();
  816.   }
  817.   var c = a || {}, d, g;
  818.   c.currentTarget ? (g = $(c.currentTarget), d = g.closest(".top-level-reply").find(".replies"), c.useAnimation = !0) : (d = c.$elem.closest(".top-level-reply").find(".replies"), g = d.next(".more-replies"));
  819.   var e = d.find(".truncated");
  820.   if (c.useAnimation) {
  821.     g.slideUp("fast");
  822.     var f = e.first().prev(".lastvisible");
  823.     f.animate({height:f.children(":first").outerHeight()}, "fast");
  824.     e.slideDown("fast").promise().always(function() {
  825.       b();
  826.       f.height("");
  827.     });
  828.   } else {
  829.     b();
  830.   }
  831. }, toggleComments:function(a) {
  832.   var b = $(a.target), c = this.$(".comments-off"), d = this.$(".comments-on"), g = this.$('[data-content="reply-form"]'), e = this.$('.reply[data-control="reply-to"]'), f = b.is(":checked"), h = function() {
  833.     c.show();
  834.     d.hide();
  835.     g.hide();
  836.     e.hide();
  837.   }, k = function() {
  838.     c.hide();
  839.     d.show();
  840.     g.show();
  841.     e.show();
  842.   };
  843.   f ? h() : k();
  844.   $.post("/site-api/comments/" + this.type + "/" + this.typeId + "/toggle-comments/", {}).fail(function(a) {
  845.     f ? (k(), b.removeAttr("checked")) : (h(), b.attr("checked", "checked"));
  846.   });
  847. }});
  848. Scratch.ViewController = Backbone.View.extend({showView:function(a) {
  849.   this.currentView && this.currentView.close();
  850.   (this.currentView = a) && (this.currentView.render(), this.$el.html(this.currentView.el));
  851. }});
  852. Scratch.FollowButton = Backbone.View.extend({events:{'click [data-control="follow"]':"follow", 'click [data-control="unfollow"]':"unfollow"}, initialize:function(a) {
  853.   _.bindAll(this, "followed");
  854.   _.bindAll(this, "unfollowed");
  855.   this.displayName = a.displayName;
  856. }, follow:function() {
  857.   this.model.related.followers.addItems(Scratch.LoggedInUser.get("username"), {success:this.followed, error:this.onFollowError});
  858. }, followed:function(a, b) {
  859.   this.$('[data-control="follow"]').removeClass("blue notfollowing").addClass("grey following").attr("data-control", "unfollow");
  860.   Scratch.AlertView.msg($("#alert-view"), {alert:"success", msg:Scratch.ALERT_MSGS.followed + this.displayName});
  861.   _gaq.push(["_trackEvent", "studio", "follow_add"]);
  862. }, onFollowError:function(a, b) {
  863.   Scratch.AlertView.msg($("#alert-view"), {alert:"error", msg:a.responseJSON[0].errors.join(",")});
  864. }, unfollow:function() {
  865.   this.model.related.followers.removeItems(Scratch.LoggedInUser.get("username"), {success:this.unfollowed});
  866. }, unfollowed:function(a, b) {
  867.   this.$('[data-control="unfollow"]').removeClass("grey following").addClass("blue notfollowing").attr("data-control", "follow");
  868.   Scratch.AlertView.msg($("#alert-view"), {alert:"success", msg:Scratch.ALERT_MSGS.unfollowed + this.displayName});
  869.   _gaq.push(["_trackEvent", "studio", "follow_remove"]);
  870. }});
  871. Scratch.EditableTextField = Backbone.View.extend({events:{"focusout textarea":"saveEditable", "focusout input":"saveEditable", click:"edit", "submit form":"preventFormSubmit"}, initialize:function(a, b) {
  872.   _.bindAll(this, "success", "error", "saveEditable");
  873.   this.$eField = this.$("input, textarea");
  874.   this.eField = this.$eField[0];
  875. }, saveEditable:function(a) {
  876.   if (this.eField.value != this.eField.defaultValue) {
  877.     var b = {};
  878.     b[this.eField.name] = this.eField.value;
  879.     this.serverCall(b);
  880.     "focusout" == a.type && this.$el.addClass("loading");
  881.     this.eField.defaultValue = this.eField.value;
  882.   }
  883.   "focusout" == a.type && (clearInterval(this.saveInt), this.$el.removeClass("editable-empty").addClass("editable"), this.$el.addClass("read").removeClass("write"), this.eField.value || (this.$el.addClass("editable-empty").removeClass("editable"), this.$('[data-content="prompt"]').show()));
  884. }, serverCall:function(a) {
  885.   this.model.save(a, {wait:!0, success:this.success, error:this.error});
  886. }, edit:function(a) {
  887.   if (!this.$("form").length) {
  888.     return this.undelegateEvents();
  889.   }
  890.   this.clearPrompt();
  891.   this.$el.removeClass("read").addClass("write");
  892.   this.$eField.focus();
  893.   var b = this;
  894.   clearInterval(this.saveInt);
  895.   this.saveInt = setInterval(function() {
  896.     b.saveEditable(a);
  897.   }, 1e4);
  898. }, clearPrompt:function() {
  899.   this.$('[data-content="prompt"]').hide();
  900.   this.$eField.focus();
  901. }, preventFormSubmit:function(a) {
  902.   a.preventDefault();
  903.   this.saveEditable(a);
  904. }, success:function(a, b) {
  905.   this.$el.removeClass("loading");
  906.   if (b.errors) {
  907.     Scratch.AlertView.msg($("#alert-view"), {alert:"error", msg:Scratch.ALERT_MSGS[b.errors[0]], timer:1e4});
  908.   } else {
  909.     this.onEditSuccess();
  910.   }
  911. }, onEditSuccess:function(a) {
  912. }, error:function(a, b, c) {
  913.   throw "in Scratch.EditableTextField, error - responseText:" + b.responseText + "  status:" + b.status;
  914. }});
  915. Scratch.EditableSelectField = Backbone.View.extend({events:{"change select":"saveEditable", "submit form":"preventFormSubmit"}, initialize:function(a, b) {
  916.   _.bindAll(this, "success", "error", "saveEditable");
  917.   this.$eField = this.$("select");
  918.   this.eField = this.$eField[0];
  919. }, saveEditable:function(a) {
  920.   a = {};
  921.   a[this.eField.name] = this.$("select").val();
  922.   this.serverCall(a);
  923. }, serverCall:function(a) {
  924.   this.model.save(a, {wait:!0, success:this.success, error:this.error});
  925. }, preventFormSubmit:function(a) {
  926.   a.preventDefault();
  927.   this.saveEditable(a);
  928. }, success:function(a, b) {
  929.   this.$el.removeClass("loading");
  930.   if (b.isBad) {
  931.     Scratch.AlertView.msg($("#alert-view"), {alert:"error", msg:Scratch.ALERT_MSGS["inappropriate-generic"], timer:1e4});
  932.   } else {
  933.     this.onEditSuccess();
  934.   }
  935. }, onEditSuccess:function(a) {
  936. }, error:function(a, b, c) {
  937.   throw "in Scratch.EditableSelectField, error - responseText:" + b.responseText + "  status:" + b.status;
  938. }});
  939. Scratch.EditableCheckboxField = Backbone.View.extend({events:{'click [type="checkbox"]':"saveEditable", "submit form":"preventFormSubmit"}, initialize:function(a, b) {
  940.   _.bindAll(this, "success", "error", "saveEditable");
  941.   this.$eField = this.$('input[type="checkbox"]');
  942.   this.eField = this.$eField[0];
  943. }, saveEditable:function(a) {
  944.   a = {};
  945.   a[this.eField.name] = this.$eField.is(":checked") ? 1 : 0;
  946.   this.serverCall(a);
  947. }, serverCall:function(a) {
  948.   this.model.save(a, {wait:!0, success:this.success, error:this.error});
  949. }, preventFormSubmit:function(a) {
  950.   a.preventDefault();
  951.   this.saveEditable(a);
  952. }, success:function(a, b) {
  953.   this.$el.removeClass("loading");
  954.   if (b.isBad) {
  955.     Scratch.AlertView.msg($("#alert-view"), {alert:"error", msg:Scratch.ALERT_MSGS["inappropriate-generic"], timer:1e4});
  956.   } else {
  957.     this.onEditSuccess();
  958.   }
  959. }, onEditSuccess:function(a) {
  960. }, error:function(a, b, c) {
  961.   throw "in Scratch.EditableSelectField, error - responseText:" + b.responseText + "  status:" + b.status;
  962. }});
  963. Scratch.EditableImage = Backbone.View.extend({events:{mouseover:"showEdit", mouseout:"hideEdit", 'change input[type="file"]':"submit"}, initialize:function() {
  964.   _.bindAll(this, "imageUploadStart");
  965.   _.bindAll(this, "imageUploadSuccess");
  966.   this.$el.fileupload({url:this.model.url(), done:this.imageUploadSuccess, start:this.imageUploadStart, pasteZone:this.$el});
  967. }, showEdit:function(a) {
  968.   this.$el.addClass("edit");
  969. }, hideEdit:function(a) {
  970.   this.$el.removeClass("edit");
  971. }, imageUploadSuccess:function(a, b) {
  972.   this.$el.removeClass("loading");
  973.   if (b.result.error) {
  974.     Scratch.AlertView.msg($("#alert-view"), {alert:"error", msg:b.result.errors[0]});
  975.   } else {
  976.     if (b.result.errors) {
  977.       Scratch.AlertView.msg($("#alert-view"), {alert:"error", msg:Scratch.ALERT_MSGS[b.result.errors[0]], timer:1e4});
  978.     } else {
  979.       var c = b.result.thumbnail_url + "#" + (new Date).getTime();
  980.       this.$("img").attr("src", c);
  981.       Scratch.AlertView.msg($("#alert-view"), {alert:"success", msg:"Thumbnail changed"});
  982.     }
  983.   }
  984. }, imageUploadStart:function() {
  985.   this.$el.removeClass("edit");
  986.   this.$el.addClass("loading");
  987. }, submit:function(a) {
  988. }});
  989. Scratch.UserThumbnail = Scratch.Model.extend({urlRoot:"/site-api/users/all/", slug:"username"});
  990. Scratch.UserThumbnailCollection = Scratch.Collection.extend({model:Scratch.UserThumbnail, urlRoot:"/site-api/users/", slug:"username", initialize:function(a, b) {
  991.   this.options = this._meta = b;
  992. }, deleteItem:function(a, b) {
  993.   this.remove(a);
  994.   b.url = this.url() + "remove/" + this.url_params({usernames:a.get("fields").user.username});
  995.   this.sync("update", a, b);
  996. }, addItem:function(a) {
  997.   a.url = this.url() + "add/" + this.url_params({usernames:a.usernames});
  998.   this.sync("update", new Scratch.UserThumbnail, a);
  999. }, meta:function(a, b) {
  1000.   if (void 0 === b) {
  1001.     return this._meta[a];
  1002.   }
  1003.   this._meta[a] = b;
  1004. }});
  1005. Scratch.LoggedInUserModel = Scratch.UserThumbnail.extend({authenticated:!1, admin:!1, loginUrl:"/login/", loginRetryUrl:"/login_retry/", currentLoginUrl:"/login/", initialize:function(a, b) {
  1006.   this.constructor.__super__.initialize.apply(this, [a, b]);
  1007.   this.authenticated = b.authenticated;
  1008. }, login:function(a, b) {
  1009.   this.save(a, $.extend(b, {url:this.currentLoginUrl, wait:!0}));
  1010.   this.authenticated = !0;
  1011. }, logout:function() {
  1012.   this.authenticated = !1;
  1013. }});
  1014. Scratch.ProjectThumbnail = Scratch.Model.extend({urlRoot:"/site-api/projects/all/"});
  1015. Scratch.ProjectThumbnailCollection = Scratch.Collection.extend({model:Scratch.ProjectThumbnail, urlRoot:"/site-api/projects/", initialize:function(a, b) {
  1016.   _.bindAll(this, "added");
  1017.   _.bindAll(this, "deletedAll");
  1018.   this.options = this._meta = b;
  1019. }, added:function(a, b) {
  1020.   this.fetch();
  1021. }, deleteAll:function(a) {
  1022.   "trashed" == this._meta.collectionType && (a || (a = {}), _.extend(a, {url:this.url() + "empty/", success:this.deletedAll}), Backbone.sync("update", this, a));
  1023. }, deletedAll:function(a, b) {
  1024.   this.fetch();
  1025. }, meta:function(a, b) {
  1026.   if (void 0 === b) {
  1027.     return this._meta[a];
  1028.   }
  1029.   this._meta[a] = b;
  1030. }});
  1031. Scratch.GalleryThumbnail = Scratch.Model.extend({urlRoot:"/site-api/galleries/all/", deleteCurators:function(a, b) {
  1032.   b = b || {};
  1033.   b.url = "/site-api/users/curators/delete/?gallery_id=" + this.pk;
  1034.   this.sync("update", a, b);
  1035. }, addCurators:function(a) {
  1036.   a = a || {};
  1037.   a.url = "/site-api/users/curators/add/?gallery_id=" + this.pk + "&usernames=" + a.usernames;
  1038.   this.sync("update", this, a);
  1039. }, deleteProjects:function(a, b) {
  1040.   b = b || {};
  1041.   b.url = "/site-api/projects/in/?gallery_id=" + this.get("pk");
  1042.   this.sync("update", a, b);
  1043. }, addProjects:function(a, b) {
  1044.   b = b || {};
  1045.   b.url = "/site-api/projects/in/?gallery_id" + this.get("pk");
  1046.   this.sync("update", a, b);
  1047. }, follow:function(a) {
  1048.   options = options || {};
  1049.   options.url = "/site-api/users/bookmarkers/add/?gallery_id=" + this.get("pk");
  1050.   this.sync("update", this, options);
  1051. }, unfollow:function(a) {
  1052.   a = a || {};
  1053.   a.url = "/site-api/users/bookmarkers/remove/?gallery_id=" + this.get("pk");
  1054.   this.sync("update", this, a);
  1055. }});
  1056. Scratch.GalleryThumbnailCollection = Scratch.Collection.extend({model:Scratch.GalleryThumbnail, urlRoot:"/site-api/galleries/", initialize:function(a, b) {
  1057.   this.options = this._meta = b;
  1058. }, meta:function(a, b) {
  1059.   if (void 0 === b) {
  1060.     return this._meta[a];
  1061.   }
  1062.   this._meta[a] = b;
  1063. }});
  1064. Scratch.Comment = Scratch.Model.extend({urlRoot:"/site-api/comments/"});
  1065. Scratch.CommentCollection = Scratch.Collection.extend({model:Scratch.Comment, urlRoot:"/site-api/comments/", initialize:function(a, b) {
  1066.   this.options = b;
  1067. }, toggleDisabled:function() {
  1068. }, addComment:function(a, b) {
  1069.   b = b || {};
  1070.   return b.url = this.url() + "add/?", b.data = JSON.stringify(a), Backbone.sync("create", this.parentModel, b);
  1071. }, isCommentOkay:function(a) {
  1072. }, report:function(a, b) {
  1073.   a || (a = {});
  1074.   var c = this.url() + "rep/";
  1075.   $.ajax(c, {type:"POST", data:JSON.stringify(a), dataType:"json", success:b});
  1076. }, unreport:function(a, b) {
  1077.   a || (a = {});
  1078.   var c = this.url() + "unrep/";
  1079.   $.ajax(c, {type:"POST", data:JSON.stringify(a), dataType:"json", success:b});
  1080. }});
  1081. (function(a) {
  1082.   a.fn.scratchIncrementCount = function(a) {
  1083.     var b = parseInt(this.html(), 10);
  1084.     this.html(b + a);
  1085.   };
  1086.   a.withCSRF = function(b) {
  1087.     a.get("/csrf_token/", function(a, d, g) {
  1088.       csrf = ("; " + document.cookie).split("; scratchcsrftoken=")[1].split(";")[0];
  1089.       b(csrf);
  1090.     });
  1091.   };
  1092. })(jQuery);
  1093. $.ajaxSetup({jsonp:!1});
  1094. $(document).ajaxSend(function(a, b, c) {
  1095.   function d(a) {
  1096.     var b = null;
  1097.     if (document.cookie && "" != document.cookie) {
  1098.       for (var c = document.cookie.split(";"), d = 0; d < c.length; d++) {
  1099.         var e = jQuery.trim(c[d]);
  1100.         if (e.substring(0, a.length + 1) == a + "=") {
  1101.           b = decodeURIComponent(e.substring(a.length + 1));
  1102.           break;
  1103.         }
  1104.       }
  1105.     }
  1106.     return b;
  1107.   }
  1108.   function g(a) {
  1109.     var b = "//" + document.location.host, c = document.location.protocol + b;
  1110.     return a == c || a.slice(0, c.length + 1) == c + "/" || a == b || a.slice(0, b.length + 1) == b + "/" || !/^(\/\/|http:|https:).*/.test(a);
  1111.   }
  1112.   !/^(GET|HEAD|OPTIONS|TRACE)$/.test(c.type) && g(c.url) && b.setRequestHeader("X-CSRFToken", d("scratchcsrftoken"));
  1113. });
  1114. $(document).ajaxError(function(a, b, c, d) {
  1115.   if (void 0 === c.error) {
  1116.     if ("" === location.port) {
  1117.       throw "Uncaught ajax error. Attempted URL: " + c.url + "   Status: " + b.status;
  1118.     }
  1119.     0 === b.status && (c.success(c.fakeResponseForDevPortAjaxFail, b.status, b), console.error("Status 0 ajax bug. Calling success(options.fakeResponseForDevPortAjaxFail, xhr.status, xhr)"));
  1120.   }
  1121. });
  1122. $(document).on("click", ".dropdown.select ul li", function() {
  1123.   var a = $(this).text(), b = $(this).closest(".dropdown"), c = b.find(".selected");
  1124.   b.find("li.hide").removeClass("hide");
  1125.   $(this).addClass("hide");
  1126.   c.text(a);
  1127. });
  1128. $(document).on("click", ".dropdown.radio-style ul li", function() {
  1129.   $(this).closest(".dropdown").find(".selected").removeClass("selected");
  1130.   $(this).addClass("selected");
  1131. });
  1132. $.urlParam = function(a) {
  1133.   return -1 == window.location.search.indexOf(a) ? null : (new RegExp("[\\?&]" + a + "=([^&#]*)")).exec(window.location.href)[1] || 0;
  1134. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement