1
0
Fork 0
mirror of https://github.com/FrankerFaceZ/FrankerFaceZ.git synced 2025-06-28 05:15:54 +00:00
FrankerFaceZ/script.min.js

2 lines
No EOL
38 KiB
JavaScript

!function(e){!function t(e,o,n){function s(i,a){if(!o[i]){if(!e[i]){var l="function"==typeof require&&require;if(!a&&l)return l(i,!0);if(r)return r(i,!0);throw new Error("Cannot find module '"+i+"'")}var c=o[i]={exports:{}};e[i][0].call(c.exports,function(t){var o=e[i][1][t];return s(o?o:t)},c,c.exports,t,e,o,n)}return o[i].exports}for(var r="function"==typeof require&&require,i=0;i<n.length;i++)s(n[i]);return s}({1:[function(t){var o=e.FrankerFaceZ,n=t("./constants"),s=t("./utils");o.prototype.setup_badges=function(){this.log("Preparing badge system."),this.badges={},this.log("Creating badge style element.");var e=this._badge_style=document.createElement("style");e.id="ffz-badge-css",document.head.appendChild(e),this.log("Adding legacy donor badges."),this._legacy_add_donors()};var r=function(e){return".badges .ffz-badge-"+e.id+" { background-color: "+e.color+'; background-image: url("'+e.image+'"); '+(e.extra_css||"")+"}"};o.prototype.bttv_badges=function(e){var t=e.sender,o=this.users[t],n=[],s=-1;if(o&&o.badges){for(var r=0;r<e.badges.length;r++){var i=e.badges[r];if("subscriber"==i.type||"turbo"==i.type){s=r;break}}for(var a in o.badges)if(o.badges.hasOwnProperty(a)){var i=o.badges[a],l=this.badges[i.id]||{},c=i.title||l.title,u="",d=BetterTTV.settings.get("alphaTags");i.image&&(u+='background-image: url(\\"'+i.image+'\\"); '),i.color&&!d&&(u+="background-color: "+i.color+"; "),i.extra_css&&(u+=i.extra_css),u&&(c+='" style="'+u),n.push([(-1==s?1:-1)*a,{type:"ffz-badge-"+i.id+(d?" alpha":""),name:"",description:c}])}if(n.sort(function(e,t){return e[0]-t[0]}),-1==s)for(;n.length;)e.badges.push(n.shift()[1]);else for(;n.length;)e.badges.insertAt(s,n.shift()[1])}},o.prototype.render_badge=function(e){var t=e.get("context.model.from"),o=(e.get("context.parentController.content.id"),e.$(".badges")),n=this.users[t];if(n&&n.badges){var s=o.find(".badge").filter(function(){var e=this.title.toLowerCase();return"subscriber"==e||"turbo"==e}).first(),r=[],i=!!s.length;for(var a in n.badges)if(n.badges.hasOwnProperty(a)){var l=n.badges[a],c=this.badges[l.id]||{},u=document.createElement("div");u.className="badge float-left tooltip ffz-badge-"+l.id,u.setAttribute("title",l.title||c.title),l.image&&(u.style.backgroundImage='url("'+l.image+'")'),l.color&&(u.style.backgroundColor=l.color),l.extra_css&&(u.style.cssText+=l.extra_css),r.push([(i?1:-1)*a,u])}if(r.sort(function(e,t){return e[0]-t[0]}),i)for(;r.length;)s.before(r.shift()[1]);else for(;r.length;)o.append(r.shift()[1])}},o.prototype._legacy_add_donors=function(e){this.badges[1]={id:1,title:"FFZ Donor",color:"#755000",image:"//cdn.frankerfacez.com/channel/global/donoricon.png"},s.update_css(this._badge_style,1,r(this.badges[1])),this.badges[0]={id:0,title:"FFZ Developer",color:"#FAAF19",image:"//cdn.frankerfacez.com/channel/global/devicon.png"},s.update_css(this._badge_style,0,r(this.badges[0])),this.users.sirstendec={badges:{0:{id:0}}},jQuery.ajax(n.SERVER+"script/donors.txt",{cache:!1,context:this}).done(function(e){this._legacy_parse_donors(e)}).fail(function(t){return 404!=t.status?(e=(e||0)+1,10>e?this._legacy_add_donors(e):void 0):void 0})},o.prototype._legacy_parse_donors=function(e){var t=0;if(null!=e)for(var o=e.trim().split(/\W+/),n=0;n<o.length;n++){var r=o[n],i=this.users[r]=this.users[r]||{},a=i.badges=i.badges||{};a[0]||(a[0]={id:1},t+=1)}this.log("Added donor badge to "+s.number_commas(t)+" users.")}},{"./constants":3,"./utils":23}],2:[function(){var t=e.FrankerFaceZ;t.chat_commands.massunmod=function(e,t){if(t=t.join(" ").trim(),!t.length)return"You must provide a list of users to unmod.";t=t.split(/\W*,\W*/);var o=this.get_user();if(!o||!o.login==e.id)return"You must be the broadcaster to use massunmod.";if(t.length>50)return"Each user you unmod counts as a single message. To avoid being globally banned, please limit yourself to 50 at a time and wait between uses.";for(var n=t.length;t.length;){var s=t.shift();e.room.tmiRoom.sendMessage("/unmod "+s)}return"Sent unmod command for "+n+" users."},t.chat_commands.massunmod.help="Usage: /ffz massunmod <list, of, users>\nBroadcaster only. Unmod all the users in the provided list.",t.chat_commands.massmod=function(e,t){if(t=t.join(" ").trim(),!t.length)return"You must provide a list of users to mod.";t=t.split(/\W*,\W*/);var o=this.get_user();if(!o||!o.login==e.id)return"You must be the broadcaster to use massmod.";if(t.length>50)return"Each user you mod counts as a single message. To avoid being globally banned, please limit yourself to 50 at a time and wait between uses.";for(var n=t.length;t.length;){var s=t.shift();e.room.tmiRoom.sendMessage("/mod "+s)}return"Sent mod command for "+n+" users."},t.chat_commands.massmod.help="Usage: /ffz massmod <list, of, users>\nBroadcaster only. Mod all the users in the provided list."},{}],3:[function(e,t){var o='<path d="m120.95 1.74c4.08-0.09 8.33-0.84 12.21 0.82 3.61 1.8 7 4.16 11.01 5.05 2.08 3.61 6.12 5.46 8.19 9.07 3.6 5.67 7.09 11.66 8.28 18.36 1.61 9.51 7.07 17.72 12.69 25.35 3.43 7.74 1.97 16.49 3.6 24.62 2.23 5.11 4.09 10.39 6.76 15.31 1.16 2 4.38 0.63 4.77-1.32 1.2-7.1-2.39-13.94-1.97-21.03 0.38-3.64-0.91-7.48 0.25-10.99 2.74-3.74 4.57-8.05 7.47-11.67 3.55-5.47 10.31-8.34 16.73-7.64 2.26 2.89 5.13 5.21 7.58 7.92 2.88 4.3 6.52 8.01 9.83 11.97 1.89 2.61 3.06 5.64 4.48 8.52 2.81 4.9 4 10.5 6.63 15.49 2.16 6.04 5.56 11.92 5.37 18.5 0.65 1.95 0.78 4 0.98 6.03 1.01 3.95 2.84 8.55 0.63 12.42-2.4 5.23-7.03 8.97-11.55 12.33-6.06 4.66-11.62 10.05-18.37 13.75-4.06 2.65-8.24 5.17-12.71 7.08-3.59 1.57-6.06 4.94-9.85 6.09-2.29 1.71-3.98 4.51-6.97 5.02-4.56 1.35-8.98-3.72-13.5-1.25-2.99 1.83-6.19 3.21-9.39 4.6-8.5 5.61-18.13 9.48-28.06 11.62-8.36-0.2-16.69 0.62-25.05 0.47-3.5-1.87-7.67-1.08-11.22-2.83-6.19-1.52-10.93-6.01-16.62-8.61-2.87-1.39-5.53-3.16-8.11-4.99-2.58-1.88-4.17-4.85-6.98-6.44-3.83-0.11-6.54 3.42-10.24 3.92-2.31 0.28-4.64 0.32-6.96 0.31-3.5-3.65-5.69-8.74-10.59-10.77-5.01-3.68-10.57-6.67-14.84-11.25-2.52-2.55-5.22-4.87-8.24-6.8-4.73-4.07-7.93-9.51-11.41-14.62-3.08-4.41-5.22-9.73-4.6-15.19 0.65-8.01 0.62-16.18 2.55-24.02 4.06-10.46 11.15-19.34 18.05-28.06 3.71-5.31 9.91-10.21 16.8-8.39 3.25 1.61 5.74 4.56 7.14 7.89 1.19 2.7 3.49 4.93 3.87 7.96 0.97 5.85 1.6 11.86 0.74 17.77-1.7 6.12-2.98 12.53-2.32 18.9 0.01 2.92 2.9 5.36 5.78 4.57 3.06-0.68 3.99-4.07 5.32-6.48 1.67-4.06 4.18-7.66 6.69-11.23 3.61-5.28 5.09-11.57 7.63-17.37 2.07-4.56 1.7-9.64 2.56-14.46 0.78-7.65-0.62-15.44 0.7-23.04 1.32-3.78 1.79-7.89 3.8-11.4 3.01-3.66 6.78-6.63 9.85-10.26 1.72-2.12 4.21-3.32 6.55-4.6 7.89-2.71 15.56-6.75 24.06-7z"/>',n="true"==localStorage.ffzDebugMode&&document.body.classList.contains("ffz-dev");t.exports={DEBUG:n,SERVER:n?"//localhost:8000/":"//cdn.frankerfacez.com/",SVGPATH:o,ZREKNARF:'<svg style="padding:1.75px 0" class="svg-glyph_views" width="16px" viewBox="0 0 249 195" version="1.1" height="12.5px">'+o+"</svg>",CHAT_BUTTON:'<svg class="svg-emoticons ffz-svg" height="18px" width="24px" viewBox="0 0 249 195" version="1.1">'+o+"</svg>"}},{}],4:[function(){var t=e.FrankerFaceZ;t.chat_commands.developer_mode=function(e,t){var o,t=t&&t.length?t[0].toLowerCase():null;return"y"==t||"yes"==t||"true"==t||"on"==t?o=!0:("n"==t||"no"==t||"false"==t||"off"==t)&&(o=!1),void 0===o?"Developer Mode is currently "+("true"==localStorage.ffzDebugMode?"enabled.":"disabled."):(localStorage.ffzDebugMode=o,"Developer Mode is now "+(o?"enabled":"disabled")+". Please refresh your browser.")},t.chat_commands.developer_mode.help="Usage: /ffz developer_mode <on|off>\nEnable or disable Developer Mode. When Developer Mode is enabled, the script will be reloaded from //localhost:8000/script.js instead of from the CDN."},{}],5:[function(){var t=e.FrankerFaceZ;t.prototype.setup_chatview=function(){this.log("Hooking the Ember Chat view.");var e=App.__container__.resolve("view:chat");this._modify_cview(e),e.create().destroy();for(var t in Ember.View.views)if(Ember.View.views.hasOwnProperty(t)){var o=Ember.View.views[t];o instanceof e&&(this.log("Adding UI link manually to Chat view.",o),o.$(".textarea-contain").append(this.build_ui_link(o)))}},t.prototype._modify_cview=function(e){var t=this;e.reopen({didInsertElement:function(){this._super(),this.$()&&this.$(".textarea-contain").append(t.build_ui_link(this))},willClearRender:function(){this._super(),this.$(".ffz-ui-toggle").remove()},ffzUpdateLink:Ember.observer("controller.currentRoom",function(){t.update_ui_link()})})}},{}],6:[function(){var t=e.FrankerFaceZ,o=function(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")};t.prototype.setup_line=function(){this.log("Hooking the Ember Line controller.");var e=App.__container__.resolve("controller:line"),o=this;e.reopen({tokenizedMessage:function(){var e=o._emoticonize(this,this._super()),t=o.get_user();return t&&this.get("model.from")==t.login||(e=o._mentionize(this,e)),e}.property("model.message","isModeratorOrHigher","controllers.emoticons.emoticons.[]")}),this.log("Hooking the Ember Line view.");var e=App.__container__.resolve("view:line");e.reopen({didInsertElement:function(){this._super();var e=this.get("element"),t=this.get("context.model.from");e.setAttribute("data-room",this.get("context.parentController.content.id")),e.setAttribute("data-sender",t),o.render_badge(this),"false"!=localStorage.ffzCapitalize&&o.capitalize(this,t)}});var n=this.get_user();n&&n.name&&(t.capitalization[n.login]=[n.name,Date.now()]),this.mention_words=localStorage.ffzMentionize?JSON.parse(localStorage.ffzMentionize):[]},t.capitalization={},t._cap_fetching=0,t.get_capitalization=function(e,o){if(e=e.toLowerCase(),"jtv"==e||"twitchnotify"==e)return e;var n=t.capitalization[e];return n&&Date.now()-n[1]<36e5?n[0]:(t._cap_fetching<5&&(t._cap_fetching++,Twitch.api.get("users/"+e).always(function(n){var s=n.display_name||e;t.capitalization[e]=[s,Date.now()],t._cap_fetching--,"function"==typeof o&&o(s)})),n?n[0]:e)},t.prototype.capitalize=function(e,o){var n=t.get_capitalization(o,this.capitalize.bind(this,e));n&&e.$(".from").text(n)},t.chat_commands.capitalization=function(e,t){var o,t=t&&t.length?t[0].toLowerCase():null;return"y"==t||"yes"==t||"true"==t||"on"==t?o=!0:("n"==t||"no"==t||"false"==t||"off"==t)&&(o=!1),void 0===o?"Chat Name Capitalization is currently "+("false"!=localStorage.ffzCapitalize?"enabled.":"disabled."):(localStorage.ffzCapitalize=o,"Chat Name Capitalization is now "+(o?"enabled.":"disabled."))},t.chat_commands.capitalization.help="Usage: /ffz capitalization <on|off>\nEnable or disable Chat Name Capitalization. This setting does not work with BetterTTV.",t._regex_cache={},t.get_regex=function(e){return t._regex_cache[e]=t._regex_cache[e]||RegExp("\\b"+o(e)+"\\b","i")},t.prototype._mentionize=function(e,o){return this.mention_words?("string"==typeof o&&(o=[o]),_.each(this.mention_words,function(e){var n={mentionedUser:e,own:!1};o=_.compact(_.flatten(_.map(o,function(o){if(_.isObject(o))return o;var s=o.split(t.get_regex(e)),r=[];return s.forEach(function(e,t){r.push(e),t!==s.length-1&&r.push(n)}),r})))}),o):o},t.chat_commands.mentionize=function(e,t){return t&&t.length&&(this.mention_words=t.join(" ").trim().split(/\W*,\W*/),1==this.mention_words.length&&"disable"==this.mention_words[0]&&(this.mention_words=[]),localStorage.ffzMentionize=JSON.stringify(this.mention_words)),this.mention_words.length?"The following words will be treated as mentions: "+this.mention_words.join(", "):"There are no words set that will be treated as mentions."},t.chat_commands.mentionize.help="Usage: /ffz mentionize <comma, separated, word, list|disable>\nSet a list of words that will also be treated as mentions and be displayed specially in chat.",t.prototype._emoticonize=function(e,t){var o=e.get("parentController.model.id"),n=e.get("model.from"),s=this,r=this.getEmotes(n,o),i=[];return _.each(r,function(e){var o=s.emote_sets[e];o&&_.each(o.emotes,function(e){_.any(t,function(t){return _.isString(t)&&t.match(e.regex)})&&i.push(e)})}),i.length?("string"==typeof t&&(t=[t]),_.each(i,function(e){var o={isEmoticon:!0,cls:e.klass,emoticonSrc:e.url,altText:e.hidden?"???":e.name};t=_.compact(_.flatten(_.map(t,function(t){if(_.isObject(t))return t;var n=t.split(e.regex),s=[];return n.forEach(function(e,t){s.push(e),t!==n.length-1&&s.push(o)}),s})))}),t):t}},{}],7:[function(t){var o=e.FrankerFaceZ,n=/\.([\w\-_]+)\s*?\{content:\s*?"([^"]+)";\s*?background-image:\s*?url\("([^"]+)"\);\s*?height:\s*?(\d+)px;\s*?width:\s*?(\d+)px;\s*?margin:([^;}]+);?([^}]*)\}/gm,s=/[^\n}]*\.badges\s+\.moderator\s*{\s*background-image:\s*url\(\s*['"]([^'"]+)['"][^}]+(?:}|$)/,r=/^_([^_]+)_\d+$/,i=t("../constants"),a=t("../utils"),l=function(e){return e.moderator_badge?'.chat-line[data-room="'+e.id+'"] .badges .moderator { background-image:url("'+e.moderator_badge+'") !important; }':""};o.prototype.setup_room=function(){this.rooms={},this.log("Creating room style element.");var e=this._room_style=document.createElement("style");e.id="ffz-room-css",document.head.appendChild(e),this.log("Hooking the Ember Room model.");var t=App.__container__.resolve("model:room");this._modify_room(t);var o=t.instances;for(var n in o)if(o.hasOwnProperty(n)){var s=o[n];this.add_room(s.id,s),this._modify_room(s)}},o.chat_commands={},o.prototype.room_message=function(e,t){var o=t.split("\n");if(this.has_bttv)for(var n=0;n<o.length;n++)BetterTTV.chat.handlers.onPrivmsg(e.id,{style:"admin",date:new Date,from:"jtv",message:o[n]});else for(var n=0;n<o.length;n++)e.room.addMessage({style:"ffz admin",date:new Date,from:"FFZ",message:o[n]})},o.prototype.run_command=function(e,t){var n=this.rooms[t];if(n&&n.room){if(!e){var s=document.querySelector("a.ffz-ui-toggle");if(s)return s.click();e="help"}var r=e.split(" "),i=r.shift().toLowerCase();this.log("Received Command: "+i,r,!0);var a,l=o.chat_commands[i];if(l)try{a=l.bind(this)(n,r)}catch(c){this.log("Error Running Command - "+i+": "+c,n),a="There was an error running the command."}else a='There is no "'+i+'" command.';a&&this.room_message(n,a)}},o.chat_commands.help=function(e,t){if(t&&t.length){var n=o.chat_commands[t[0].toLowerCase()];return n?n.help?n.help:'No help is available for the command "'+t[0]+'".':'There is no "'+t[0]+'" command.'}var s=[];for(var r in o.chat_commands)o.chat_commands.hasOwnProperty(r)&&s.push(r);return"The available commands are: "+s.join(", ")},o.chat_commands.help.help="Usage: /ffz help [command]\nList available commands, or show help for a specific command.",o.prototype.add_room=function(e,t){return this.rooms[e]?this.log("Tried to add existing room: "+e):(this.log("Adding Room: "+e),this.rooms[e]={id:e,room:t,menu_sets:[],sets:[],css:null},this.ws_send("sub",e),void this._legacy_add_room(e))},o.prototype.remove_room=function(e){var t=this.rooms[e];if(t){this.log("Removing Room: "+e),(t.css||t.moderator_badge)&&a.update_css(this._room_style,e,null),this.ws_send("unsub",e),delete this.rooms[e];for(var o=0;o<t.sets.length;o++){var n=t.sets[o],s=this.emote_sets[n];s&&(s.users.removeObject(e),s.global||s.users.length||this.unload_set(n))}}},o.prototype.load_room=function(e,t){return this._legacy_load_room(e,t)},o.prototype._load_room_json=function(e,t,o){this.rooms[e]&&(o.room=this.rooms[e].room),this.rooms[e]=o,(o.css||o.moderator_badge)&&a.update_css(this._room_style,e,l(o)+(o.css||""));for(var n=0;n<o.sets.length;n++){var s=o.sets[n];this.emote_sets.hasOwnProperty(s)||this.load_set(s)}this.update_ui_link(),t&&t(!0,o)},o.prototype._modify_room=function(e){var t=this;e.reopen({init:function(){this._super(),t.add_room(this.id,this)},willDestroy:function(){this._super(),t.remove_room(this.id)},getSuggestions:function(){var e=this._super();return"false"!=localStorage.ffzCapitalize&&(e=_.map(e,o.get_capitalization)),e},send:function(e){var o=e.split(" ",1)[0].toLowerCase();return"/ffz"!==o?this._super(e):(this.set("messageToSend",""),void t.run_command(e.substr(5),this.get("id")))}})},o.prototype._legacy_add_room=function(e,t,o){jQuery.ajax(i.SERVER+"channel/"+e+".css",{cache:!1,context:this}).done(function(o){this._legacy_load_room_css(e,t,o)}).fail(function(n){return 404==n.status?this._legacy_load_room_css(e,t,null):(o=o||0,o++,10>o?this._legacy_add_room(e,t,o):void 0)})},o.prototype._legacy_load_room_css=function(e,t,o){var i=e,a=i.match(r);a&&a[1]&&(i=a[1]);var l={id:e,menu_sets:[i],sets:[i],moderator_badge:null,css:null};return o&&(o=o.replace(n,"").trim()),o&&(o=o.replace(s,function(e,t){return l.moderator_badge||"modicon.png"!==t.substr(-11)?e:(l.moderator_badge=t,"")})),l.css=o||null,this._load_room_json(e,t,l)}},{"../constants":3,"../utils":23}],8:[function(){var t=e.FrankerFaceZ;t.prototype.setup_router=function(){this.log("Hooking the Ember router.");var e=this;App.__container__.lookup("router:main").reopen({ffzTransition:function(){e.track_page()}.on("didTransition")})}},{}],9:[function(){var t=e.FrankerFaceZ;t.prototype.setup_viewers=function(){this.log("Hooking the Ember Viewers controller.");var e=App.__container__.resolve("controller:viewers");this._modify_viewers(e)},t.prototype._modify_viewers=function(e){var o=this;e.reopen({lines:function(){var e=this._super(),n=[],s={},r=null,i=App.__container__.lookup("controller:channel"),a=this.get("parentController.model.id"),l=i&&i.get("id");if(l){var c=i.get("display_name");c&&(t.capitalization[l]=[c,Date.now()])}a!=l&&(l=null);for(var u=0;u<e.length;u++){var d=e[u];if(d.category)r=d.category,n.push(r),s[r]=[];else{var h=d.chatter.toLowerCase();if(!h)continue;h==l?(n.unshift("Broadcaster"),s.Broadcaster=[h]):s.hasOwnProperty(r)&&s[r].push(h)}}e=[];for(var u=0;u<n.length;u++){var m=n[u],f=s[m];if(f&&f.length)for(e.push({category:m}),e.push({chatter:""}),f.sort();f.length;){var h=f.shift();h=o.has_bttv?BetterTTV.chat.helpers.lookupDisplayName(h):t.get_capitalization(h),e.push({chatter:h})}}return e}.property("content.chatters")})}},{}],10:[function(t){var o=e.FrankerFaceZ,n=/\.([\w\-_]+)\s*?\{content:\s*?"([^"]+)";\s*?background-image:\s*?url\("([^"]+)"\);\s*?height:\s*?(\d+)px;\s*?width:\s*?(\d+)px;\s*?margin:([^;}]+);?([^}]*)\}/gm,s=/[^\n}]*\.badges\s+\.moderator\s*{\s*background-image:\s*url\(\s*['"]([^'"]+)['"][^}]+(?:}|$)/,r=t("./constants"),i=t("./utils"),a=function(e,t,o){t&&(o.global=!0,this.global_sets.push(e))},l=function(e,t){var o=e.split(/ +/);return 2!=o.length?e:(o[0]=parseFloat(o[0]),o[1]=parseFloat(o[1]),o[0]==(t-18)/-2&&0==o[1]?null:e)},c=function(e){var t=e.margins;return t||(t=(e.height-18)/-2+"px 0"),".ffz-emote-"+e.id+' { background-image: url("'+e.url+'"); height: '+e.height+"px; width: "+e.width+"px; margin: "+t+(e.extra_css?"; "+e.extra_css:"")+"}\n"},u=function(e){return e.margins||e.extra_css?c(e)+'img[src="'+e.url+'"] { '+(e.margins?"margin: "+e.margins+";":"")+(e.extra_css||"")+" }\n":c(e)},d=u;o.prototype.setup_emoticons=function(){this.log("Preparing emoticon system."),this.emote_sets={},this.global_sets=[],this._last_emote_id=0,this.log("Creating emoticon style element.");var e=this._emote_style=document.createElement("style");e.id="ffz-emoticon-css",document.head.appendChild(e),this.log("Loading global emote set."),this.load_set("global",a.bind(this,"global"))},o.prototype.getEmotes=function(e,t){var o=this.users[e],n=this.rooms[t];return _.union(o&&o.sets||[],n&&n.sets||[],this.global_sets)},o.ws_commands.reload_set=function(e){this.load_set(e)},o.prototype.load_set=function(e,t){return this._legacy_load_set(e,t)},o.prototype.unload_set=function(e){var t=this.emote_sets[e];if(t){this.log("Unloading emoticons for set: "+e),i.update_css(this._emote_style,e,null),delete this.emote_sets[e];for(var o=0;o<t.users.length;o++){var n=this.rooms[t.users[o]];n&&n.sets.removeObject(e)}}},o.prototype._load_set_json=function(e,t,o){this.emote_sets[e]=o,o.users=[],o.global=!1,o.count=0;var n="";for(var s in o.emotes)if(o.emotes.hasOwnProperty(s)){var r=o.emotes[s];r.klass="ffz-emote-"+r.id,r.regex="!"===r.name[r.name.length-1]?new RegExp("\\b"+r.name+"(?=\\W|$)","g"):new RegExp("\\b"+r.name+"\\b","g"),n+=d(r),o.count++}i.update_css(this._emote_style,e,n+(o.extra_css||"")),this.log("Updated emoticons for set: "+e,o),this.update_ui_link(),t&&t(!0,o)},o.prototype._legacy_load_set=function(e,t,o){jQuery.ajax(r.SERVER+"channel/"+e+".css",{cache:!1,context:this}).done(function(o){this._legacy_load_css(e,t,o)}).fail(function(n){return 404==n.status?"function"==typeof t&&t(!1):(o=o||0,o++,10>o?this._legacy_load_set(e,t,o):"function"==typeof t&&t(!1))})},o.prototype._legacy_load_css=function(e,t,o){var r={},i={id:e,emotes:r,extra_css:null},a=this;o=o.replace(n,function(e,t,o,n,s,i,c,u){s=parseInt(s),i=parseInt(i),c=l(c,s);var d="."===n.substr(n.lastIndexOf("/")+1,1),h=++a._last_emote_id,m={id:h,hidden:d,name:o,height:s,width:i,url:n,margins:c,extra_css:u};return r[h]=m,""}).trim(),o&&o.replace(s,function(e,t){i.icon||"modicon.png"!==t.substr(-11)||(i.icon=t)}),this._load_set_json(e,t,i)}},{"./constants":3,"./utils":23}],11:[function(){var t=e.FrankerFaceZ,o=/(\sdata-sender="[^"]*"(?=>))/;t.prototype.find_bttv=function(t,o){return this.has_bttv=!1,e.BTTVLOADED?this.setup_bttv(o||0):void(o>=6e4?this.log("BetterTTV was not detected after 60 seconds."):setTimeout(this.find_bttv.bind(this,t,(o||0)+t),t))},t.prototype.setup_bttv=function(e){this.log("BetterTTV was detected after "+e+"ms. Hooking."),this.has_bttv=!0,this.track("setCustomVariable","3","BetterTTV",BetterTTV.info.versionString());var t=BetterTTV.chat.helpers.sendMessage,n=this;BetterTTV.chat.helpers.sendMessage=function(e){var o=e.split(" ",1)[0].toLowerCase();return"/ffz"!==o?t(e):void n.run_command(e.substr(5),BetterTTV.chat.store.currentRoom)};var s,r=BetterTTV.chat.handlers.privmsg;BetterTTV.chat.handlers.privmsg=function(e,t){s=e;var o=r(e,t);return s=null,o};var i=BetterTTV.chat.templates.privmsg;BetterTTV.chat.templates.privmsg=function(e,t,r,a,l){n.bttv_badges(l);var c=i(e,t,r,a,l);return c.replace(o,'$1 data-room="'+s+'"')};var a,l=BetterTTV.chat.templates.message;BetterTTV.chat.templates.message=function(e,t,o,n){a=e;var s=l(e,t,o,n);return a=null,s};var c=BetterTTV.chat.templates.emoticonize;BetterTTV.chat.templates.emoticonize=function(e,t){var o=c(e,t),r=n.getEmotes(a,s),t=[];return _.each(r,function(e){var s=n.emote_sets[e];s&&_.each(s.emotes,function(e){_.any(o,function(t){return _.isString(t)&&t.match(e.regex)})&&t.push(e)})}),t.length?(_.each(t,function(e){var t=['<img class="emoticon" src="'+e.url+(e.hidden?"":'" alt="'+e.name+'" title="'+e.name)+'" />'],n=o;if(o=[],!n||!n.length)return o;for(var s=0;s<n.length;s++){var r=n[s];if("string"==typeof r){var i=r.split(e.regex);i.forEach(function(e,n){e&&e.length&&o.push(e),n!==i.length-1&&o.push(t)})}else o.push(r)}}),o):o},this.update_ui_link()}},{}],12:[function(){var t=e.FrankerFaceZ;t.prototype.find_emote_menu=function(t,o){return this.has_emote_menu=!1,e.emoteMenu&&emoteMenu.registerEmoteGetter?this.setup_emote_menu(o||0):void(o>=6e4?this.log("Emote Menu for Twitch was not detected after 60 seconds."):setTimeout(this.find_emote_menu.bind(this,t,(o||0)+t),t))},t.prototype.setup_emote_menu=function(e){this.log("Emote Menu for Twitch was detected after "+e+"ms. Registering emote enumerator."),emoteMenu.registerEmoteGetter("FrankerFaceZ",this._emote_menu_enumerator.bind(this))},t.prototype._emote_menu_enumerator=function(){for(var e=this.get_user(),o=e?e.login:null,n=App.__container__.lookup("controller:chat"),s=n?n.get("currentRoom.id"):null,r=this.getEmotes(o,s),i=[],a=0;a<r.length;a++){var l=this.emote_sets[r[a]];if(l&&l.emotes)for(var c in l.emotes)if(l.emotes.hasOwnProperty(c)){var u=l.emotes[c];if(!u.hidden){var d=l.title,h=l.icon||null;d||(d="global"==l.id?"FrankerFaceZ Global Emotes":"globalevent"==l.id?"FrankerFaceZ Event Emotes":this.feature_friday&&l.id==this.feature_friday.set?"FrankerFaceZ Feature Friday: "+this.feature_friday.channel:"FrankerFaceZ Set: "+t.get_capitalization(l.id)),i.push({text:u.name,url:u.url,hidden:!1,channel:d,badge:h})}}}return i}},{}],13:[function(t){t("./shims");var o=e.FrankerFaceZ=function(){o.instance=this,this.initialize()};o.get=function(){return o.instance};var n=o.version_info={major:3,minor:0,revision:0,toString:function(){return[n.major,n.minor,n.revision].join(".")+(n.extra||"")}};o.prototype.log=function(e,t,o){e="FFZ: "+e+(o?" -- "+JSON.stringify(t):""),void 0!==t&&console.groupCollapsed&&console.dir?(console.groupCollapsed(e),-1!==navigator.userAgent.indexOf("Firefox/")?console.log(t):console.dir(t),console.groupEnd(e)):console.log(e)},o.prototype.get_user=function(){if(e.PP&&PP.login)return PP;if(e.App){var t=App.__container__.lookup("controller:navigation");return t?t.get("userData"):void 0}},t("./socket"),t("./emoticons"),t("./badges"),t("./ember/router"),t("./ember/room"),t("./ember/line"),t("./ember/chatview"),t("./ember/viewers"),t("./tracking"),t("./debug"),t("./ext/betterttv"),t("./ext/emote_menu"),t("./featurefriday"),t("./ui/styles"),t("./ui/notifications"),t("./ui/viewer_count"),t("./ui/menu_button"),t("./ui/menu"),t("./commands"),o.prototype.initialize=function(t,o){var n=void 0!=e.App&&void 0!=App.__container__&&void 0!=App.__container__.resolve("model:room");return n?void this.setup_ember(o):(t=t||10,void(o>=6e4?this.log('Twitch application not detected in "'+location.toString()+'". Aborting.'):setTimeout(this.initialize.bind(this,t,(o||0)+t),t)))},o.prototype.setup_ember=function(t){var n=e.performance&&performance.now?performance.now():Date.now();this.log("Found Twitch application after "+(t||0)+' ms in "'+location+'". Initializing FrankerFaceZ version '+o.version_info),this.users={};for(var s in localStorage)"ffz_"==s.substr(0,4)&&localStorage.removeItem(s);this.ws_create(),this.setup_emoticons(),this.setup_badges(),this.setup_piwik(),this.setup_router(),this.setup_room(),this.setup_line(),this.setup_chatview(),this.setup_viewers(),this.setup_css(),this.setup_menu(),this.find_bttv(10),this.find_emote_menu(10),this.check_ff();var r=e.performance&&performance.now?performance.now():Date.now(),i=r-n;this.log("Initialization complete in "+i+"ms")}},{"./badges":1,"./commands":2,"./debug":4,"./ember/chatview":5,"./ember/line":6,"./ember/room":7,"./ember/router":8,"./ember/viewers":9,"./emoticons":10,"./ext/betterttv":11,"./ext/emote_menu":12,"./featurefriday":14,"./shims":15,"./socket":16,"./tracking":17,"./ui/menu":18,"./ui/menu_button":19,"./ui/notifications":20,"./ui/styles":21,"./ui/viewer_count":22}],14:[function(t){var o=e.FrankerFaceZ,n=t("./constants");o.prototype.feature_friday=null,o.prototype.check_ff=function(e){e||this.log("Checking for Feature Friday data..."),jQuery.ajax(n.SERVER+"script/event.json",{cache:!1,dataType:"json",context:this}).done(function(e){return this._load_ff(e)}).fail(function(t){return 404==t.status?this._load_ff(null):(e=e||0,e++,10>e?setTimeout(this.check_ff.bind(this,e),250):this._load_ff(null))})},o.ws_commands.reload_ff=function(){this.check_ff()},o.prototype._feature_friday_ui=function(e,t,o){if(this.feature_friday&&this.feature_friday.channel!=e){this._emotes_for_sets(t,o,[this.feature_friday.set],"Feature Friday");var n=App.__container__.lookup("controller:channel");if(!n||n.get("id")!=this.feature_friday.channel){var s=this.feature_friday,r=this,i=document.createElement("div"),a=document.createElement("a");i.className="chat-menu-content",i.style.textAlign="center";var l=s.display_name+(s.live?" is live now!":"");a.className="button primary",a.classList.toggle("live",s.live),a.classList.toggle("blue",this.has_bttv&&BetterTTV.settings.get("showBlueButtons")),a.href="http://www.twitch.tv/"+s.channel,a.title=l,a.target="_new",a.innerHTML="<span>"+l+"</span>",a.addEventListener("click",function(){r.track("trackLink",this.href,"link")}),i.appendChild(a),t.appendChild(i)}}},o.prototype._load_ff=function(e){if(this.feature_friday){this.global_sets.removeObject(this.feature_friday.set);var t=this.emote_sets[this.feature_friday.set];t&&(t.global=!1),this.feature_friday=null,this.update_ui_link()}e&&e.set&&e.channel&&(this.feature_friday={set:e.set,channel:e.channel,live:!1,display_name:o.get_capitalization(e.channel,this._update_ff_name.bind(this))},this.global_sets.push(e.set),this.load_set(e.set,this._update_ff_set.bind(this)),this._update_ff_live())},o.prototype._update_ff_live=function(){if(this.feature_friday){var e=this;Twitch.api.get("streams/"+this.feature_friday.channel).done(function(t){e.feature_friday.live=null!=t.stream,e.update_ui_link()}).always(function(){e.feature_friday.timer=setTimeout(e._update_ff_live.bind(e),12e4)})}},o.prototype._update_ff_set=function(e,t){t&&(t.global=!0)},o.prototype._update_ff_name=function(e){this.feature_friday&&(this.feature_friday.display_name=e)}},{"./constants":3}],15:[function(){Array.prototype.equals=function(e){if(!e)return!1;if(this.length!=e.length)return!1;for(var t=0,o=this.length;o>t;t++)if(this[t]instanceof Array&&e[t]instanceof Array){if(!this[t].equals(e[t]))return!1}else if(this[t]!=e[t])return!1;return!0}},{}],16:[function(){var t=e.FrankerFaceZ;t.prototype._ws_open=!1,t.prototype._ws_delay=0,t.ws_commands={},t.prototype.ws_create=function(){var e,o=this;this._ws_last_req=0,this._ws_callbacks={},this._ws_pending=this._ws_pending||[];try{e=this._ws_sock=new WebSocket("ws://ffz.stendec.me/")}catch(n){return this._ws_exists=!1,this.log("Error Creating WebSocket: "+n)}this._ws_exists=!0,e.onopen=function(){o._ws_open=!0,o._ws_delay=0,o.log("Socket connected.");var e=o.get_user();e&&o.ws_send("setuser",e.login);for(var t in o.rooms)o.ws_send("sub",t);var n=o._ws_pending;o._ws_pending=[];for(var s=0;s<n.length;s++){var r=n[s];o.ws_send(r[0],r[1],r[2])}},e.onclose=function(){o.log("Socket closed."),o._ws_open=!1,o._ws_delay<3e4&&(o._ws_delay+=5e3),setTimeout(o.ws_create.bind(o),o._ws_delay)},e.onmessage=function(e){var n,s,r=e.data.indexOf(" "),i=e.data.substr(r+1),a=parseInt(e.data.slice(0,r));if(r=i.indexOf(" "),-1===r&&(r=i.length),n=i.slice(0,r),i=i.substr(r+1),i&&(s=JSON.parse(i)),-1===a){var l=t.ws_commands[n];l?l.bind(o)(s):o.log("Invalid command: "+n,s)}else{var c="True"===n,u=o._ws_callbacks[a];o.log("Socket Reply to "+a+" - "+(c?"SUCCESS":"FAIL"),s),u&&(delete o._ws_callbacks[a],u(c,s))}}},t.prototype.ws_send=function(e,t,o,n){if(!this._ws_open){if(n){var s=this._ws_pending=this._ws_pending||[];return s.push([e,t,o]),!0}return!1}var r=++this._ws_last_req;return t=void 0!==t?" "+JSON.stringify(t):"",o&&(this._ws_callbacks[r]=o),this._ws_sock.send(r+" "+e+t),r}},{}],17:[function(t){var o=e.FrankerFaceZ,n=(t("./constants"),("https:"==document.location.protocol?"https:":"http:")+"//sir.stendec.me/ffz_piwik/");o.prototype.setup_piwik=function(){if(void 0!=e._paq)return this.log("Piwik is already present. Disabling analytics."),void(this._tracking=!1);if("false"==localStorage.ffzTracking)return this.log("The user has opted out of tracking. Disabling analytics."),void(this._tracking=!1);this.log("Initializing Piwik."),this._tracking=!0;var t=e._paq=[];t.push(["setSiteId",1]),t.push(["setTrackerUrl",n+"piwik.php"]),this.has_bttv&&t.push(["setCustomVariable","3","BetterTTV",BetterTTV.info.versionString()]);var o=this.get_user(),s=this;o?(t.push(["setCustomVariable","1","Partnered",o.is_partner?"Yes":"No"]),t.push(["setCustomVariable","2","User Type",o.is_staff?"Staff":o.is_admin?"Admin":"User"]),t.push(["setUserId",o.login]),Twitch.api.get("channels/"+o.login).done(function(e){e.logo&&s.track("setCustomVariable","4","Avatar",e.logo)}).always(function(){s.track_page()})):this.track_page(),"true"==localStorage.ffzTracking&&(this.track("trackEvent","Analytics","Enable"),localStorage.removeItem("ffzTracking"));var r=document.createElement("script");r.type="text/javascript",r.defer=!0,r.async=!0,r.src=n+"piwik.js",document.head.appendChild(r)},o.chat_commands.analytics=function(e,t){var o,t=t&&t.length?t[0].toLowerCase():null;return"y"==t||"yes"==t||"true"==t||"on"==t?o=!0:("n"==t||"no"==t||"false"==t||"off"==t)&&(o=!1),void 0===o?"Analytics are currently "+("false"!=localStorage.ffzTracking?"enabled.":"disabled."):(this._tracking&&!o&&"false"!=localStorage.ffzTracking&&this.track("trackEvent","Analytics","Disable"),localStorage.ffzTracking=o,"Analytics are now "+(o?"enabled":"disabled")+". Please refresh your browser.")
},o.chat_commands.analytics.help="Usage: /ffz analytics <on|off>\nEnable or disable FrankerFaceZ analytics. We collect some data about your browser and how you use FrankerFaceZ to help us improve the script. Turn off analytics if you'd rather we not.",o.prototype.track=function(){this._tracking&&e._paq&&_paq.push(Array.prototype.slice.call(arguments))},o.prototype.track_page=function(){if(this._tracking){this._old_url&&this.track("setReferrerUrl",this._old_url),this._old_url=document.location.toString(),this.track("setCustomUrl",this._old_url),this.track("deleteCustomVariable","1","page"),this.track("deleteCustomVariable","3","page");var e=App.__container__.resolve("router:main").router.currentHandlerInfos;if(e&&0!=e.length){var t=e[e.length-1];if("channel.index"==t.name&&t.context){var o=t.context.get("isFollowing.isFollowing");void 0!==o&&null!==o&&this.track("setCustomVariable","1","Following",o?"Yes":"No","page");var n=t.context.get("game");n&&this.track("setCustomVariable","3","Game",n,"page"),this.track("trackPageView",document.title)}}}}},{"./constants":3}],18:[function(){var t=e.FrankerFaceZ;t.prototype.setup_menu=function(){this.log("Installing mouse-up event to auto-close menus.");var e=this;jQuery(document).mouseup(function(t){var o,n=e._popup;n&&(n=jQuery(n),o=n.parent(),o.is(t.target)||0!==o.has(t.target).length||(n.remove(),delete e._popup))})},t.prototype.build_ui_popup=function(t){var o=this._popup;if(o)return o.parentElement.removeChild(o),void delete this._popup;var n=document.createElement("div"),s=document.createElement("div");n.className="emoticon-selector chat-menu ffz-ui-popup",s.className="emoticon-selector-box dropmenu",n.appendChild(s);var r=t.get("controller.currentRoom.id"),i=this.rooms[r];this.log("Menu for Room: "+r,i),this.track("trackEvent","Menu","Open",r);var a=document.createElement("a");a.className="button glyph-only ffz-button",a.title="Advertise for FrankerFaceZ in chat!",a.href="#",a.innerHTML='<svg class="svg-followers" height="16px" version="1.1" viewBox="0 0 16 16" width="16px" x="0px" y="0px"><path clip-rule="evenodd" d="M8,13.5L1.5,7V4l2-2h3L8,3.5L9.5,2h3l2,2v3L8,13.5z" fill-rule="evenodd"></path></svg>';var l=document.createElement("div");l.className="list-header first",l.appendChild(a),l.appendChild(document.createTextNode("FrankerFaceZ")),s.appendChild(l);var c=this._emotes_for_sets(s,t,i&&i.menu_sets||[]);this._ws_exists?0===c?a.addEventListener("click",this._add_emote.bind(this,t,"To use custom emoticons in tons of channels, get FrankerFaceZ from http://www.frankerfacez.com")):a.addEventListener("click",this._add_emote.bind(this,t,"To view this channel's emoticons, get FrankerFaceZ from http://www.frankerfacez.com")):(a.className="button ffz-button primary",a.innerHTML="Server Error",a.title="FFZ Server Error",a.addEventListener("click",alert.bind(e,"The FrankerFaceZ client was unable to create a WebSocket to communicate with the FrankerFaceZ server.\n\nThis is most likely due to your browser's configuration either disabling WebSockets entirely or limiting the number of simultaneous connections. Please ensure that WebSockets have not been disabled."))),this._feature_friday_ui(r,s,t),this._popup=n,s.style.maxHeight=Math.max(300,t.$().height()-171)+"px",t.$(".chat-interface").append(n)},t.prototype._emotes_for_sets=function(e,t,o,n,s){if(null!=n){var r=document.createElement("div");r.className="list-header",r.appendChild(document.createTextNode(n)),s&&r.appendChild(s),e.appendChild(r)}var i=document.createElement("div"),a=0;i.className="emoticon-grid";for(var l=0;l<o.length;l++){var c=this.emote_sets[o[l]];if(c&&c.emotes)for(var u in c.emotes){var d=c.emotes[u];if(c.emotes.hasOwnProperty(u)&&!d.hidden){a++;var h=document.createElement("span");h.className="emoticon tooltip",h.style.backgroundImage='url("'+d.url+'")',h.style.width=d.width+"px",h.style.height=d.height+"px",h.title=d.name,h.addEventListener("click",this._add_emote.bind(this,t,d.name)),i.appendChild(h)}}}a||(i.innerHTML="This channel has no emoticons.",i.className="chat-menu-content ffz-no-emotes center"),e.appendChild(i)},t.prototype._add_emote=function(e,t){var o=e.get("controller.currentRoom"),n=o.get("messageToSend")||"";n&&" "!==n.substr(-1)&&(n+=" "),o.set("messageToSend",n+(t.name||t))}},{}],19:[function(t){var o=e.FrankerFaceZ,n=t("../constants");o.prototype.build_ui_link=function(e){var t=document.createElement("a");return t.className="ffz-ui-toggle",t.innerHTML=n.CHAT_BUTTON,t.addEventListener("click",this.build_ui_popup.bind(this,e)),this.update_ui_link(t),t},o.prototype.update_ui_link=function(e){var t=App.__container__.lookup("controller:chat");if(e=e||document.querySelector("a.ffz-ui-toggle"),e&&t){var o=t.get("currentRoom.id"),n=this.rooms[o],s=!1,r=this.has_bttv?BetterTTV.settings.get("darkenedMode"):!1,i=this.has_bttv?BetterTTV.settings.get("showBlueButtons"):!1,a=this.feature_friday&&this.feature_friday.live;if(n&&n.sets.length)for(var l=0;l<n.sets.length;l++){var c=this.emote_sets[n.sets[l]];if(c&&c.count>0){s=!0;break}}e.classList.toggle("no-emotes",!s),e.classList.toggle("live",a),e.classList.toggle("dark",r),e.classList.toggle("blue",i)}}},{"../constants":3}],20:[function(){var t=e.FrankerFaceZ;t.prototype.show_notification=function(t){e.noty({text:t,theme:"ffzTheme",layout:"bottomCenter",closeWith:["button"]}).show()},t.ws_commands.message=function(e){this.show_notification(e)}},{}],21:[function(t){var o=e.FrankerFaceZ,n=t("../constants");o.prototype.setup_css=function(){this.log("Injecting main FrankerFaceZ CSS.");var e=this._main_style=document.createElement("link");e.id="ffz-ui-css",e.setAttribute("rel","stylesheet"),e.setAttribute("href",n.SERVER+"script/style.css"),document.head.appendChild(e),jQuery.noty.themes.ffzTheme={name:"ffzTheme",style:function(){this.$bar.removeClass().addClass("noty_bar").addClass("ffz-noty").addClass(this.options.type)},callback:{onShow:function(){},onClose:function(){}}}}},{"../constants":3}],22:[function(t){var o=e.FrankerFaceZ,n=t("../constants"),s=t("../utils");o.ws_commands.viewers=function(e){var t=e[0],o=e[1],r=App.__container__.lookup("controller:channel"),i=r&&r.get&&r.get("id");if(i===t){var a=document.querySelector(".channel-stats .ffz.stat"),l=n.ZREKNARF+" "+s.number_commas(o);if(a)a.innerHTML=l;else{var c=document.querySelector(".channel-stats");if(!c)return;a=document.createElement("span"),a.className="ffz stat",a.title="Viewers with FrankerFaceZ",a.innerHTML=l,c.appendChild(a),jQuery(a).tipsy()}}}},{"../constants":3,"../utils":23}],23:[function(t,o){e.FrankerFaceZ,t("./constants");o.exports={update_css:function(e,t,o){var n=e.innerHTML,s="/*BEGIN "+t+"*/",r="/*END "+t+"*/",i=n.indexOf(s),a=n.indexOf(r),l=-1!==i&&-1!==a&&a>i;(l||o)&&(l&&(n=n.substr(0,i)+n.substr(a+r.length)),o&&(n+=s+o+r),e.innerHTML=n)},number_commas:function(e){var t=e.toString().split(".");return t[0]=t[0].replace(/\B(?=(\d{3})+(?!\d))/g,","),t.join(".")}}},{"./constants":3}]},{},[13]),e.ffz=new FrankerFaceZ}(window);