1
0
Fork 0
mirror of https://github.com/FrankerFaceZ/FrankerFaceZ.git synced 2025-06-29 23:58:31 +00:00
FrankerFaceZ/script.min.js

7 lines
209 KiB
JavaScript
Raw Normal View History

!function(t){!function e(t,s,o){function n(a,r){if(!s[a]){if(!t[a]){var d="function"==typeof require&&require;if(!r&&d)return d(a,!0);if(i)return i(a,!0);throw new Error("Cannot find module '"+a+"'")}var u=s[a]={exports:{}};t[a][0].call(u.exports,function(e){var s=t[a][1][e];return n(s?s:e)},u,u.exports,e,t,s,o)}return s[a].exports}for(var i="function"==typeof require&&require,a=0;a<o.length;a++)n(o[a]);return n}({1:[function(e){var s=t.FrankerFaceZ,o=e("./constants"),n=e("./utils");s.settings_info.show_badges={type:"boolean",value:!0,category:"Chat Appearance",name:"Additional Badges",help:"Show additional badges for bots, FrankerFaceZ donors, and other special users."},s.settings_info.transparent_badges={type:"boolean",value:!1,category:"Chat Appearance",no_bttv:!0,name:"Transparent Badges",help:"Make chat badges transparent for a nice, clean look. On light chat, non-subscriber badges are inverted to remain visible.",on_update:function(t){this.has_bttv||document.body.classList.toggle("ffz-transparent-badges",t)}},s.prototype.setup_badges=function(){this.has_bttv||document.body.classList.toggle("ffz-transparent-badges",this.settings.transparent_badges),this.log("Preparing badge system."),this.badges={},this.log("Creating badge style element.");var t=this._badge_style=document.createElement("style");t.id="ffz-badge-css",document.head.appendChild(t),this.log("Adding legacy donor badges."),this._legacy_add_donors()},s.ws_commands.reload_badges=function(){this._legacy_load_bots(),this._legacy_load_donors()},s.ws_commands.set_badge=function(t){var e=t[0],s=t[1],o=t[2],n=this.users[e]=this.users[e]||{},i=n.badges=n.badges||{};void 0===o||null===o?delete i[s]:i[s]=o};var i=function(t){var e=".badges .ffz-badge-"+t.id+" { background-color: "+t.color+'; background-image: url("'+t.image+'"); '+(t.extra_css||"")+"}";return t.transparent_image&&(e+=".ffz-transparent-badges .badges .ffz-badge-"+t.id+' { background-image: url("'+t.transparent_image+'"); }'),e};s.prototype.bttv_badges=function(t){if(this.settings.show_badges){var e=t.sender,s=this.users[e],o=[],n=-1,i=BetterTTV.settings.get("alphaTags");if(s&&s.badges){t.badges||(t.badges=[]);for(var a=0;a<t.badges.length;a++){var r=t.badges[a];if("subscriber"==r.type||"turbo"==r.type){n=a;break}}for(var d in s.badges)if(s.badges.hasOwnProperty(d)){var r=s.badges[d],u=this.badges[r.id]||{},c=r.title||u.title,l="";if(void 0!==u.visible){var h=u.visible;if("function"==typeof h&&(h=h.bind(this)(null,e)),!h)continue}if(u.replaces){for(var f=!1,a=0;a<t.badges.length;a++){var _=t.badges[a];if(_.type==u.replaces){_.type="ffz-badge-replacement "+_.type,_.description+=", "+(r.title||u.title)+'" style="background-image: url(&quot;'+(r.image||u.image)+"&quot;)",f=!0;break}}if(f)continue}r.image&&(l+="background-image: url(&quot;"+r.image+"&quot;); "),r.color&&!i&&(l+="background-color: "+r.color+"; "),r.extra_css&&(l+=r.extra_css),l&&(c+='" style="'+l),o.push([(-1==n?1:-1)*d,{type:"ffz-badge-"+r.id+(i?" alpha":""),name:"",description:c}])}if(o.sort(function(t,e){return t[0]-e[0]}),-1==n)for(;o.length;)t.badges.push(o.shift()[1]);else for(;o.length;)t.badges.insertAt(n,o.shift()[1])}}},s.prototype.render_badge=function(t){if(this.settings.show_badges){var e=t.get("msgObject.from"),s=App.__container__.lookup("controller:chat").get("currentRoom.id"),o=t.$(".badges"),n=this.users[e];if(n&&n.badges){if(!o.length){var i=document.createElement("span"),a=t.$(".from");if(i.className="badges float-left",!a)return;a.before(i),o=$(i)}var r=o.find(".badge").filter(function(){var t=this.title.toLowerCase();return"subscriber"==t||"turbo"==t}).first(),d=[],u=!!r.length;for(var c in n.badges)if(n.badges.hasOwnProperty(c)){var l=n.badges[c],h=this.badges[l.id]||{};if(void 0!==h.visible){var f=h.visible;if("function"==typeof f&&(f=f.bind(this)(s,e)),!f)continue}if(h.replaces){var _=o[0].querySelector(".badge."+h.replaces);if(_){_.style.backgroundImage='url("'+(l.image||h.image)+'")',_.classList.add("ffz-badge-replacement"),_.title+=", "+(l.title||h.title);continue}}var _=document.createElement("div");_.className=
},{}],5:[function(){var e=t.FrankerFaceZ;e.settings_info.developer_mode={type:"boolean",value:!1,storage_key:"ffzDebugMode",visible:function(){return this.settings.developer_mode||Date.now()-parseInt(localStorage.ffzLastDevMode||"0")<6048e5},category:"Debugging",name:"Developer Mode",help:"Load FrankerFaceZ from the local development server instead of the CDN. Please refresh after changing this setting.",on_update:function(){localStorage.ffzLastDevMode=Date.now()}},e.ffz_commands.developer_mode=function(t,e){var s,e=e&&e.length?e[0].toLowerCase():null;return"y"==e||"yes"==e||"true"==e||"on"==e?s=!0:("n"==e||"no"==e||"false"==e||"off"==e)&&(s=!1),void 0===s?"Developer Mode is currently "+(this.settings.developer_mode?"enabled.":"disabled."):(this.settings.set("developer_mode",s),"Developer Mode is now "+(s?"enabled":"disabled")+". Please refresh your browser.")},e.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."},{}],6:[function(e){var s=t.FrankerFaceZ,o=e("../utils"),n=e("../constants");s.prototype.setup_channel=function(){this.log("Creating channel style element.");var t=this._channel_style=document.createElement("style");t.id="ffz-channel-css",document.head.appendChild(t),document.body.classList.toggle("ffz-hide-view-count",!this.settings.channel_views),this.log("Creating channel style element.");var t=this._channel_style=document.createElement("style");t.id="ffz-channel-css",document.head.appendChild(t),this.log("Hooking the Ember Channel Index view.");var e=App.__container__.resolve("view:channel/index"),o=this;if(e){this._modify_cindex(e);try{e.create().destroy()}catch(n){}for(var i in Ember.View.views)if(Ember.View.views.hasOwnProperty(i)){var a=Ember.View.views[i];a instanceof e&&(this.log("Manually updating Channel Index view.",a),this._modify_cindex(a),a.ffzInit())}this.log("Hooking the Ember Channel model."),e=App.__container__.resolve("model:channel"),e&&(e.reopen({ffz_host_target:void 0,setHostMode:function(t){return o.settings.hosted_channels?(this.set("ffz_host_target",t.target),this._super(t)):(this.set("ffz_host_target",void 0),this._super({target:void 0,delay:0}))}}),this.log("Hooking the Ember Channel controller."),e=App.__container__.lookup("controller:channel"),e&&e.reopen({ffzUpdateUptime:function(){o._cindex&&o._cindex.ffzUpdateUptime()}.observes("isLive","content.id"),ffzUpdateTitle:function(){var t=this.get("content.name"),e=this.get("content.display_name");e&&(s.capitalization[t]=[e,Date.now()]),o._cindex&&o._cindex.ffzFixTitle()}.observes("content.status","content.id"),ffzHostTarget:function(){var t=this.get("content.hostModeTarget"),e=t&&t.get("name"),n=t&&t.get("id"),i=t&&t.get("display_name");n!==o.__old_host_target&&(o.__old_host_target&&o.ws_send("unsub_channel",o.__old_host_target),n?(o.ws_send("sub_channel",n),o.__old_host_target=n):delete o.__old_host_target),i&&(s.capitalization[e]=[i,Date.now()]),o.settings.group_tabs&&o._chatv&&o._chatv.ffzRebuildTabs(),o.settings.follow_buttons&&o.rebuild_following_ui(),o.settings.srl_races&&o.rebuild_race_ui()}.observes("content.hostModeTarget")}))}},s.prototype._modify_cindex=function(t){var e=this;t.reopen({didInsertElement:function(){this._super();try{this.ffzInit()}catch(t){e.error("CIndex didInsertElement: "+t)}},willClearRender:function(){try{this.ffzTeardown()}catch(t){e.error("CIndex willClearRender: "+t)}return this._super()},ffzInit:function(){var t=this.get("controller.id"),s=this.get("element");e._cindex=this,e.ws_send("sub_channel",t),s.setAttribute("data-channel",t),s.classList.add("ffz-channel"),this.$(".theatre-button a").attr("title","Theater Mode (Alt+T)"),this.ffzFixTitle(),this.ffzUpdateUptime(),this.ffzUpdateChatters(),this.ffzUpdateHostButton();var o=this.get("element").querySelector(".svg-glyph_views:not(.ffz-svg)");o&&o.parentNode.classList.add("twitch-channel-views"),e.settings.follow_buttons&&e.rebuild_following_ui(),e.settings.srl_races&&e.rebuild_rac
build_srcset=function(t){if(d[t])return d[t];var e=d[t]=r+t+"/1.0 1x, "+r+t+"/2.0 2x, "+r+t+"/3.0 4x";return e},LINK_SPLIT=/^(?:(https?):\/\/)?(?:(.*?)@)?([^\/:]+)(?::(\d+))?(.*?)(?:\?(.*?))?(?:\#(.*?))?$/,YOUTUBE_CHECK=/^(?:https?:\/\/)?(?:m\.|www\.)?youtu(?:be\.com|\.be)\/(?:v\/|watch\/|.*?(?:embed|watch).*?v=)?([a-zA-Z0-9\-_]+)$/,IMGUR_PATH=/^\/(?:gallery\/)?[A-Za-z0-9]+(?:\.(?:png|jpg|jpeg|gif|gifv|bmp))?$/,IMAGE_EXT=/\.(?:png|jpg|jpeg|gif|bmp)$/i,IMAGE_DOMAINS=[],is_image=function(t,e){var s=t.match(LINK_SPLIT);if(s){var o=s[3].toLowerCase(),n=s[4],i=s[5];return n&&"80"!==n&&"443"!==n?!1:"i.imgur.com"===o||"imgur.com"===o||"www.imgur.com"===o||"m.imgur.com"===o?IMGUR_PATH.test(i):e?IMAGE_EXT.test(i):-1!==IMAGE_DOMAINS.indexOf(o)}},image_iframe=function(t,e){return'<iframe class="ffz-image-hover'+(e?" "+e:"")+'" allowtransparency="true" src="'+n.SERVER+"script/image-proxy.html?"+o.quote_attr(t)+'"></iframe>'},data_to_tooltip=function(t){var e=t.set,s=t.set_type,o=t.owner;return void 0===s&&(s="Channel"),e?(("--twitch-turbo--"==e||"turbo"==e)&&(e="Twitch Turbo",s=null),"Emoticon: "+t.code+"\n"+(s?s+": ":"")+e+(o?"\nBy: "+o.display_name:"")):t.code},build_tooltip=function(t){{var e=this._twitch_emotes[t];e?e.set:null}return e?"string"==typeof e?e:e.tooltip?e.tooltip:e.tooltip=data_to_tooltip(e):"???"},load_emote_data=function(t,e,s,o){if(s){e&&(o.code=e),this._twitch_emotes[t]=o;for(var n=build_tooltip.bind(this)(t),i=document.querySelectorAll('img[emote-id="'+t+'"]'),a=0;a<i.length;a++)i[a].title=n}},build_link_tooltip=function(t){var e,s=this._link_data[t];if(!s)return"";if(s.tooltip)return s.tooltip;if("youtube"==s.type)e=this.settings.link_image_hover?image_iframe(s.full||t,"ffz-yt-thumb"):"",e+="<b>YouTube: "+o.sanitize(s.title)+"</b><hr>",e+="Channel: "+o.sanitize(s.channel)+" | "+o.time_to_string(s.duration)+"<br>",e+=o.number_commas(s.views||0)+" Views | &#128077; "+o.number_commas(s.likes||0)+" &#128078; "+o.number_commas(s.dislikes||0);else if("strawpoll"==s.type){e="<b>Strawpoll: "+o.sanitize(s.title)+"</b><hr><table><tbody>";for(var n in s.items){{var i=s.items[n];Math.floor(i/s.total*100)}e+='<tr><td style="text-align:left">'+o.sanitize(n)+'</td><td style="text-align:right">'+o.number_commas(i)+"</td></tr>"}e+="</tbody></table><hr>Total: "+o.number_commas(s.total);var a=o.parse_date(s.fetched);if(a){var r=Math.floor((a.getTime()-Date.now())/1e3);r>60&&(e+="<br><small>Data was cached "+o.time_to_string(r)+" ago.</small>")}}else if("twitch"==s.type){e="<b>Twitch: "+o.sanitize(s.display_name)+"</b><hr>";var d=o.parse_date(s.since);d&&(e+="Member Since: "+o.date_string(d)+"<br>"),e+="<nobr>Views: "+o.number_commas(s.views)+"</nobr> | <nobr>Followers: "+o.number_commas(s.followers)+"</nobr>"}else if("twitch_vod"==s.type)e="<b>Twitch "+("highlight"==s.broadcast_type?"Highlight":"Broadcast")+": "+o.sanitize(s.title)+"</b><hr>",e+="By: "+o.sanitize(s.display_name)+(s.game?" | Playing: "+o.sanitize(s.game):" | Not Playing")+"<br>",e+="Views: "+o.number_commas(s.views)+" | "+o.time_to_string(s.length);else if("twitter"==s.type)e="<b>Tweet By: "+o.sanitize(s.user)+"</b><hr>",e+=o.sanitize(s.tweet);else if("reputation"==s.type){if(e=this.settings.link_image_hover&&is_image(s.full||t,this.settings.image_hover_all_domains)?image_iframe(s.full||t):"",e+='<span style="word-wrap: break-word">'+o.sanitize(s.full.toLowerCase())+"</span>",s.trust<50||s.safety<50||s.tags&&s.tags.length>0){e+="<hr>";var u=!1;(s.trust<50||s.safety<50)&&(s.unsafe=!0,e+="<b>Potentially Unsafe Link</b><br>",e+="Trust: "+s.trust+"% | Child Safety: "+s.safety+"%",u=!0),s.tags&&s.tags.length>0&&(e+=(u?"<br>":"")+"Tags: "+s.tags.join(", ")),e+="<br>Data Source: WOT"}}else s.full&&(e=this.settings.link_image_hover&&is_image(s.full||t,this.settings.image_hover_all_domains)?image_iframe(s.full||t):"",e+='<span style="word-wrap: break-word">'+o.sanitize(s.full.toLowerCase())+"</span>");return e||(e='<span style="word-wrap: break-word">'+o.sanitize(t.toLowerCase())+"</span>"),s.tooltip=e,e},load_link_data=function(t,e,s){if(e){this._link_data[t]=s,s.unsafe
}},o.chat_commands.p=function(t,e){return o.chat_commands.purge.bind(this)(t,e)},o.chat_commands.p.enabled=function(){return this.settings.short_commands},o.chat_commands.t=function(t,e){return e&&e.length?void t.room.send("/timeout "+e.join(" ")):"Timeout Usage: /t username [duration]"},o.chat_commands.t.enabled=function(){return this.settings.short_commands},o.chat_commands.b=function(t,e){if(!e||!e.length)return"Ban Usage: /b username [more usernames separated by spaces]";if(e.length>10)return"Please only ban up to 10 users at once.";for(var s=0;s<e.length;s++){var o=e[s];o&&t.room.send("/ban "+o)}},o.chat_commands.b.enabled=function(){return this.settings.short_commands},o.chat_commands.u=function(t,e){if(!e||!e.length)return"Unban Usage: /u username [more usernames separated by spaces]";if(e.length>10)return"Please only unban up to 10 users at once.";for(var s=0;s<e.length;s++){var o=e[s];o&&t.room.send("/unban "+o)}},o.chat_commands.u.enabled=function(){return this.settings.short_commands}},{"../constants":4,"../utils":33}],11:[function(e){var s=t.FrankerFaceZ,o=e("../constants"),n=e("../utils"),i=-1!==navigator.userAgent.indexOf("Android"),a=function(t){return t.moderator_badge?'.chat-line[data-room="'+t.id+'"] .badges .moderator:not(.ffz-badge-replacement) { background-image:url("'+t.moderator_badge+'") !important; }':""};s.prototype.setup_room=function(){this.rooms={},this.log("Creating room style element.");var t=this._room_style=document.createElement("style");t.id="ffz-room-css",document.head.appendChild(t),this.log("Hooking the Ember Room controller.");var e=App.__container__.lookup("controller:room");if(e){var s=e._actions.banUser,o=e._actions.timeoutUser;e._actions.banUser=function(t){s.bind(this)(t),this.get("model").clearMessages(t.user)},e._actions.timeoutUser=function(t){o.bind(this)(t),this.get("model").clearMessages(t.user)},e._actions.purgeUser=function(t){this.get("model.tmiRoom").sendMessage("/timeout "+t.user+" 1"),this.get("model").clearMessages(t.user)}}this.log("Hooking the Ember Room model.");var n=App.__container__.resolve("model:room");this._modify_room(n);var i=n.instances;for(var a in i)if(i.hasOwnProperty(a)){var r=i[a];this.add_room(r.id,r),this._modify_room(r),r.ffzPatchTMI()}this.log("Hooking the Ember Room view.");var d=App.__container__.resolve("view:room");this._modify_rview(d);try{d.create().destroy()}catch(u){}for(var a in Ember.View.views)if(Ember.View.views.hasOwnProperty(a)){var c=Ember.View.views[a];if(c instanceof d){this.log("Manually updating existing Room view.",c);try{c.ffzInit()}catch(u){this.error("RoomView setup ffzInit: "+u)}}}},s.prototype._modify_rview=function(t){var e=this;t.reopen({didInsertElement:function(){this._super();try{this.ffzInit()}catch(t){e.error("RoomView didInsertElement: "+t)}},willClearRender:function(){try{this.ffzTeardown()}catch(t){e.error("RoomView willClearRender: "+t)}this._super()},ffzInit:function(){e._roomv=this,this.ffz_frozen=!1,this._ffz_mouse_down=this.ffzMouseDown.bind(this),i&&this._$chatMessagesScroller.bind("scroll",this._ffz_mouse_down),this._$chatMessagesScroller.unbind("mousedown"),this._$chatMessagesScroller.bind("mousedown",this._ffz_mouse_down),e.settings.chat_hover_pause&&this.ffzEnableFreeze(),e.settings.room_status&&this.ffzUpdateStatus();var t=this.get("controller");t&&(t.reopen({submitButtonText:function(){if(this.get("model.isWhisperMessage")&&this.get("model.isWhispersEnabled"))return i18n("Whisper");var t=this.get("model.slowWait"),s=this.get("model.messageToSend")||"";return"/"===s.charAt(0)&&"/me "!==s.substr(0,4)||!t||!e.settings.room_status?i18n("Chat"):n.time_to_string(t,!1,!1,!0)}.property("model.isWhisperMessage","model.isWhispersEnabled","model.slowWait")}),Ember.propertyDidChange(t,"submitButtonText"))},ffzTeardown:function(){e._roomv===this&&(e._roomv=void 0),this.ffzDisableFreeze()},ffzUpdateStatus:function(){var t=this.get("controller.model"),s=this.get("element"),o=s&&s.querySelector(".chat-buttons-container");if(o){var i=o.querySelector("#ffz-stat-r9k"),a=o.querySelector("#ffz-stat-sub"),r=o.querySele
u=null;for(var r=0;r<a.length;r++)a[r]="string"==typeof a[r]?BetterTTV.chat.templates.bttvMessageTokenize(t,a[r]):a[r][0];e=a.join(" ")}return'<span class="message" '+(n?'style="color: '+n+'" ':"")+'data-raw="'+i+'" data-emotes="'+(o?encodeURIComponent(JSON.stringify(o)):"false")+'">'+e+"</span>"}catch(d){return s.log("Error: ",d),c(t,e,o,n)}};var l=BetterTTV.chat.templates.emoticonize;BetterTTV.chat.templates.emoticonize=function(t,e){var a=l(t,e),r=i||BetterTTV.getChannel(),d=r&&r.toLowerCase(),c=u&&u.toLowerCase(),h=s.getEmotes(c,d),e=[],f=s.get_user(),m=f&&f.login===c;if(_.each(h,function(t){var o=s.emote_sets[t];o&&_.each(o.emoticons,function(t){_.any(a,function(e){return _.isString(e)&&e.match(t.regex)})&&e.push(t)})}),e.length&&_.each(e,function(t){var e=s._emote_tooltip(t),o=['<img class="emoticon" srcset="'+(t.srcSet||"")+'" src="'+t.urls[1]+'" alt="'+e+'" title="'+e+'" />'],n=a;a=[];for(var i=0;i<n.length;i++){var r=n[i];if("string"==typeof r)for(var u=r.split(t.regex);u.length;){var c=u.shift();u.length?(c+=u.shift(),c&&a.push(c),u.shift(),a.push(o),m&&d&&s.add_usage(d,t.id)):a.push(c)}else a.push(r)}}),s.settings.parse_emoji&&s.emoji_data){var p=a;a=[];for(var g=0;g<p.length;g++){var v=p[g];if("string"==typeof v)for(var b=v.split(o.EMOJI_REGEX);b.length;){var y=b.shift();if(y&&a.push(y),b.length){var w=b.shift(),z=b.shift();if(""===z)bits.push(w);else{var k=n.emoji_to_codepoint(w,z),C=s.emoji_data[k];a.push(C?['<img class="emoticon" height="18px" srcset="'+(C.srcSet||"")+'" src="'+C.src+'" alt="'+alt+'" title="Emoji: '+C.raw+"\nName: :"+C.short_name+':">']:w+(z||""))}}}else a.push(v)}}return a},this.update_ui_link()}},{"../constants":4,"../utils":33}],15:[function(){var e=t.FrankerFaceZ;e.prototype.find_emote_menu=function(e,s){return this.has_emote_menu=!1,t.emoteMenu&&emoteMenu.registerEmoteGetter?this.setup_emote_menu(s||0):void(s>=6e4?this.log("Emote Menu for Twitch was not detected after 60 seconds."):setTimeout(this.find_emote_menu.bind(this,e,(s||0)+e),e))},e.prototype.setup_emote_menu=function(t){this.log("Emote Menu for Twitch was detected after "+t+"ms. Registering emote enumerator."),emoteMenu.registerEmoteGetter("FrankerFaceZ",this._emote_menu_enumerator.bind(this))},e.prototype._emote_menu_enumerator=function(){for(var t=this.get_user(),s=t?t.login:null,o=App.__container__.lookup("controller:chat"),n=o?o.get("currentRoom.id"):null,i=this.getEmotes(s,n),a=[],r=0;r<i.length;r++){var d=this.emote_sets[i[r]];if(d&&d.emoticons)for(var u in d.emoticons)if(d.emoticons.hasOwnProperty(u)){var c=d.emoticons[u];if(!c.hidden){var l=d.title,h=d.icon||null;l=l?"FrankerFaceZ: "+l:"global"==d.id?"FrankerFaceZ Global Emotes":"globalevent"==d.id?"FrankerFaceZ Event Emotes":this.feature_friday&&d.id==this.feature_friday.set?"FrankerFaceZ "+this.feature_friday.title+": "+this.feature_friday.display_name:"FrankerFaceZ Set: "+e.get_capitalization(d.id),a.push({text:c.name,url:c.urls[1],hidden:!1,channel:l,badge:h})}}}return a}},{}],16:[function(e){var s=t.FrankerFaceZ=function(){s.instance=this,this._log_data=[],this.initialize()};s.get=function(){return s.instance};var o=s.version_info={major:3,minor:4,revision:25,toString:function(){return[o.major,o.minor,o.revision].join(".")+(o.extra||"")}};s.prototype.log=function(t,e,s,o){t="FFZ: "+t+(s?" -- "+JSON.stringify(e):""),this._log_data.push(t+(!s&&o?" -- "+JSON.stringify(e):"")),void 0!==e&&console.groupCollapsed&&console.dir?(console.groupCollapsed(t),-1!==navigator.userAgent.indexOf("Firefox/")?console.log(e):console.dir(e),console.groupEnd(t)):console.log(t)},s.prototype.error=function(t,e,s){t="FFZ Error: "+t+(s?" -- "+JSON.stringify(e):""),this._log_data.push(t),void 0!==e&&console.groupCollapsed&&console.dir?(console.groupCollapsed(t),-1!==navigator.userAgent.indexOf("Firefox/")?console.log(e):console.dir(e),console.groupEnd(t)):console.assert(!1,t)},s.prototype.paste_logs=function(){this._pastebin(this._log_data.join("\n"),function(t){return t?void console.log("FFZ: Your FrankerFaceZ log has been pasted to: "+t):console.log("FFZ Error: Unable to upload log
h.className="button primary",h.innerHTML="Advertise in Chat",h.addEventListener("click",this._add_emote.bind(this,t,f)),l.appendChild(h);var _=document.createElement("a");_.className="button ffz-donate",_.href="https://www.frankerfacez.com/donate",_.target="_new",_.innerHTML="Donate",l.appendChild(_),l.className="chat-menu-content center",e.appendChild(l);var m=document.createElement("div");d='<table class="ffz-about-table">',d+='<tr><th colspan="4">Developers</th></tr>',d+='<tr><td>Dan Salvato</td><td><a class="twitch" href="http://www.twitch.tv/dansalvato" title="Twitch" target="_new">&nbsp;</a></td><td><a class="twitter" href="https://twitter.com/dansalvato1" title="Twitter" target="_new">&nbsp;</a></td><td><a class="youtube" href="https://www.youtube.com/user/dansalvato1" title="YouTube" target="_new">&nbsp;</a></td></tr>',d+='<tr><td>Stendec</td><td><a class="twitch" href="http://www.twitch.tv/sirstendec" title="Twitch" target="_new">&nbsp;</a></td><td><a class="twitter" href="https://twitter.com/SirStendec" title="Twitter" target="_new">&nbsp;</a></td><td><a class="youtube" href="https://www.youtube.com/channel/UCnxuvmK1DCPCXSJ-mXIh4KQ" title="YouTube" target="_new">&nbsp;</a></td></tr>',d+='<tr class="debug"><td>Version '+s.version_info+'</td><td colspan="3"><a href="#" id="ffz-debug-logs">Logs</a></td></tr>',m.className="chat-menu-content center",m.innerHTML=d;var p=!1;m.querySelector("#ffz-debug-logs").addEventListener("click",function(){p||(p=!0,i._pastebin(i._log_data.join("\n"),function(t){p=!1,t?prompt("Your FrankerFaceZ logs have been uploaded to the URL:",t):alert("There was an error uploading the FrankerFaceZ logs.")}))}),e.appendChild(m)}}},{"../constants":4}],22:[function(e){var s=t.FrankerFaceZ,o=e("../constants");s.settings_info.twitch_chat_dark={type:"boolean",value:!1,visible:!1},s.settings_info.dark_twitch={type:"boolean",value:!1,no_bttv:!0,category:"Appearance",name:"Dark Twitch",help:"Apply a dark background to channels and other related pages for easier viewing.",on_update:function(e){var s=document.querySelector("input.ffz-setting-dark-twitch");if(s&&(s.checked=e),!this.has_bttv){document.body.classList.toggle("ffz-dark",e);var o=t.App?App.__container__.lookup("controller:settings").get("model"):void 0;e?(this._load_dark_css(),o&&this.settings.set("twitch_chat_dark",o.get("darkMode")),o&&o.set("darkMode",!0)):o&&o.set("darkMode",this.settings.twitch_chat_dark)}}},s.settings_info.dark_no_blue={type:"boolean",value:!1,category:"Appearance",name:"Gray Chat (no blue)",help:"Make the dark theme for chat and a few other places on Twitch a bit darker and not at all blue.",on_update:function(t){document.body.classList.toggle("ffz-no-blue",t)}},s.settings_info.hide_recent_past_broadcast={type:"boolean",value:!1,no_mobile:!0,category:"Channel Metadata",name:'Hide "Watch Last Broadcast"',help:'Hide the "Watch Last Broadcast" banner at the top of offline Twitch channels.',on_update:function(t){document.body.classList.toggle("ffz-hide-recent-past-broadcast",t)}},s.prototype.setup_dark=function(){document.body.classList.toggle("ffz-hide-recent-past-broadcast",this.settings.hide_recent_past_broadcast),document.body.classList.toggle("ffz-no-blue",this.settings.dark_no_blue),this.has_bttv||(document.body.classList.toggle("ffz-dark",this.settings.dark_twitch),this.settings.dark_twitch&&(t.App&&App.__container__.lookup("controller:settings").set("model.darkMode",!0),this._load_dark_css()))},s.prototype._load_dark_css=function(){if(!this._dark_style){this.log("Injecting FrankerFaceZ Dark Twitch CSS.");var t=this._dark_style=document.createElement("link");t.id="ffz-dark-css",t.setAttribute("rel","stylesheet"),t.setAttribute("href",o.SERVER+"script/dark.css?_="+(o.DEBUG?Date.now():s.version_info)),document.head.appendChild(t)}}},{"../constants":4}],23:[function(e){var s=t.FrankerFaceZ,o=e("../utils");s.settings_info.following_count={type:"boolean",value:!0,no_bttv:!0,no_mobile:!0,category:"Appearance",name:"Sidebar Following Count",help:"Display the number of live channels you're following on the sidebar.",on_upda
},e.settings_info.highlight_notifications={type:"boolean",value:!1,category:"Chat Filtering",no_bttv:!0,no_mobile:!0,name:"Highlight Notifications",help:"Display notifications when a highlighted word appears in chat in an unfocused tab. This is automatically disabled on the dashboard.",on_update:function(t,e){if(t&&e){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 s=this;Notification.requestPermission(function(t){"denied"===t&&(s.log("Notifications have been denied by the user."),s.settings.set("highlight_notifications",!1))})}}}},e.settings_info.notification_timeout={type:"button",value:60,category:"Chat Filtering",no_bttv:!0,no_mobile:!0,name:"Notification Timeout",help:"Specify how long notifications should be displayed before automatically closing.",method:function(){var t=this.settings.notification_timeout,e=prompt("Notification Timeout\n\nPlease enter the time you'd like notifications to be displayed before automatically closing, in seconds.\n\nDefault is: 60",t);if(null!==e&&void 0!==e){var s=parseInt(e);(0/0===s||1>s)&&(s=60),this.settings.set("notification_timeout",s)}}},e.ws_commands.message=function(t){this.show_message(t)},e._notifications={},e._last_notification=0,e.prototype.clear_notifications=function(){for(var t in e._notifications){var s=e._notifications[t];if(s)try{s.close()}catch(o){}}e._notifications={},e._last_notification=0},e.prototype.show_notification=function(t,s,o,n,i,a){var r=Notification.permission;if("denied "===r)return!1;if("granted"===r){s=s||"FrankerFaceZ",n=n||1e3*this.settings.notification_timeout;var d={lang:"en-US",dir:"ltr",body:t,tag:o||"FrankerFaceZ",icon:"http://cdn.frankerfacez.com/icon32.png"},u=this,c=new Notification(s,d),l=e._last_notification++;return e._notifications[l]=c,c.addEventListener("click",function(){delete e._notifications[l],i&&i.bind(u)()}),c.addEventListener("close",function(){delete e._notifications[l],a&&a.bind(u)()}),void("number"==typeof n&&c.addEventListener("show",function(){setTimeout(function(){delete e._notifications[l],c.close()},n)}))}var u=this;Notification.requestPermission(function(){u.show_notification(t,s,o)})},e.prototype.show_message=function(e){t.noty({text:e,theme:"ffzTheme",layout:"bottomCenter",closeWith:["button"]}).show()}},{}],29:[function(e){var s=t.FrankerFaceZ,o=e("../utils");s.prototype.setup_races=function(){this.log("Initializing race support."),this.srl_races={}},s.settings_info.srl_races={type:"boolean",value:!0,no_mobile:!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()}},s.ws_on_close.push(function(){var e=t.App&&App.__container__.lookup("controller:channel"),s=e&&e.get("id"),o=e&&e.get("hostModeTarget.id"),n=!1;if(e){for(var i in this.srl_races)delete this.srl_races[i],(i===s||i===o)&&(n=!0);n&&this.rebuild_race_ui()}}),s.ws_commands.srl_race=function(t){var e=App.__container__.lookup("controller:channel"),s=e&&e.get("id"),o=e&&e.get("hostModeTarget.id"),n=!1;this.srl_races=this.srl_races||{};for(var i=0;i<t[0].length;i++){var a=t[0][i];this.srl_races[a]=t[1],(a===s||a===o)&&(n=!0)}if(t[1]){var r=t[1],d=r.twitch_entrants={};for(var u in r.entrants)r.entrants.hasOwnProperty(u)&&(r.entrants[u].channel&&(d[r.entrants[u].channel]=u),r.entrants[u].name=u)}n&&this.rebuild_race_ui()},s.prototype.rebuild_race_ui=function(){var t=App.__container__.lookup("controller:channel"),e=t&&t.get("id"),s=t&&t.get("hostModeTarget.id");if(this._cindex){if(e){var o=this.srl_races&&this.srl_races[e],n=this._cindex.get("element"),i=n&&n.querySelector(".stats-and-actions .channel-actions"),a=i&&i.querySelector("#ffz-ui-race");if(i&&this.settings.srl_races&&o){if(!a){a=document.createElement("span"),a.id="ffz-ui-race",a.setAttribute("data-channel",e);var r=document.createElement("span");r.className="button drop action",r.ti