mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-06-28 15:27:43 +00:00
2 lines
No EOL
57 KiB
JavaScript
2 lines
No EOL
57 KiB
JavaScript
!function(e){!function t(e,n,i){function o(r,a){if(!n[r]){if(!e[r]){var c="function"==typeof require&&require;if(!a&&c)return c(r,!0);if(s)return s(r,!0);throw new Error("Cannot find module '"+r+"'")}var l=n[r]={exports:{}};e[r][0].call(l.exports,function(t){var n=e[r][1][t];return o(n?n:t)},l,l.exports,t,e,n,i)}return n[r].exports}for(var s="function"==typeof require&&require,r=0;r<i.length;r++)o(i[r]);return o}({1:[function(t){var n=e.FrankerFaceZ,i=t("./constants"),o=t("./utils");n.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 s=function(e){return".badges .ffz-badge-"+e.id+" { background-color: "+e.color+'; background-image: url("'+e.image+'"); '+(e.extra_css||"")+"}"};n.prototype.bttv_badges=function(e){var t=e.sender,n=this.users[t],i=[],o=-1;if(n&&n.badges){for(var s=0;s<e.badges.length;s++){var r=e.badges[s];if("subscriber"==r.type||"turbo"==r.type){o=s;break}}for(var a in n.badges)if(n.badges.hasOwnProperty(a)){var r=n.badges[a],c=this.badges[r.id]||{},l=r.title||c.title,d="",u=BetterTTV.settings.get("alphaTags");r.image&&(d+='background-image: url(\\"'+r.image+'\\"); '),r.color&&!u&&(d+="background-color: "+r.color+"; "),r.extra_css&&(d+=r.extra_css),d&&(l+='" style="'+d),i.push([(-1==o?1:-1)*a,{type:"ffz-badge-"+r.id+(u?" alpha":""),name:"",description:l}])}if(i.sort(function(e,t){return e[0]-t[0]}),-1==o)for(;i.length;)e.badges.push(i.shift()[1]);else for(;i.length;)e.badges.insertAt(o,i.shift()[1])}},n.prototype.render_badge=function(e){var t=e.get("context.model.from"),n=(e.get("context.parentController.content.id"),e.$(".badges")),i=this.users[t];if(i&&i.badges){var o=n.find(".badge").filter(function(){var e=this.title.toLowerCase();return"subscriber"==e||"turbo"==e}).first(),s=[],r=!!o.length;for(var a in i.badges)if(i.badges.hasOwnProperty(a)){var c=i.badges[a],l=this.badges[c.id]||{},d=document.createElement("div");d.className="badge float-left tooltip ffz-badge-"+c.id,d.setAttribute("title",c.title||l.title),c.image&&(d.style.backgroundImage='url("'+c.image+'")'),c.color&&(d.style.backgroundColor=c.color),c.extra_css&&(d.style.cssText+=c.extra_css),s.push([(r?1:-1)*a,d])}if(s.sort(function(e,t){return e[0]-t[0]}),r)for(;s.length;)o.before(s.shift()[1]);else for(;s.length;)n.append(s.shift()[1])}},n.prototype._legacy_add_donors=function(e){this.badges[1]={id:1,title:"FFZ Donor",color:"#755000",image:"//cdn.frankerfacez.com/channel/global/donoricon.png"},o.update_css(this._badge_style,1,s(this.badges[1])),this.badges[0]={id:0,title:"FFZ Developer",color:"#FAAF19",image:"//cdn.frankerfacez.com/channel/global/devicon.png"},o.update_css(this._badge_style,0,s(this.badges[0])),this.users.sirstendec={badges:{0:{id:0}}},jQuery.ajax(i.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})},n.prototype._legacy_parse_donors=function(e){var t=0;if(null!=e)for(var n=e.trim().split(/\W+/),i=0;i<n.length;i++){var s=n[i],r=this.users[s]=this.users[s]||{},a=r.badges=r.badges||{};a[0]||(a[0]={id:1},t+=1)}this.log("Added donor badge to "+o.number_commas(t)+" users.")}},{"./constants":3,"./utils":24}],2:[function(){var t=e.FrankerFaceZ;t.ffz_commands.log=function(e){this._pastebin(this._log_data.join("\n"),function(t){return t?void this.room_message(e,"Your FrankerFaceZ log has been pasted to: "+t):this.room_message(e,"There was an error uploading the FrankerFaceZ log.")})},t.ffz_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 n=this.get_user();if(!n||!n.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 i=t.length;t.length;){var o=t.shift();e.room.tmiRoom.sendMessage("/unmod "+o)}return"Sent unmod command for "+i+" users."},t.ffz_commands.massunmod.help="Usage: /ffz massunmod <list, of, users>\nBroadcaster only. Unmod all the users in the provided list.",t.ffz_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 n=this.get_user();if(!n||!n.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 i=t.length;t.length;){var o=t.shift();e.room.tmiRoom.sendMessage("/mod "+o)}return"Sent mod command for "+i+" users."},t.ffz_commands.massmod.help="Usage: /ffz massmod <list, of, users>\nBroadcaster only. Mod all the users in the provided list."},{}],3:[function(e,t){var n='<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"/>',i="true"==localStorage.ffzDebugMode&&document.body.classList.contains("ffz-dev");t.exports={DEBUG:i,SERVER:i?"//localhost:8000/":"//cdn.frankerfacez.com/",SVGPATH:n,ZREKNARF:'<svg style="padding:1.75px 0" class="svg-glyph_views" width="16px" viewBox="0 0 249 195" version="1.1" height="12.5px">'+n+"</svg>",CHAT_BUTTON:'<svg class="svg-emoticons ffz-svg" height="18px" width="24px" viewBox="0 0 249 195" version="1.1">'+n+"</svg>",GEAR:'<svg class="svg-gear" height="16px" version="1.1" viewBox="0 0 16 16" width="16px" x="0px" y="0px"><path clip-rule="evenodd" d="M15,7v2h-2.115c-0.125,0.615-0.354,1.215-0.713,1.758l1.484,1.484l-1.414,1.414l-1.484-1.484C10.215,12.531,9.615,12.76,9,12.885V15H7v-2.12c-0.614-0.126-1.21-0.356-1.751-0.714l-1.491,1.49l-1.414-1.414l1.491-1.49C3.477,10.211,3.247,9.613,3.12,9H1V7h2.116C3.24,6.384,3.469,5.785,3.829,5.242L2.343,3.757l1.414-1.414l1.485,1.485C5.785,3.469,6.384,3.24,7,3.115V1h2v2.12c0.613,0.126,1.211,0.356,1.752,0.714l1.49-1.491l1.414,1.414l-1.49,1.492C12.523,5.79,12.754,6.387,12.88,7H15z M8,6C6.896,6,6,6.896,6,8s0.896,2,2,2s2-0.896,2-2S9.104,6,8,6z" fill-rule="evenodd"></path></svg>',HEART:'<svg class="svg-heart" 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>'}},{}],4:[function(){var t=e.FrankerFaceZ;t.ffz_commands.developer_mode=function(e,t){var n,t=t&&t.length?t[0].toLowerCase():null;return"y"==t||"yes"==t||"true"==t||"on"==t?n=!0:("n"==t||"no"==t||"false"==t||"off"==t)&&(n=!1),void 0===n?"Developer Mode is currently "+("true"==localStorage.ffzDebugMode?"enabled.":"disabled."):(localStorage.ffzDebugMode=n,"Developer Mode is now "+(n?"enabled":"disabled")+". Please refresh your browser.")},t.ffz_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 n=Ember.View.views[t];if(n instanceof e){this.log("Adding UI link manually to Chat view.",n);try{n.$(".textarea-contain").append(this.build_ui_link(n))}catch(i){this.error("setup: build_ui_link: "+i)}}}},t.prototype._modify_cview=function(e){var t=this;e.reopen({didInsertElement:function(){this._super();try{this.$()&&this.$(".textarea-contain").append(t.build_ui_link(this))}catch(e){t.error("didInsertElement: build_ui_link: "+e)}},willClearRender:function(){this._super();try{this.$(".ffz-ui-toggle").remove()}catch(e){t.error("willClearRender: remove ui link: "+e)}},ffzUpdateLink:Ember.observer("controller.currentRoom",function(){try{t.update_ui_link()}catch(e){t.error("ffzUpdateLink: update_ui_link: "+e)}})})}},{}],6:[function(t){var n=e.FrankerFaceZ,i=t("../utils"),o=function(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")};n.settings_info.capitalize={type:"boolean",value:!0,category:"Chat",visible:function(){return!this.has_bttv},name:"Username Capitalization",help:"Display names in chat with proper capitalization."},n.settings_info.keywords={type:"button",value:[],category:"Chat",visible:function(){return!this.has_bttv},name:"Highlight Keywords",help:"Set additional keywords that will be highlighted in chat.",method:function(){var e=this.settings.keywords.join(", "),t=prompt("Highlight Keywords\n\nPlease enter a comma-separated list of words that you would like to be highlighted in chat.",e);null!==t&&void 0!==t&&(t=t.trim().split(/\W*,\W*/),1!=t.length||""!=t[0]&&"disable"!=t[0]||(t=[]),this.settings.set("keywords",t))}},n.settings_info.fix_color={type:"boolean",value:!1,category:"Chat",visible:function(){return!this.has_bttv},name:"Adjust Username Colors",help:"Ensure that username colors contrast with the background enough to be readable.",on_update:function(e){this.has_bttv||document.body.classList.toggle("ffz-chat-colors",e)}},n.settings_info.chat_rows={type:"boolean",value:!1,category:"Chat",visible:function(){return!this.has_bttv},name:"Chat Line Backgrounds",help:"Display alternating background colors for lines in chat.",on_update:function(e){this.has_bttv||document.body.classList.toggle("ffz-chat-background",e)}},n.prototype.setup_line=function(){document.body.classList.toggle("ffz-chat-colors",!this.has_bttv&&this.settings.fix_color),document.body.classList.toggle("ffz-chat-background",!this.has_bttv&&this.settings.chat_rows),this._colors={},this._last_row={};var t=this._fix_color_style=document.createElement("style");t.id="ffz-style-username-colors",t.type="text/css",document.head.appendChild(t),this.log("Hooking the Ember Line controller.");var i=App.__container__.resolve("controller:line"),o=this;i.reopen({tokenizedMessage:function(){var e=this._super();try{e=o._emoticonize(this,e);var t=o.get_user();t&&this.get("model.from")==t.login||(e=o._mentionize(this,e))}catch(n){try{o.error("LineController tokenizedMessage: "+n)}catch(n){}}return e}.property("model.message","isModeratorOrHigher")}),this.log("Hooking the Ember Line view.");var i=App.__container__.resolve("view:line");i.reopen({didInsertElement:function(){this._super();try{var t=this.get("element"),i=this.get("context.model.from"),s=this.get("context.parentController.content.id"),r=this.get("context.model.color"),a=this.get("context.model.ffz_alternate");r&&o._handle_color(r),void 0===a&&(a=o._last_row[s]=o._last_row.hasOwnProperty(s)?!o._last_row[s]:!1,this.set("context.model.ffz_alternate",a)),t.classList.toggle("ffz-alternate",a),t.setAttribute("data-room",s),t.setAttribute("data-sender",i),o.render_badge(this),o.settings.capitalize&&o.capitalize(this,i);var c=t.querySelector("span.mentioned");if(c&&(t.classList.add("ffz-mentioned"),!document.hasFocus()&&!this.get("context.model.ffz_notified")&&o.settings.highlight_notifications)){var l=n.get_capitalization(s),d=n.get_capitalization(i),u=l,h=this.get("context.model.message");this.get("context.parentController.content.isGroupRoom")&&(u=this.get("context.parentController.content.tmiRoom.displayName")),h="action"==this.get("context.model.style")?"* "+d+" "+h:d+": "+h,o.show_notification(h,"Twitch Chat Mention in "+u,l,6e4,e.focus.bind(e))}this.set("context.model.ffz_notified",!0)}catch(p){try{o.error("LineView didInsertElement: "+p)}catch(p){}}}});var s=this.get_user();s&&s.name&&(n.capitalization[s.login]=[s.name,Date.now()])},n.prototype._handle_color=function(e){if(e&&!this._colors[e]){this._colors[e]=!0;var t=parseInt(e.substr(1),16),n=[t>>16,t>>8&255,255&t],o=i.get_luminance(n),s="",r='span[style="color:'+e+'"]',a=!1;if(o>.3){a=!0;for(var c=255,l=n;c--&&(l=i.darken(l),!(i.get_luminance(l)<=.3)););s+=".ffz-chat-colors .ember-chat-container:not(.dark) .chat-line "+r+", .ffz-chat-colors .chat-container:not(.dark) .chat-line "+r+" { color: "+i.rgb_to_css(l)+" !important; }\n"}else s+=".ffz-chat-colors .ember-chat-container:not(.dark) .chat-line "+r+", .ffz-chat-colors .chat-container:not(.dark) .chat-line "+r+" { color: "+e+" !important; }\n";if(.1>o){a=!0;for(var c=255,l=n;c--&&(l=i.brighten(l),!(i.get_luminance(l)>=.1)););s+=".ffz-chat-colors .theatre .chat-container .chat-line "+r+", .ffz-chat-colors .chat-container.dark .chat-line "+r+", .ffz-chat-colors .ember-chat-container.dark .chat-line "+r+" { color: "+i.rgb_to_css(l)+" !important; }\n"}else s+=".ffz-chat-colors .theatre .chat-container .chat-line "+r+", .ffz-chat-colors .chat-container.dark .chat-line "+r+", .ffz-chat-colors .ember-chat-container.dark .chat-line "+r+" { color: "+e+" !important; }\n";a&&(this._fix_color_style.innerHTML+=s)}},n.capitalization={},n._cap_fetching=0,n.get_capitalization=function(t,i){if(e.BetterTTV)return BetterTTV.chat.helpers.lookupDisplayName(t);if(!t)return t;if(t=t.toLowerCase(),"jtv"==t||"twitchnotify"==t)return t;var o=n.capitalization[t];return o&&Date.now()-o[1]<36e5?o[0]:(n._cap_fetching<5&&(n._cap_fetching++,Twitch.api.get("users/"+t).always(function(e){var o=e.display_name||t;n.capitalization[t]=[o,Date.now()],n._cap_fetching--,"function"==typeof i&&i(o)})),o?o[0]:t)},n.prototype.capitalize=function(e,t){var i=n.get_capitalization(t,this.capitalize.bind(this,e));i&&e.$(".from").text(i)},n._regex_cache={},n._get_regex=function(e){return n._regex_cache[e]=n._regex_cache[e]||RegExp("\\b"+o(e)+"\\b","ig")},n._mentions_to_regex=function(e){return n._regex_cache[e]=n._regex_cache[e]||RegExp("\\b(?:"+_.chain(e).map(o).value().join("|")+")\\b","ig")},n.prototype._mentionize=function(e,t){var i=this.settings.keywords;if(!i||!i.length)return t;"string"==typeof t&&(t=[t]);var o=n._mentions_to_regex(i);return _.chain(t).map(function(e){return _.isString(e)?e.match(o)?_.zip(_.map(e.split(o),_.identity),_.map(e.match(o),function(e){return{mentionedUser:e,own:!1}})):[e]:e}).flatten().compact().value()},n.prototype._emoticonize=function(e,t){var n=e.get("parentController.model.id"),i=e.get("model.from"),o=this,s=this.getEmotes(i,n),r=[];return _.each(s,function(e){var n=o.emote_sets[e];n&&_.each(n.emotes,function(e){_.any(t,function(t){return _.isString(t)&&t.match(e.regex)})&&r.push(e)})}),r.length?("string"==typeof t&&(t=[t]),_.each(r,function(e){var n={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 i=t.split(e.regex),o=[];return i.forEach(function(e,t){o.push(e),t!==i.length-1&&o.push(n)}),o})))}),t):t}},{"../utils":24}],7:[function(t){var n=e.FrankerFaceZ,i=t("../utils"),o={ESC:27,P:80,B:66,T:84},s=[["5m",300],["10m",600],["1hr",3600],["12hr",43200],["24hr",86400]],r='<svg class="svg-messages" height="16px" version="1.1" viewBox="0 0 18 18" width="16px" x="0px" y="0px"><path clip-rule="evenodd" d="M1,15V3h16v12H1z M15.354,5.354l-0.707-0.707L9,10.293L3.354,4.646L2.646,5.354L6.293,9l-3.646,3.646l0.707,0.707L7,9.707l1.646,1.646h0.707L11,9.707l3.646,3.646l0.707-0.707L11.707,9L15.354,5.354z" fill-rule="evenodd"></path></svg>';n.settings_info.enhanced_moderation={type:"boolean",value:!1,visible:function(){return!this.has_bttv},category:"Chat",name:"Enhanced Moderation",help:"Use /p, /t, /u and /b in chat to moderator, or use hotkeys with moderation cards."},n.prototype.setup_mod_card=function(){this.log("Hooking the Ember Moderation Card view.");var e=App.__container__.resolve("view:moderation-card"),t=this;e.reopen({didInsertElement:function(){this._super();try{if(!t.settings.enhanced_moderation)return;var e=this.get("element"),n=this.get("context");if(n.get("parentController.model.isModeratorOrHigher")){e.classList.add("ffz-moderation-card"),e.setAttribute("tabindex",1),e.addEventListener("keyup",function(e){var t=e.keyCode||e.which,i=n.get("model.user.id"),s=n.get("parentController.model");if(t==o.P)s.send("/timeout "+i+" 1");else if(t==o.B)s.send("/ban "+i);else if(t==o.T)s.send("/timeout "+i+" 600");else if(t!=o.ESC)return;n.send("hideModOverlay")});var a=document.createElement("div");a.className="interface clearfix";var c=function(e){var t=n.get("model.user.id"),i=n.get("parentController.model");i.send(-1===e?"/unban "+t:"/timeout "+t+" "+e)},l=function(e,t){var n=document.createElement("button");return n.className="button",n.innerHTML=e,n.title="Timeout User for "+i.number_commas(t)+" Second"+(1!=t?"s":""),600===t?n.title="(T)"+n.title.substr(1):1===t&&(n.title="(P)urge - "+n.title),jQuery(n).tipsy(),n.addEventListener("click",c.bind(this,t)),n};a.appendChild(l("Purge",1));var d=document.createElement("span");d.className="right",a.appendChild(d);for(var u=0;u<s.length;u++)d.appendChild(l(s[u][0],s[u][1]));e.appendChild(a);var h=document.createElement("button");h.className="unban button glyph-only light",h.innerHTML="✓",h.title="(U)nban User",jQuery(h).tipsy(),h.addEventListener("click",c.bind(this,-1));var p=e.querySelector("button.ban");p.setAttribute("title","(B)an User"),jQuery(p).after(h),this.$("button.timeout").remove()}var _=e.querySelector("button.mod");if(_){var f=n.get("parentController.model"),m=f.get("isBroadcaster")||f.get("isStaff")||f.get("isAdmin");m||_.parentElement.removeChild(_)}var g=e.querySelector(".interface > button");g&&"button"==g.className&&(g.innerHTML=r,g.classList.add("glyph-only"),g.classList.add("message"),g.title="Message User",jQuery(g).tipsy()),this.$().draggable({start:function(){e.focus()}}),e.focus()}catch(v){try{t.error("ModerationCardView didInsertElement: "+v)}catch(v){}}}})},n.chat_commands.purge=n.chat_commands.p=function(e,t){if(!t||!t.length)return"Purge Usage: /p username [more usernames separated by spaces]";if(t.length>10)return"Please only purge up to 10 users at once.";for(var n=0;n<t.length;n++){var i=t[n];i&&e.room.send("/timeout "+i+" 1")}},n.chat_commands.p.enabled=function(){return this.settings.enhanced_moderation},n.chat_commands.t=function(e,t){return t&&t.length?void e.room.send("/timeout "+t.join(" ")):"Timeout Usage: /t username [duration]"},n.chat_commands.t.enabled=function(){return this.settings.enhanced_moderation},n.chat_commands.b=function(e,t){if(!t||!t.length)return"Ban Usage: /b username [more usernames separated by spaces]";if(t.length>10)return"Please only ban up to 10 users at once.";for(var n=0;n<t.length;n++){var i=t[n];i&&e.room.send("/ban "+i)}},n.chat_commands.b.enabled=function(){return this.settings.enhanced_moderation},n.chat_commands.u=function(e,t){if(!t||!t.length)return"Unban Usage: /b username [more usernames separated by spaces]";if(t.length>10)return"Please only unban up to 10 users at once.";for(var n=0;n<t.length;n++){var i=t[n];i&&e.room.send("/unban "+i)}},n.chat_commands.u.enabled=function(){return this.settings.enhanced_moderation}},{"../utils":24}],8:[function(t){var n=e.FrankerFaceZ,i=/\.([\w\-_]+)\s*?\{content:\s*?"([^"]+)";\s*?background-image:\s*?url\("([^"]+)"\);\s*?height:\s*?(\d+)px;\s*?width:\s*?(\d+)px;\s*?margin:([^;}]+);?([^}]*)\}/gm,o=/[^\n}]*\.badges\s+\.moderator\s*{\s*background-image:\s*url\(\s*['"]([^'"]+)['"][^}]+(?:}|$)/,s=/^_([^_]+)_\d+$/,r=t("../constants"),a=t("../utils"),c=function(e){return e.moderator_badge?'.chat-line[data-room="'+e.id+'"] .badges .moderator { background-image:url("'+e.moderator_badge+'") !important; }':""};n.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 n=t.instances;for(var i in n)if(n.hasOwnProperty(i)){var o=n[i];this.add_room(o.id,o),this._modify_room(o)}},n.chat_commands={},n.ffz_commands={},n.prototype.room_message=function(e,t){var n=t.split("\n");if(this.has_bttv)for(var i=0;i<n.length;i++)BetterTTV.chat.handlers.onPrivmsg(e.id,{style:"admin",date:new Date,from:"jtv",message:n[i]});else for(var i=0;i<n.length;i++)e.room.addMessage({style:"ffz admin",date:new Date,from:"FFZ",message:n[i]})},n.prototype.run_command=function(e,t){var i=this.rooms[t];if(!i||!i.room)return!1;if(e){var o,s=e.split(" "),r=s.shift().substr(1).toLowerCase(),a=n.chat_commands[r];if(!a)return!1;if(a.hasOwnProperty("enabled")){var c=a.enabled;if("function"==typeof c)try{c=a.enabled.bind(this)(i,s)}catch(l){this.error('command "'+r+'" enabled: '+l),c=!1}if(!c)return!1}this.log("Received Command: "+r,s,!0);try{o=a.bind(this)(i,s)}catch(l){this.error('command "'+r+'" runner: '+l),o="There was an error running the command."}return o&&this.room_message(i,o),!0}},n.prototype.run_ffz_command=function(e,t){var i=this.rooms[t];if(i&&i.room){if(!e){var o=document.querySelector("a.ffz-ui-toggle");if(o)return o.click();e="help"}var s=e.split(" "),r=s.shift().toLowerCase();this.log("Received Command: "+r,s,!0);var a,c=n.ffz_commands[r];if(c)try{a=c.bind(this)(i,s)}catch(l){this.log("Error Running Command - "+r+": "+l,i),a="There was an error running the command."}else a='There is no "'+r+'" command.';a&&this.room_message(i,a)}},n.ffz_commands.help=function(e,t){if(t&&t.length){var i=n.ffz_commands[t[0].toLowerCase()];return i?i.help?i.help:'No help is available for the command "'+t[0]+'".':'There is no "'+t[0]+'" command.'}var o=[];for(var s in n.ffz_commands)n.ffz_commands.hasOwnProperty(s)&&o.push(s);return"The available commands are: "+o.join(", ")},n.ffz_commands.help.help="Usage: /ffz help [command]\nList available commands, or show help for a specific command.",n.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))},n.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 n=0;n<t.sets.length;n++){var i=t.sets[n],o=this.emote_sets[i];o&&(o.users.removeObject(e),o.global||o.users.length||this.unload_set(i))}}},n.prototype.load_room=function(e,t){return this._legacy_load_room(e,t)},n.prototype._load_room_json=function(e,t,n){this.rooms[e]&&(n.room=this.rooms[e].room),this.rooms[e]=n,(n.css||n.moderator_badge)&&a.update_css(this._room_style,e,c(n)+(n.css||""));for(var i=0;i<n.sets.length;i++){var o=n.sets[i];this.emote_sets.hasOwnProperty(o)||this.load_set(o)}this.update_ui_link(),t&&t(!0,n)},n.prototype._modify_room=function(e){var t=this;e.reopen({init:function(){this._super();try{t.add_room(this.id,this)}catch(e){t.error("add_room: "+e)}},willDestroy:function(){this._super();try{t.remove_room(this.id)}catch(e){t.error("remove_room: "+e)}},getSuggestions:function(){var e=this._super();try{t.settings.capitalize&&(e=_.map(e,n.get_capitalization))}catch(i){t.error("get_suggestions: "+i)}return e},send:function(e){try{var n=e.split(" ",1)[0].toLowerCase();if("/ffz"===n)return this.set("messageToSend",""),void t.run_ffz_command(e.substr(5),this.get("id"));if("/"===n.charAt(0)&&t.run_command(e,this.get("id")))return void this.set("messageToSend","")}catch(i){t.error("send: "+i)}return this._super(e)}})},n.prototype._legacy_add_room=function(e,t,n){jQuery.ajax(r.SERVER+"channel/"+e+".css",{cache:!1,context:this}).done(function(n){this._legacy_load_room_css(e,t,n)}).fail(function(i){return 404==i.status?this._legacy_load_room_css(e,t,null):(n=n||0,n++,10>n?this._legacy_add_room(e,t,n):void 0)})},n.prototype._legacy_load_room_css=function(e,t,n){var r=e,a=r.match(s);a&&a[1]&&(r=a[1]);var c={id:e,menu_sets:[r],sets:[r],moderator_badge:null,css:null};return n&&(n=n.replace(i,"").trim()),n&&(n=n.replace(o,function(e,t){return c.moderator_badge||"modicon.png"!==t.substr(-11)?e:(c.moderator_badge=t,"")})),c.css=n||null,this._load_room_json(e,t,c)}},{"../constants":3,"../utils":24}],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 n=this;e.reopen({lines:function(){var e=this._super();try{var i=[],o={},s=null,r=App.__container__.lookup("controller:channel"),a=this.get("parentController.model.id"),c=r&&r.get("id");if(c){var l=r.get("display_name");l&&(t.capitalization[c]=[l,Date.now()])}a!=c&&(c=null);for(var d=0;d<e.length;d++){var u=e[d];if(u.category)s=u.category,i.push(s),o[s]=[];else{var h=u.chatter.toLowerCase();if(!h)continue;h==c?(i.unshift("Broadcaster"),o.Broadcaster=[h]):o.hasOwnProperty(s)&&o[s].push(h)}}e=[];for(var d=0;d<i.length;d++){var p=i[d],_=o[p];if(_&&_.length)for(e.push({category:p}),e.push({chatter:""}),_.sort();_.length;){var h=_.shift();h=t.get_capitalization(h),e.push({chatter:h})}}}catch(f){n.error("ViewersController lines: "+f)}return e}.property("content.chatters")})}},{}],10:[function(t){var n=e.FrankerFaceZ,i=/\.([\w\-_]+)\s*?\{content:\s*?"([^"]+)";\s*?background-image:\s*?url\("([^"]+)"\);\s*?height:\s*?(\d+)px;\s*?width:\s*?(\d+)px;\s*?margin:([^;}]+);?([^}]*)\}/gm,o=/[^\n}]*\.badges\s+\.moderator\s*{\s*background-image:\s*url\(\s*['"]([^'"]+)['"][^}]+(?:}|$)/,s=t("./constants"),r=t("./utils"),a=function(e,t,n){t&&(n.global=!0,this.global_sets.push(e))},c=function(e,t){var n=e.split(/ +/);return 2!=n.length?e:(n[0]=parseFloat(n[0]),n[1]=parseFloat(n[1]),n[0]==(t-18)/-2&&0==n[1]?null:e)},l=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"},d=function(e){return e.margins||e.extra_css?l(e)+'img[src="'+e.url+'"] { '+(e.margins?"margin: "+e.margins+";":"")+(e.extra_css||"")+" }\n":l(e)},u=d;n.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"))},n.prototype.getEmotes=function(e,t){var n=this.users[e],i=this.rooms[t];return _.union(n&&n.sets||[],i&&i.sets||[],this.global_sets)},n.ws_commands.reload_set=function(e){this.load_set(e)},n.prototype.load_set=function(e,t){return this._legacy_load_set(e,t)},n.prototype.unload_set=function(e){var t=this.emote_sets[e];if(t){this.log("Unloading emoticons for set: "+e),r.update_css(this._emote_style,e,null),delete this.emote_sets[e];for(var n=0;n<t.users.length;n++){var i=this.rooms[t.users[n]];i&&i.sets.removeObject(e)}}},n.prototype._load_set_json=function(e,t,n){this.emote_sets[e]=n,n.users=[],n.global=!1,n.count=0;var i="";for(var o in n.emotes)if(n.emotes.hasOwnProperty(o)){var s=n.emotes[o];s.klass="ffz-emote-"+s.id,s.regex="!"===s.name[s.name.length-1]?new RegExp("\\b"+s.name+"(?=\\W|$)","g"):new RegExp("\\b"+s.name+"\\b","g"),i+=u(s),n.count++}r.update_css(this._emote_style,e,i+(n.extra_css||"")),this.log("Updated emoticons for set: "+e,n),this.update_ui_link(),t&&t(!0,n)},n.prototype._legacy_load_set=function(e,t,n){jQuery.ajax(s.SERVER+"channel/"+e+".css",{cache:!1,context:this}).done(function(n){this._legacy_load_css(e,t,n)}).fail(function(i){return 404==i.status?"function"==typeof t&&t(!1):(n=n||0,n++,10>n?this._legacy_load_set(e,t,n):"function"==typeof t&&t(!1))})},n.prototype._legacy_load_css=function(e,t,n){var s={},r={id:e,emotes:s,extra_css:null},a=this;n=n.replace(i,function(e,t,n,i,o,r,l,d){o=parseInt(o),r=parseInt(r),l=c(l,o);var u="."===i.substr(i.lastIndexOf("/")+1,1),h=++a._last_emote_id,p={id:h,hidden:u,name:n,height:o,width:r,url:i,margins:l,extra_css:d};return s[h]=p,""}).trim(),n&&n.replace(o,function(e,t){r.icon||"modicon.png"!==t.substr(-11)||(r.icon=t)}),this._load_set_json(e,t,r)}},{"./constants":3,"./utils":24}],11:[function(){var t=e.FrankerFaceZ,n=/(\sdata-sender="[^"]*"(?=>))/;t.prototype.find_bttv=function(t,n){return this.has_bttv=!1,e.BTTVLOADED?this.setup_bttv(n||0):void(n>=6e4?this.log("BetterTTV was not detected after 60 seconds."):setTimeout(this.find_bttv.bind(this,t,(n||0)+t),t))},t.prototype.setup_bttv=function(e){this.log("BetterTTV was detected after "+e+"ms. Hooking."),this.has_bttv=!0,document.body.classList.remove("ffz-dark"),this._dark_style&&(this._dark_style.parentElement.removeChild(this._dark_style),delete this._dark_style),document.body.classList.remove("ffz-chat-colors"),document.body.classList.remove("ffz-chat-background");var t=BetterTTV.chat.helpers.sendMessage,i=this;BetterTTV.chat.helpers.sendMessage=function(e){var n=e.split(" ",1)[0].toLowerCase();return"/ffz"!==n?t(e):void i.run_ffz_command(e.substr(5),BetterTTV.chat.store.currentRoom)};var o,s=BetterTTV.chat.handlers.privmsg;BetterTTV.chat.handlers.privmsg=function(e,t){o=e;var n=s(e,t);return o=null,n};var r=BetterTTV.chat.templates.privmsg;BetterTTV.chat.templates.privmsg=function(e,t,s,a,c){i.bttv_badges(c);var l=r(e,t,s,a,c);return l.replace(n,'$1 data-room="'+o+'"')};var a,c=BetterTTV.chat.templates.message;BetterTTV.chat.templates.message=function(e,t,n,i){a=e;var o=c(e,t,n,i);return a=null,o};var l=BetterTTV.chat.templates.emoticonize;BetterTTV.chat.templates.emoticonize=function(e,t){var n=l(e,t),s=i.getEmotes(a,o),t=[];return _.each(s,function(e){var o=i.emote_sets[e];o&&_.each(o.emotes,function(e){_.any(n,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)+'" />'],i=n;if(n=[],!i||!i.length)return n;for(var o=0;o<i.length;o++){var s=i[o];if("string"==typeof s){var r=s.split(e.regex);r.forEach(function(e,i){e&&e.length&&n.push(e),i!==r.length-1&&n.push(t)})}else n.push(s)}}),n):n},this.update_ui_link()}},{}],12:[function(){var t=e.FrankerFaceZ;t.prototype.find_emote_menu=function(t,n){return this.has_emote_menu=!1,e.emoteMenu&&emoteMenu.registerEmoteGetter?this.setup_emote_menu(n||0):void(n>=6e4?this.log("Emote Menu for Twitch was not detected after 60 seconds."):setTimeout(this.find_emote_menu.bind(this,t,(n||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(),n=e?e.login:null,i=App.__container__.lookup("controller:chat"),o=i?i.get("currentRoom.id"):null,s=this.getEmotes(n,o),r=[],a=0;a<s.length;a++){var c=this.emote_sets[s[a]];if(c&&c.emotes)for(var l in c.emotes)if(c.emotes.hasOwnProperty(l)){var d=c.emotes[l];if(!d.hidden){var u=c.title,h=c.icon||null;u||(u="global"==c.id?"FrankerFaceZ Global Emotes":"globalevent"==c.id?"FrankerFaceZ Event Emotes":this.feature_friday&&c.id==this.feature_friday.set?"FrankerFaceZ Feature Friday: "+this.feature_friday.channel:"FrankerFaceZ Set: "+t.get_capitalization(c.id)),r.push({text:d.name,url:d.url,hidden:!1,channel:u,badge:h})}}}return r}},{}],13:[function(t){t("./shims");var n=e.FrankerFaceZ=function(){n.instance=this,this._log_data=[],this.initialize()};n.get=function(){return n.instance};var i=n.version_info={major:3,minor:1,revision:0,toString:function(){return[i.major,i.minor,i.revision].join(".")+(i.extra||"")}};n.prototype.log=function(e,t,n){e="FFZ: "+e+(n?" -- "+JSON.stringify(t):""),this._log_data.push(e),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)},n.prototype.error=function(e,t,n){e="FFZ Error: "+e+(n?" -- "+JSON.stringify(t):""),this._log_data.push(e),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.assert(!1,e)},n.prototype.paste_logs=function(){this._pastebin(this._log_data.join("\n"),function(e){return e?void console.log("FFZ: Your FrankerFaceZ log has been pasted to: "+e):console.log("FFZ Error: Unable to upload log to pastebin.")})},n.prototype._pastebin=function(e,t){jQuery.ajax({url:"http://putco.de/",type:"PUT",data:e,context:this}).success(function(e){t.bind(this)(e.trim()+".log")}).fail(function(){t.bind(this)(null)})},n.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("./settings"),t("./socket"),t("./emoticons"),t("./badges"),t("./ember/room"),t("./ember/line"),t("./ember/chatview"),t("./ember/viewers"),t("./ember/moderation-card"),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("./ui/races"),t("./commands"),n.prototype.initialize=function(t,n){var i=void 0!=e.App&&void 0!=App.__container__&&void 0!=App.__container__.resolve("model:room");return i?void this.setup_ember(n):(t=t||10,void(n>=6e4?this.log('Twitch application not detected in "'+location.toString()+'". Aborting.'):setTimeout(this.initialize.bind(this,t,(n||0)+t),t)))},n.prototype.setup_ember=function(t){var i=e.performance&&performance.now?performance.now():Date.now();this.log("Found Twitch application after "+(t||0)+' ms in "'+location+'". Initializing FrankerFaceZ version '+n.version_info),this.users={},this.load_settings(),this.ws_create(),this.setup_emoticons(),this.setup_badges(),this.setup_room(),this.setup_line(),this.setup_chatview(),this.setup_viewers(),this.setup_mod_card(),this.setup_notifications(),this.setup_css(),this.setup_menu(),this.setup_races(),this.find_bttv(10),this.find_emote_menu(10),this.check_ff();var o=e.performance&&performance.now?performance.now():Date.now(),s=o-i;this.log("Initialization complete in "+s+"ms")}},{"./badges":1,"./commands":2,"./debug":4,"./ember/chatview":5,"./ember/line":6,"./ember/moderation-card":7,"./ember/room":8,"./ember/viewers":9,"./emoticons":10,"./ext/betterttv":11,"./ext/emote_menu":12,"./featurefriday":14,"./settings":15,"./shims":16,"./socket":17,"./ui/menu":18,"./ui/menu_button":19,"./ui/notifications":20,"./ui/races":21,"./ui/styles":22,"./ui/viewer_count":23}],14:[function(t){var n=e.FrankerFaceZ,i=t("./constants");n.prototype.feature_friday=null,n.prototype.check_ff=function(e){e||this.log("Checking for Feature Friday data..."),jQuery.ajax(i.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))})},n.ws_commands.reload_ff=function(){this.check_ff()},n.prototype._feature_friday_ui=function(e,t,n){if(this.feature_friday&&this.feature_friday.channel!=e){this._emotes_for_sets(t,n,[this.feature_friday.set],"Feature Friday");var i=App.__container__.lookup("controller:channel");if(!i||i.get("id")!=this.feature_friday.channel){var o=this.feature_friday,s=document.createElement("div"),r=document.createElement("a");s.className="chat-menu-content",s.style.textAlign="center";var a=o.display_name+(o.live?" is live now!":"");r.className="button primary",r.classList.toggle("live",o.live),r.classList.toggle("blue",this.has_bttv&&BetterTTV.settings.get("showBlueButtons")),r.href="http://www.twitch.tv/"+o.channel,r.title=a,r.target="_new",r.innerHTML="<span>"+a+"</span>",s.appendChild(r),t.appendChild(s)}}},n.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:n.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())},n.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)})}},n.prototype._update_ff_set=function(e,t){t&&(t.global=!0)},n.prototype._update_ff_name=function(e){this.feature_friday&&(this.feature_friday.display_name=e)}},{"./constants":3}],15:[function(){var t=e.FrankerFaceZ,n=function(e){return"ffz_setting_"+e};t.settings_info={},t.prototype.load_settings=function(){this.log("Loading settings."),this.settings={};for(var i in t.settings_info){var o=n(i),s=t.settings_info[i],r=s.hasOwnProperty("value")?s.value:void 0;if(localStorage.hasOwnProperty(o))try{r=JSON.parse(localStorage.getItem(o))}catch(a){this.log('Error loading value for "'+i+'": '+a)}this.settings[i]=r}this.settings.get=this._setting_get.bind(this),this.settings.set=this._setting_set.bind(this),this.settings.del=this._setting_del.bind(this),e.addEventListener("storage",this._setting_update.bind(this))},t.prototype._setting_update=function(n){if(n||(n=e.event),this.log("Storage Event",n),n.key&&"ffz_setting_"===n.key.substr(0,12)){var i=n.key,o=i.substr(12),s=void 0,r=t.settings_info[o];this.log("Updated Setting: "+o);try{s=JSON.parse(n.newValue)}catch(a){this.log('Error loading new value for "'+o+'": '+a),s=r.value||void 0}if(this.settings[o]=s,r.on_update)try{r.on_update.bind(this)(s,!1)}catch(a){this.log('Error running updater for setting "'+o+'": '+a)}}},t.prototype._setting_get=function(e){return this.settings[e]},t.prototype._setting_set=function(e,i){var o=n(e),s=t.settings_info[e],r=JSON.stringify(i);if(this.settings[e]=i,localStorage.setItem(o,r),this.log('Changed Setting "'+e+'" to: '+r),s.on_update)try{s.on_update.bind(this)(i,!0)}catch(a){this.log('Error running updater for setting "'+e+'": '+a)}},t.prototype._setting_del=function(e){var i=n(e),o=t.settings_info[e],s=void 0;if(localStorage.hasOwnProperty(i)&&localStorage.removeItem(i),delete this.settings[e],o&&(s=this.settings[e]=o.hasOwnProperty("value")?o.value:void 0),o.on_update)try{o.on_update.bind(this)(s,!0)}catch(r){this.log('Error running updater for setting "'+e+'": '+r)}}},{}],16:[function(){Array.prototype.equals=function(e){if(!e)return!1;if(this.length!=e.length)return!1;for(var t=0,n=this.length;n>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}},{}],17:[function(){var t=e.FrankerFaceZ;t.prototype._ws_open=!1,t.prototype._ws_delay=0,t.ws_commands={},t.ws_on_close=[],t.prototype.ws_create=function(){var e,n=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(i){return this._ws_exists=!1,this.log("Error Creating WebSocket: "+i)}this._ws_exists=!0,e.onopen=function(){n._ws_open=!0,n._ws_delay=0,n.log("Socket connected.");var e=n.get_user();e&&n.ws_send("setuser",e.login);for(var t in n.rooms)n.ws_send("sub",t);var i=n._ws_pending;n._ws_pending=[];for(var o=0;o<i.length;o++){var s=i[o];n.ws_send(s[0],s[1],s[2])}},e.onclose=function(){n.log("Socket closed."),n._ws_open=!1;for(var e=0;e<t.ws_on_close.length;e++)try{t.ws_on_close[e].bind(n)()}catch(i){n.log("Error on Socket Close Callback: "+i)}n._ws_delay<3e4&&(n._ws_delay+=5e3),setTimeout(n.ws_create.bind(n),n._ws_delay)},e.onmessage=function(e){var i,o,s=e.data.indexOf(" "),r=e.data.substr(s+1),a=parseInt(e.data.slice(0,s));if(s=r.indexOf(" "),-1===s&&(s=r.length),i=r.slice(0,s),r=r.substr(s+1),r&&(o=JSON.parse(r)),-1===a){var c=t.ws_commands[i];c?c.bind(n)(o):n.log("Invalid command: "+i,o)}else{var l="True"===i,d=n._ws_callbacks[a];n.log("Socket Reply to "+a+" - "+(l?"SUCCESS":"FAIL"),o),d&&(delete n._ws_callbacks[a],d(l,o))}}},t.prototype.ws_send=function(e,t,n,i){if(!this._ws_open){if(i){var o=this._ws_pending=this._ws_pending||[];return o.push([e,t,n]),!0}return!1}var s=++this._ws_last_req;return t=void 0!==t?" "+JSON.stringify(t):"",n&&(this._ws_callbacks[s]=n),this._ws_sock.send(s+" "+e+t),s}},{}],18:[function(t){var n=e.FrankerFaceZ,i=t("../constants");n.prototype.setup_menu=function(){this.log("Installing mouse-up event to auto-close menus.");var e=this;jQuery(document).mouseup(function(t){var n,i=e._popup;i&&(i=jQuery(i),n=i.parent(),n.is(t.target)||0!==n.has(t.target).length||(i.remove(),delete e._popup,e._popup_kill&&e._popup_kill(),delete e._popup_kill))})},n.menu_pages={},n.prototype.build_ui_popup=function(e){var t=this._popup;if(t)return t.parentElement.removeChild(t),delete this._popup,this._popup_kill&&this._popup_kill(),void delete this._popup_kill;var i=document.createElement("div"),o=document.createElement("div"),s=document.createElement("ul"),r=this.has_bttv?BetterTTV.settings.get("darkenedMode"):!1;i.className="emoticon-selector chat-menu ffz-ui-popup",o.className="emoticon-selector-box dropmenu",i.appendChild(o),i.classList.toggle("dark",r),s.className="menu clearfix",o.appendChild(s);var a=document.createElement("li");a.className="title",a.innerHTML="<span>FrankerFaceZ</span>",s.appendChild(a),a.addEventListener("click",this._add_emote.bind(this,e,"To use custom emoticons in tons of channels, get FrankerFaceZ from http://www.frankerfacez.com"));var c=document.createElement("div");c.className="ffz-ui-menu-page",o.appendChild(c);for(var l in n.menu_pages){var d=n.menu_pages[l];if(d&&(!d.hasOwnProperty("visible")||d.visible&&("function"!=typeof d.visible||d.visible.bind(this)()))){var a=document.createElement("li"),u=document.createElement("a");a.className="item",a.id="ffz-menu-page-"+l,u.title=d.name,u.innerHTML=d.icon,u.addEventListener("click",this._ui_change_page.bind(this,e,s,c,l)),a.appendChild(u),s.appendChild(a)}}this._ui_change_page(e,s,c,this._last_page||"channel"),this._popup=i,c.style.maxHeight=Math.max(100,e.$().height()-162)+"px",e.$(".chat-interface").append(i)},n.prototype._ui_change_page=function(e,t,i,o){this._last_page=o,i.innerHTML="";for(var s=t.querySelectorAll("li.active"),r=0;r<s.length;r++)s[r].classList.remove("active");var a=t.querySelector("#ffz-menu-page-"+o);a?a.classList.add("active"):this.log("No matching page: "+o),n.menu_pages[o].render.bind(this)(e,i)},n.menu_pages.settings={render:function(e,t){var i={},o=[];for(var s in n.settings_info){var r=n.settings_info[s],a=r.category||"Miscellaneous",c=i[a];if(void 0!==r.visible&&null!==r.visible){var l=r.visible;if("function"==typeof r.visible&&(l=r.visible.bind(this)()),!l)continue}c||(o.push(a),c=i[a]=[]),c.push([s,r])}o.sort(function(e,t){var e=e.toLowerCase(),t=t.toLowerCase();return t>e?-1:e>t?1:0});for(var d=0;d<o.length;d++){var u=o[d],h=i[u],p=document.createElement("div"),_=document.createElement("div");_.className="heading",p.className="chat-menu-content",_.innerHTML=u,p.appendChild(_),h.sort(function(e,t){var n=e[1],i=t[1],o=n.name.toLowerCase(),s=i.name.toLowerCase();return s>o?-1:o>s?1:0});for(var f=0;f<h.length;f++){var s=h[f][0],r=h[f][1],m=document.createElement("p"),g=this.settings.get(s);if(m.className="clearfix","boolean"==r.type){var v=document.createElement("a"),b=document.createElement("span");v.className="switch",v.classList.toggle("active",g),v.innerHTML="<span></span>",b.className="switch-label",b.innerHTML=r.name,m.appendChild(v),m.appendChild(b),v.addEventListener("click",this._ui_toggle_setting.bind(this,v,s))}else{m.classList.add("option");var y=document.createElement("a");y.innerHTML=r.name,y.href="#",m.appendChild(y),y.addEventListener("click",r.method.bind(this))}if(r.help){var w=document.createElement("span");w.className="help",w.innerHTML=r.help,m.appendChild(w)}p.appendChild(m)}t.appendChild(p)}},name:"Settings",icon:i.GEAR},n.prototype._ui_toggle_setting=function(e,t){var n=!this.settings.get(t);this.settings.set(t,n),e.classList.toggle("active",n)},n.menu_pages.channel={render:function(e,t){{var n=e.get("controller.currentRoom.id"),i=this.rooms[n];this._emotes_for_sets(t,e,i&&i.menu_sets||[])}this._feature_friday_ui(n,t,e)},name:"Channel",icon:i.ZREKNARF},n.prototype._emotes_for_sets=function(e,t,n,i,o){if(null!=i){var s=document.createElement("div");s.className="list-header",s.appendChild(document.createTextNode(i)),o&&s.appendChild(o),e.appendChild(s)}var r=document.createElement("div"),a=0;r.className="emoticon-grid";for(var c=0;c<n.length;c++){var l=this.emote_sets[n[c]];if(l&&l.emotes)for(var d in l.emotes){var u=l.emotes[d];if(l.emotes.hasOwnProperty(d)&&!u.hidden){a++;var h=document.createElement("span");h.className="emoticon tooltip",h.style.backgroundImage='url("'+u.url+'")',h.style.width=u.width+"px",h.style.height=u.height+"px",h.title=u.name,h.addEventListener("click",this._add_emote.bind(this,t,u.name)),r.appendChild(h)}}}a||(r.innerHTML="This channel has no emoticons.",r.className="chat-menu-content ffz-no-emotes center"),e.appendChild(r)},n.prototype._add_emote=function(e,t){var n=e.get("controller.currentRoom"),i=n.get("messageToSend")||"";i&&" "!==i.substr(-1)&&(i+=" "),n.set("messageToSend",i+(t.name||t))}},{"../constants":3}],19:[function(t){var n=e.FrankerFaceZ,i=t("../constants");n.prototype.build_ui_link=function(e){var t=document.createElement("a");return t.className="ffz-ui-toggle",t.innerHTML=i.CHAT_BUTTON,t.addEventListener("click",this.build_ui_popup.bind(this,e)),this.update_ui_link(t),t},n.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 n=t.get("currentRoom.id"),i=this.rooms[n],o=!1,s=this.has_bttv?BetterTTV.settings.get("darkenedMode"):!1,r=this.has_bttv?BetterTTV.settings.get("showBlueButtons"):!1,a=this.feature_friday&&this.feature_friday.live;if(i&&i.sets.length)for(var c=0;c<i.sets.length;c++){var l=this.emote_sets[i.sets[c]];if(l&&l.count>0){o=!0;break}}e.classList.toggle("no-emotes",!o),e.classList.toggle("live",a),e.classList.toggle("dark",s),e.classList.toggle("blue",r)}}},{"../constants":3}],20:[function(){var t=e.FrankerFaceZ;t.prototype.setup_notifications=function(){this.log("Adding event handler for window focus."),e.addEventListener("focus",this.clear_notifications.bind(this))},t.settings_info.highlight_notifications={type:"boolean",value:!1,category:"Chat",visible:function(){return!this.has_bttv},name:"Highlight Notifications",help:"Display notifications when a highlighted word appears in chat in an unfocused tab.",on_update:function(e,t){if(e&&t){if("denied"===Notification.permission)return this.log("Notifications have been denied by the user."),void this.settings.set("highlight_notifications",!1);if("granted"!==Notification.permission){var n=this;Notification.requestPermission(function(e){"denied"===e&&(n.log("Notifications have been denied by the user."),n.settings.set("highlight_notifications",!1))})}}}},t.ws_commands.message=function(e){this.show_message(e)},t._notifications={},t._last_notification=0,t.prototype.clear_notifications=function(){for(var e in t._notifications){var n=t._notifications[e];if(n)try{n.close()}catch(i){}}t._notifications={},t._last_notification=0},t.prototype.show_notification=function(e,n,i,o,s,r){var a=Notification.permission;if("denied "===a)return!1;if("granted"===a){n=n||"FrankerFaceZ",o=o||1e4;var c={lang:"en-US",dir:"ltr",body:e,tag:i||"FrankerFaceZ",icon:"http://cdn.frankerfacez.com/icon32.png"},l=this,d=new Notification(n,c),u=t._last_notification++;return t._notifications[u]=d,d.addEventListener("click",function(){delete t._notifications[u],s&&s.bind(l)()}),d.addEventListener("close",function(){delete t._notifications[u],r&&r.bind(l)()}),void("number"==typeof o&&d.addEventListener("show",function(){setTimeout(function(){delete t._notifications[u],d.close()},o)}))}var l=this;Notification.requestPermission(function(){l.show_notification(e,n,i)})},t.prototype.show_message=function(t){e.noty({text:t,theme:"ffzTheme",layout:"bottomCenter",closeWith:["button"]}).show()}},{}],21:[function(t){var n=e.FrankerFaceZ,i=t("../utils");n.prototype.setup_races=function(){this.log("Initializing race support."),this.srl_races={}},n.settings_info.srl_races={type:"boolean",value:!0,category:"Channel Metadata",name:"SRL Race Information",help:'Display information about <a href="http://www.speedrunslive.com/" target="_new">SpeedRunsLive</a> races under channels.',on_update:function(){this.rebuild_race_ui()}},n.ws_on_close.push(function(){var e=App.__container__.lookup("controller:channel"),t=e.get("id"),n=!1;for(var i in this.srl_races)delete this.srl_races[i],i==t&&(n=!0);n&&this.rebuild_race_ui()}),n.ws_commands.srl_race=function(e){for(var t=App.__container__.lookup("controller:channel"),n=t.get("id"),i=!1,o=0;o<e[0].length;o++){var s=e[0][o];this.srl_races[s]=e[1],s==n&&(i=!0)}if(e[1]){var r=e[1],a=r.twitch_entrants={};for(var c in r.entrants)r.entrants.hasOwnProperty(c)&&(r.entrants[c].channel&&(a[r.entrants[c].channel]=c),r.entrants[c].name=c)}i&&this.rebuild_race_ui()},n.prototype.rebuild_race_ui=function(){var e=App.__container__.lookup("controller:channel"),t=e.get("id"),n=this.srl_races[t],i=this.settings.srl_races,o=document.querySelector(".stats-and-actions .channel-actions"),s=o.querySelector("#ffz-ui-race");if(!n||!i)return s&&s.parentElement.removeChild(s),void(this._popup&&"ffz-race-popup"==this._popup.id&&(delete this._popup,this._popup_kill&&this._popup_kill(),delete this._popup_kill));if(s)return this._update_race(!0);s=document.createElement("span"),s.setAttribute("data-channel",t),s.id="ffz-ui-race";var r=document.createElement("span");r.className="button drop action",r.title="SpeedRunsLive Race",r.innerHTML='<span class="logo"><span>',r.addEventListener("click",this.build_race_popup.bind(this)),s.appendChild(r),o.appendChild(s),this._update_race(!0)},n.prototype._race_kill=function(){this._race_timer&&(clearTimeout(this._race_timer),delete this._race_timer),delete this._race_game,delete this._race_goal},n.prototype.build_race_popup=function(){var e=this._popup;if(!e||(e.parentElement.removeChild(e),delete this._popup,this._popup_kill&&this._popup_kill(),delete this._popup_kill,"ffz-race-popup"!=e.id)){var t=document.querySelector("#ffz-ui-race");if(t){var i=t.querySelector(".button"),o=i.offsetLeft+i.offsetWidth,s=t.getAttribute("data-channel"),r=this.srl_races[s],e=document.createElement("div"),a="";e.id="ffz-race-popup",e.className=(o>=300?"right":"left")+" share dropmenu",this._popup_kill=this._race_kill.bind(this),this._popup=e;var c="http://kadgar.net/live",l=!1;for(var d in r.entrants){var u=r.entrants[d].state;r.entrants.hasOwnProperty(d)&&r.entrants[d].channel&&("racing"==u||"entered"==u)&&(c+="/"+r.entrants[d].channel,l=!0)}var h=document.querySelector(".app-main.theatre")?document.body.clientHeight-300:t.parentElement.offsetTop-175,p=App.__container__.lookup("controller:channel"),_=p?p.get("display_name"):n.get_capitalization(s),f=encodeURIComponent("I'm watching "+_+" race "+r.goal+" in "+r.game+" on SpeedRunsLive!");a='<div class="heading"><div></div><span></span></div>',a+='<div class="table" style="max-height:'+h+'px"><table><thead><tr><th>#</th><th>Entrant</th><th> </th><th>Time</th></tr></thead>',a+="<tbody></tbody></table></div>",a+='<div class="divider"></div>',a+='<iframe class="twitter_share_button" style="width:110px; height:20px" src="https://platform.twitter.com/widgets/tweet_button.html?text='+f+"%20Watch%20at&via=Twitch&url=http://www.twitch.tv/"+s+'"></iframe>',a+='<p class="right"><a target="_new" href="http://www.speedrunslive.com/race/?id='+r.id+'">SRL</a>',l&&(a+=' <a target="_new" href="'+c+'">Multitwitch</a>'),a+="</p>",e.innerHTML=a,t.appendChild(e),this._update_race(!0)}}},n.prototype._update_race=function(e){this._race_timer&&e&&(clearTimeout(this._race_timer),delete this._race_timer);var t=document.querySelector("#ffz-ui-race");if(t){var n=t.getAttribute("data-channel"),o=this.srl_races[n];if(!o)return t.parentElement.removeChild(t),this._popup_kill&&this._popup_kill(),void(this._popup&&(delete this._popup,delete this._popup_kill));var s=o.twitch_entrants[n],r=o.entrants[s],a=t.querySelector("#ffz-race-popup"),c=Date.now()/1e3,l=Math.floor(c-o.time);if(t.querySelector(".logo").innerHTML=i.placement(r),a){var d=a.querySelector("tbody"),u=a.querySelector(".heading span"),h=a.querySelector(".heading div");d.innerHTML="";var p=[],_=!0;for(var f in o.entrants)o.entrants.hasOwnProperty(f)&&("racing"==o.entrants[f].state&&(_=!1),p.push(o.entrants[f]));p.sort(function(e,t){var n=e.place||9999,i=t.place||9999,o=e.time||l,s=t.time||l;return("forfeit"==e.state||"dq"==e.state)&&(n=1e4),("forfeit"==t.state||"dq"==t.state)&&(i=1e4),i>n?-1:n>i?1:e.name<t.name?-1:e.name>t.name?1:s>o?-1:o>s?1:void 0});for(var m=0;m<p.length;m++){var f=p[m],g='<a target="_new" href="http://www.speedrunslive.com/profiles/#!/'+i.sanitize(f.name)+'">'+f.display_name+"</a>",v=f.channel?'<a target="_new" class="twitch" href="http://www.twitch.tv/'+i.sanitize(f.channel)+'"></a>':"",b=f.hitbox?'<a target="_new" class="hitbox" href="http://www.hitbox.tv/'+i.sanitize(f.hitbox)+'"></a>':"",y=l?i.time_to_string(f.time||l):"",w=i.place_string(f.place),k=f.comment?i.sanitize(f.comment):"";d.innerHTML+="<tr"+(k?' title="'+k+'"':"")+' class="'+f.state+'"><td>'+w+"</td><td>"+g+"</td><td>"+v+b+'</td><td class="time">'+("forfeit"==f.state?"Forfeit":y)+"</td></tr>"}if(this._race_game!=o.game||this._race_goal!=o.goal){this._race_game=o.game,this._race_goal=o.goal;var x=i.sanitize(o.game),z=i.sanitize(o.goal);h.innerHTML='<h2 title="'+x+'">'+x+"</h2><b>Goal: </b>"+z}l?_?u.innerHTML="Done":(u.innerHTML=i.time_to_string(l),this._race_timer=setTimeout(this._update_race.bind(this),1e3)):u.innerHTML="Entry Open"}}}},{"../utils":24}],22:[function(t){var n=e.FrankerFaceZ,i=t("../constants");n.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",i.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}],23:[function(t){var n=e.FrankerFaceZ,i=t("../constants"),o=t("../utils");n.ws_commands.viewers=function(e){var t=e[0],n=e[1],s=App.__container__.lookup("controller:channel"),r=s&&s.get&&s.get("id");if(r===t){var a=document.querySelector(".channel-stats .ffz.stat"),c=i.ZREKNARF+" "+o.number_commas(n);if(a)a.innerHTML=c;else{var l=document.querySelector(".channel-stats");if(!l)return;a=document.createElement("span"),a.className="ffz stat",a.title="Viewers with FrankerFaceZ",a.innerHTML=c,l.appendChild(a),jQuery(a).tipsy()}}}},{"../constants":3,"../utils":24}],24:[function(t,n){var i=(e.FrankerFaceZ,t("./constants"),{}),o=document.createElement("span"),s=function(e){return 1==e?"1st":2==e?"2nd":3==e?"3rd":null==e?"---":e+"th"},r=function(e,t){t=0===t?0:t||1,t=Math.round(255*-(t/100));var n=Math.max(0,Math.min(255,e[0]-t)),i=Math.max(0,Math.min(255,e[1]-t)),o=Math.max(0,Math.min(255,e[2]-t));return[n,i,o]},a=function(e){return"rgb("+e[0]+", "+e[1]+", "+e[2]+")"},c=function(e,t){return t=0===t?0:t||1,r(e,-t)},l=function(e){e=[e[0]/255,e[1]/255,e[2]/255];for(var t=0;t<e.length;t++)e[t]=e[t]<=.03928?e[t]/12.92:Math.pow((e[t]+.055)/1.055,2.4);var n=.2126*e[0]+.7152*e[1]+.0722*e[2];return n};n.exports={update_css:function(e,t,n){var i=e.innerHTML,o="/*BEGIN "+t+"*/",s="/*END "+t+"*/",r=i.indexOf(o),a=i.indexOf(s),c=-1!==r&&-1!==a&&a>r;(c||n)&&(c&&(i=i.substr(0,r)+i.substr(a+s.length)),n&&(i+=o+n+s),e.innerHTML=i)},get_luminance:l,brighten:r,darken:c,rgb_to_css:a,number_commas:function(e){var t=e.toString().split(".");return t[0]=t[0].replace(/\B(?=(\d{3})+(?!\d))/g,","),t.join(".")},place_string:s,placement:function(e){return"forfeit"==e.state?"Forfeit":"dq"==e.state?"DQed":e.place?s(e.place):""},sanitize:function(e){var t=i[e];return t||(o.textContent=e,t=i[e]=o.innerHTML,o.innerHTML=""),t},time_to_string:function(e){var t=e%60,n=Math.floor(e/60),i=Math.floor(n/60);return n%=60,(10>i?"0":"")+i+":"+(10>n?"0":"")+n+":"+(10>t?"0":"")+t}}},{"./constants":3}]},{},[13]),e.ffz=new FrankerFaceZ}(window); |