jaidbot
Version:
Personal chat bot for my Twitch stream.
6 lines • 570 kB
JavaScript
#!/usr/bin/env node
/*!
*** Jaidbot 6.4.0
*** Copyright © 2020, Jaid <jaid.jsx@gmail.com> (https://github.com/Jaid)
*** @license MIT
!*/!function(t){var e={};function n(r){if(e[r])return e[r].exports;var i=e[r]={i:r,l:!1,exports:{}};return t[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var i in t)n.d(r,i,function(e){return t[e]}.bind(null,i));return r},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=182)}([function(t,e,n){"use strict";n.d(e,"a",(function(){return u})),n.d(e,"c",(function(){return c}));var r=n(64),i=n.n(r),s=n(151),o=n.n(s);const a=new i.a({name:"Jaidbot",version:"6.4.0",insecurePort:17441,database:!0,useGot:!0,configSetup:{defaults:o(),secretKeys:["adminPassword","twitchBotAccessToken","twitchBotRefreshToken","databasePassword","githubAppPemFilePath","githubAppWebhookSecret","githubToken","serverPassword","twitchStreamerAccessToken","twitchStreamerRefreshToken","travisToken","twitchClientId","twitchClientSecret","twitterAccessSecret","twitterAccessToken","twitterConsumerKey","twitterConsumerSecret","youtubeClientAccessToken","youtubeClientId","youtubeClientRefreshToken","youtubeClientSecret"]}}),u=a.config,c=a.logger;e.b=a},function(t,e){t.exports=require("sequelize")},function(t,e,n){"use strict";n.r(e);var r=n(154),i=n.n(r),s=n(43),o=n.n(s),a=n(19),u=n.n(a),c=n(4),l=n(155),h=n.n(l),p=n(156),d=n.n(p),f=n(71),m=n.n(f),y=n(65),g=n.n(y),D=n(5),v=n(0),E=n(13),x=n(20),w=n(7),b=n(67),A=n.n(b),C=n(68),F=n.n(C),S=n(38),k=n.n(S),T=n(161),N=n.n(T),O=n(162),B=n.n(O);const I=/^(?<prefix>!)(?<commandName>[\da-z]+)(?<afterCommandName>\s*(?<commandArguments>.*))?/i,_=n(232);class P extends u.a{constructor(){super(),this.commands=_.keys().reduce((t,e)=>(t[e.match(/\.\/(?<key>[\da-z]+)\//i).groups.key]=_(e).default,t),{}),this.commandUsages=[];for(const[t,e]of Object.entries(this.commands)){const r=n(297)(`./${t}/help.yml`);if(Object(c.isEmpty)(r))continue;const i=k()(r);for(const n of i){const r={command:t,description:n.description};if(n.for&&(r.for=n.for),n.param){const e=k()(n.param);r.params=e,r.usage=`!${t} ${e.join(" ")}`}else r.usage=`!${t}`;n.example&&(r.example=k()(n.example)),Object.assign(r,A()(e,"permission","needsDesktopClient","requiredArguments")),this.commandUsages.push(r)}}}async handleMessage(t){var e;const n=I.exec(t.text);if(null===n)return;const r=n.groups.commandName.toLowerCase();let i,s;var o,a;n.groups.commandArguments&&(a=n.groups.commandArguments,o=B()(a),i=N()(o),s=i._);const u=await L.getNickname(t.sender.id),c=this.commands[r];if(c){if(!t.sender.isBroadcaster){if("subOrVip"===c.permission&&!t.sender.isVip&&!t.sender.isSub&&!t.sender.isMod)return void L.say(`${u}, für diesen Befehl musst du Moderator, Subscriber oder VIP sein!`);if("mod"===c.permission&&!t.sender.hasElevatedPermission)return void L.say(`${u}, für diesen Befehl musst du Moderator sein!`)}if(!c.needsDesktopClient||w.default.hasClient()){if(c.requiredArguments){if(!i)return void L.say(`${u}, dieser Befehl kann nicht ohne Arguments verwendet werden!`);const t=s.length;if(c.requiredArguments>t)return void L.say(`${u}, dieser Befehl benötigt ${c.requiredArguments} Arguments!`)}c.handle({...t,commandArguments:i,senderName:u,positionalArguments:s||[],combinedArguments:null==n?void 0:null===(e=n.groups)||void 0===e?void 0:e.commandArguments}).then(t=>{var e;e=t,F()(e)&&L.say(t)}).catch(e=>{v.c.error('Error at execution of "%s": %s',t.text,e),L.say(`Oh, ${u}, da hat irgendetwas nicht geklappt. Muss sich ${L.streamerUser.getDisplayName()} drum kümmern.`)})}else L.say(`Es besteht gerade keine Verbindung zum Computer von ${L.streamerUser.getDisplayName()}. ResidentSleeper`)}else L.say(`Verstehe ich jetzt nicht, ${u}! Alle Befehle sind in den Panels unter dem Stream beschrieben.`)}}function j(t){return t.replace(/^\s*\[.*]\s*/,"")}n.d(e,"removeTitlePrefix",(function(){return j}));class M extends u.a{constructor(...t){super(...t),this.isInAdLoop=!1,this.currentTitle=null,this.botClient=null,this.streamerClient=null,this.isReady=!1,this.currentTitle=null}handleConfig(t){this.nicknames=t.nicknames||{},this.streamerLogin=t.twitchStreamerLogin,this.botLogin=t.twitchBotLogin,this.predefinedStreamerAccessToken=t.twitchStreamerAccessToken,this.predefinedStreamerRefreshToken=t.twitchStreamerRefreshToken,this.predefinedBotAccessToken=t.twitchBotAccessToken,this.predefinedBotRefreshToken=t.twitchBotRefreshToken,this.clientId=t.twitchClientId,this.clientSecret=t.twitchClientSecret,this.tickMs=1e3*t.twitchTickSeconds,this.nicknameCache=new h.a({stdTTL:86400}),this.autoAds=t.autoAds}async init(){await o()(1e4),this.apiClient=await g.a.withClientCredentials(this.clientId,this.clientSecret);const t=["streamer","bot"];for(const e of t){const t=i()(e),n=this[`${e}Login`];v.c.info("Preparing %s Twitch account (%s)",e,n);const r=await x.default.findOrRegisterByLogin(n);if(!r.accessToken&&this[`predefined${t}AccessToken`]&&(r.accessToken=this[`predefined${t}AccessToken`],v.c.info("Set Twitch %s accessToken from config",e)),!r.refreshToken&&this[`predefined${t}RefreshToken`]&&(r.refreshToken=this[`predefined${t}RefreshToken`],v.c.info("Set Twitch %s refreshToken from config",e)),await r.save(),!(null==r?void 0:r.accessToken))return v.c.warn("No user auth found for requested streamer user %s",this.streamerLogin),!1;this[`${e}User`]=r,this[e]=await r.toTwitchClientWithChat(),this[`${e}Client`]=this[e].apiClient}const e=await this.streamerClient.kraken.channels.getMyChannel();this.streamerTwitchId=e.id,this.currentTitle=e.status;const n=j(this.currentTitle);this.currentTitle!==n&&(v.c.debug("The initial stream title had a prefix, removing it because it is most likely outdated"),this.setTitle(n)),v.c.info("Initial stream title: %s",this.currentTitle),this.streamerChatClient=this.streamer.chatClient,this.chatClient=this.bot.chatClient,await this.chatClient.join(this.streamerLogin),v.c.info("Connected bot"),this.chatBot=new P,this.chatClient.onPrivmsg(async(t,e,n,r)=>{const i={text:n.trim(),bits:r.totalBits||0,sender:{id:r.userInfo.userId,name:r.userInfo.userName,isBroadcaster:"1"===r.userInfo.badges.get("broadcaster"),isVip:"1"===r.userInfo.badges.get("vip"),isMod:r.userInfo.isMod,isSub:r.userInfo.isSubscriber,color:r.userInfo.color}};i.sender.displayName=r.userInfo.displayName||i.sender.name,i.sender.hasElevatedPermission=Boolean(r.userInfo.userType)||i.sender.isBroadcaster,r.userInfo._userData.has("tmi-sent-ts")&&(i.sentDate=new Date(Number(r.userInfo._userData.get("tmi-sent-ts")))),v.c.debug(`${i.sender.displayName}: ${i.text}`),this.emit("chat",i),await this.chatBot.handleMessage(i)}),this.autoAds&&(v.c.info("Starting ad loop"),this.startAdLoop()),this.isReady=!0,this.say("TBAngel Da bin ich!")}async userNameToDisplayName(t){const e=await this.apiClient.helix.users.getUserByName(t);return(null==e?void 0:e.displayName)||(null==e?void 0:e.name)||t}async getNickname(t){try{var e,n;const r=String(t).trim().toLowerCase(),i=this.nicknameCache.get(r);if(i)return i;const s=this.nicknames[r];if(s)return this.nicknameCache.set(r,s),s;let o,a;if(/^\d+$/.test(t)&&(a=await this.apiClient.helix.users.getUserById(r),a)){o=a.name;const t=this.nicknames[o];if(t)return this.nicknameCache.set(o,t),t}a||(o=r,a=await this.apiClient.helix.users.getUserByName(o));const u=(null===(e=a)||void 0===e?void 0:e.displayName)||(null===(n=a)||void 0===n?void 0:n.name)||r;return this.nicknameCache.set(o,u),u}catch(e){return v.c.error(`Could not fetch nickname for "${t}"\n%s`,e),"(?)"}}async playAd(t=30){if(!this.isLive())return;const e=async()=>{await this.streamerClient.kraken.channels.startChannelCommercial(this.streamerUser.twitchId,t)};try{await d()(e,{maxTimeout:5e3,minTimeout:100}),v.c.debug("Started %s ad",m()(1e3*t))}catch(e){v.c.error("Could not play %ss ad\n%s",t,e)}}async startAdLoop(){if(this.isInAdLoop)v.c.info("Skipping twitch.startAdLoop(), because an ad loop is already active");else for(this.isInAdLoop=!0;this.isInAdLoop;)await this.playAd(180),await o()(48e4)}async stopAdLoop(){this.isInAdLoop?this.autoAds||(this.isInAdLoop=!1):v.c.info("Skipping twitch.stopAdLoop(), because an ad loop was not active")}async getFollowMoment(t){const e=await this.apiClient.helix.users.getUserByName(t),n=await e.getFollowTo(this.streamerUser.twitchId);return null!==n&&Object(D.a)(n.followDate)}async getMyStream(){return this.streamerClient.kraken.streams.getStreamByChannel(this.streamerUser.twitchId)}async setCategory(t){await this.streamerClient.kraken.channels.updateChannel(this.streamerUser.twitchId,{game:t})}async getUserInfoByTwitchId(t){return await this.apiClient.helix.users.getUserById(t)}async getUserInfoByTwitchLogin(t){return await this.apiClient.helix.users.getUserByName(t)}async setTitle(t){const e=String(t).trim();e!==this.currentTitle?(this.currentTitle=e,v.c.info("New stream title: %s",e),await this.streamerClient.kraken.channels.updateChannel(this.streamerUser.twitchId,{status:e})):v.c.debug("Not overwriting stream title, it has not changed")}say(t){this.chatClient?this.chatClient.say(this.streamerUser.loginName,t):v.c.warn('Tried to say "%s", but chatClient was %s',t,this.chatClient)}isLive(){return!!E.default.currentStatus&&void 0!==E.default.currentStatus.streamTitle}isPlayingGame(t){return!!E.default.currentStatus&&!Object(c.isEmpty)(E.default.currentStatus.game)&&E.default.currentStatus.game.toLowerCase()===t.toLowerCase()}isLastGame(t){return!!E.default.lastTwitchStatus&&!Object(c.isEmpty)(E.default.lastTwitchStatus.game)&&E.default.lastTwitchStatus.game.toLowerCase()===t.toLowerCase()}notifyIfGame(t,e){this.isLastGame(t)&&this.say(`HumbleLife ${e}`)}notifyIfGameLive(t,e){this.isPlayingGame(t)&&this.say(`HumbleLife ${e}`)}ready(){this.tickMs?this.tickInterval=setInterval(this.tick.bind(this),this.tickMs):v.c.warn("Not starting Twitch ticking, because config.twitchTickSeconds is not given")}getTitleWithoutPrefix(){return j(this.currentTitle)}async tick(){const t=Date.now();try{const e=Date.now(),n=await this.botClient.unsupported.getChatters(this.streamerLogin);v.c.debug("Fetched %s chatters in %s",n.allChatters.length,m()(Date.now()-e));const r=[];for(const[t,e]of n.allChattersWithStatus.entries()){const n=await x.default.findOrRegisterByLogin(t,{defaults:{chatterRole:e}});n.chatterRole!==e&&(v.c.info("Changed chatter role of %s from %s to %s",n.getDisplayName(),n.chatterRole,e),n.chatterRole=e),await n.save(),r.push({role:e,login:t,displayName:n.getDisplayName(),avatarUrl:n.avatarUrl,followDate:n.followDate,nameColor:n.nameColor})}w.default.emitToClient("updateChatters",r),v.c.debug("Twitch tick done in %s",m()(Date.now()-t))}catch(t){v.c.error("Twitch tick failed: %s",t)}}}var L=e.default=new M},function(t,e,n){"use strict";n.r(e),n.d(e,"schema",(function(){return v})),n.d(e,"indexes",(function(){return E}));var r=n(67),i=n.n(r),s=n(68),o=n.n(s),a=n(25),u=n.n(a),c=n(163),l=n.n(c),h=n(1),p=n.n(h),d=n(5),f=n(0),m=n(20),y=n(7),g=n(2);class D extends p.a.Model{static associate(t){D.belongsTo(t.TwitchUser,{as:"Requester",foreignKey:"RequesterId"})}static start(){y.default.on("gotClient",t=>{f.c.debug("Received gotClient in Video model handler"),t.on("videoDownloaded",D.handleVideoDownloaded),t.on("vlcState",D.handleVlcState),t.on("setInfoFile",D.handleSetInfoFile),t.on("getDownloadJobs",t=>D.handleGetDownloadJobs(t))})}static async findNext(t){return D.findOne({where:{watchedAt:{[h.Op.eq]:null},videoFile:{[h.Op.ne]:null},frozenUntil:{[h.Op.lt]:Date.now()}},order:[["timestamp","desc"],["priority","desc"],["id","desc"]],...t})}static setCurrentVideo(t){D.currentVideoHeartbeatTimestamp=Date.now(),D.currentVideo=t}static async handleVideoDownloaded({videoId:t,bytes:e,videoFile:n,infoFile:r}){try{await D.update({bytes:e,videoFile:n,infoFile:r,downloadedAt:new Date},{where:{id:t}})}catch(t){f.c.error("Error at videoDownloaded handler: %s",t)}}static async handleVlcState(t){try{var e;D.currentVideoHeartbeatTimestamp=Date.now();const n=(null===(e=D.currentVideo)||void 0===e?void 0:e.videoFile)!==t.file;if(!n&&D.currentVideo.hasBeenWatched())return;await f.b.database.transaction(async e=>{if(n){const n=await D.findOne({transaction:e,where:{videoFile:t.file}});if(!n)return void(D.currentVideo&&(f.c.info("Video.currentVideo will be set to null, because current video is not found in database"),D.currentVideo=null));if(f.c.info(`Current video set to #${n.id}`),D.currentVideo=n,n.hasBeenWatched())return void f.c.debug("Not applying any changes on video, because it has already been watched")}const r=D.currentVideo,i=["timestamp"];r.vlcDuration||(r.vlcDuration=t.durationMs,i.push("vlcDuration")),r.timestamp=t.timestampMs;const s=t.durationMs-t.timestampMs;1e4>s&&(r.watchedAt=Object(d.a)().add(s,"ms").toDate(),i.push("watchedAt"),f.c.debug("Video #%s will be marked as watched",r.id)),await r.save({transaction:e,fields:i})})}catch(t){f.c.error("Error at vlcState handler: %s",t)}}static async handleSetInfoFile({videoId:t,infoFile:e}){try{await D.update({infoFile:e},{where:{id:t}}),f.c.debug("Got info file path for video #%s",t)}catch(t){f.c.error("Error at setInfoFile handler: %s",t)}}static async handleGetDownloadJobs(t){try{return void t(await D.findAll({where:{videoFile:{[h.Op.eq]:null}},raw:!0,attributes:["id","downloadFormat","info"]}))}catch(e){return f.c.error("Error at getDownloadJobs handler: %s",e),void t(!1)}}static async queueByUrl(t,e){let n,r;try{var i;n=await l()(f.a.youtubeDlPath,["--no-color","--ignore-config","--abort-on-error","--netrc","--format",f.a.youtubeDlFormat,"--cookies",f.a.youtubeDlCookieFile,"--dump-single-json",t]),i=n.stdout,r=JSON.parse(i)}catch(e){var s,o;f.c.error("Could not use youtube-dl to fetch media information of url %s: %s\ncommand: %s\nstd: %s",t,e,(null===(s=n)||void 0===s?void 0:s.command)||(null==e?void 0:e.command),(null===(o=n)||void 0===o?void 0:o.all)||(null==e?void 0:e.all))}if(!r&&y.default.hasClient()&&(f.c.warn("Could not fetch info for %s, trying on Desktop instead",t),r=await u.a.withDefaultTimeout(y.default.client,"fetchVideoInfo",t)),r)return D.queueByInfo(r,{requestUrl:t,...e});throw new Error(`Could not fetch info for video URL ${t}`)}static async queueByInfo(t,e){var n;const r=t.release_date||t.upload_date;let i;n=r,o()(n)&&(i=Object(d.a)(r,"YYYYMMDD").toDate());const s={title:t.title||t.webpage_url,duration:1e3*t.duration,views:t.view_count,likes:t.like_count,dislikes:t.dislike_count,publishedAt:i,format:t.format,extractor:t.extractor||t.extractor_key,width:t.width,height:t.height,webUrl:t.webpage_url||t.channel_url||t.uploader_url,audioCodec:t.acodec,videoCodec:t.vcodec,formatId:t.format_id,fileExtension:t.ext,description:t.description,thumbnailUrl:t.thumbnail,channelUrl:t.channel_url||t.uploader_url,audioBitrate:t.abr,videoBitrate:t.vbr,mediaId:t.id,ageLimit:t.age_limit,publisher:t.uploader||t.uploader_id,publisherId:t.uploader_id,info:t,downloadFormat:f.a.youtubeDlFormat};if(void 0!==e.priority&&(s.priority=e.priority),e.requesterTwitchId){const t=await m.default.getByTwitchId(e.requesterTwitchId);s.RequesterId=t.id}e.requestUrl&&(s.requestUrl=e.requestUrl);const[a,u]=await D.findOrCreate({where:{extractor:s.extractor,mediaId:s.mediaId},defaults:s});return u?(f.c.info('Requested video #%s "%s" with priority %s',a.id,a.title,a.priority),y.default.hasClient()&&y.default.client.emit("queueInfo",{videoInfo:t,videoId:a.id,downloadFormat:a.downloadFormat})):(await a.update({...s,priority:a.priority+10}),f.c.info('Video #%s "%s" got requested again, increased priority from %s to %s',a.id,a.title,a.priority-10,a.priority)),a}static getCurrentVideo(t=1e4){return D.currentVideo?Date.now()-D.currentVideoHeartbeatTimestamp>t?null:D.currentVideo:null}static getCurrentYoutubeVideo(t){const e=this.getCurrentVideo(t);return e?"youtube"===e.extractor?e:void g.default.say("Beim abgespielten Video scheint es sich nicht um ein YouTube-Video zu handeln."):null}static async getVlcState(){if(!y.default.hasClient())return void g.default.say("Ich habe keine Verbindung zum Computer von Jaidchen und kann somit auch das Kino nicht kontaktieren!");const t=await u.a.withDefaultTimeout(y.default.client,"getVlcState");if("noVlc"!==t)return t;g.default.say("Kein Lebenszeichen aus dem Kino, sorry!")}static async sendVlcCommand(t,e){if(!y.default.hasClient())return void g.default.say("Ich habe keine Verbindung zum Computer von Jaidchen und kann somit auch das Kino nicht kontaktieren!");const n={command:t,...e},r=await u.a.withDefaultTimeout(y.default.client,"sendVlcCommand",n);if("noVlc"!==r){if("commandFailed"!==r)return r;g.default.say("Die Anweisung ans Kino hat jetzt nicht so richtig geklappt.")}else g.default.say("Kein Lebenszeichen aus dem Kino, sorry!")}hasBeenWatched(){return null!==this.watchedAt}async play(){return y.default.hasClient()?this.videoFile?u.a.withDefaultTimeout(y.default.client,"playVideo",i()(this.get(),"videoFile","timestamp")):(f.c.warn("Tried to play video #%s on desktop, but videoFile is not defined",this.id),!1):(f.c.warn("Couldn't play video #%s, not connected to desktop",this.id),!1)}getDurationMs(){return this.vlcDuration||this.duration}getDurationSeconds(){return Math.floor(this.getDurationMs()/1e3)}}D.currentVideo=null,D.currentVideoHeartbeatTimestamp=null;const v={title:{allowNull:!1,type:p.a.STRING},duration:p.a.INTEGER,views:p.a.BIGINT,likes:p.a.INTEGER,dislikes:p.a.INTEGER,publishedAt:p.a.DATE,format:p.a.STRING,extractor:p.a.STRING,width:p.a.SMALLINT,height:p.a.SMALLINT,webUrl:p.a.TEXT,audioCodec:p.a.STRING,videoCodec:p.a.STRING,formatId:p.a.STRING,fileExtension:p.a.STRING,description:p.a.TEXT,thumbnailUrl:p.a.TEXT,channelUrl:p.a.TEXT,audioBitrate:p.a.SMALLINT,videoBitrate:p.a.INTEGER,mediaId:p.a.STRING,ageLimit:p.a.SMALLINT,publisher:p.a.STRING,publisherId:p.a.STRING,info:p.a.JSONB,priority:{allowNull:!1,type:p.a.SMALLINT,defaultValue:100},timestamp:p.a.INTEGER,watchedAt:p.a.DATE,skipped:{allowNull:!1,type:p.a.BOOLEAN,defaultValue:!1},liked:p.a.BOOLEAN,frozenUntil:{type:p.a.DATE,allowNull:!1,defaultValue:0},requestUrl:p.a.TEXT,infoFile:p.a.STRING,videoFile:p.a.STRING,bytes:p.a.BIGINT,downloadedAt:p.a.DATE,vlcDuration:p.a.INTEGER,downloadFormat:p.a.STRING},E=[{unique:!0,fields:["extractor","mediaId"]}];e.default=D},function(t,e){t.exports=require("has-content")},function(t,e,n){"use strict";var r=n(72),i=n.n(r),s=n(157);n.n(s)()(i.a),i.a.locale("de"),e.a=i.a},function(t,e){t.exports=require("path")},function(t,e,n){"use strict";n.r(e);var r=n(19),i=n.n(r),s=n(152),o=n.n(s),a=n(153),u=n.n(a),c=n(0),l=new u.a({logger:c.c}),h=n(2);class p extends i.a{async init(){this.socketServer=o()(c.b.insecureServer),this.socketServer.on("connection",t=>t.handshake.query.password!==c.a.serverPassword?(c.c.warn("Received wrong password from client %s, disconnecting",t.handshake.address),void t.disconnect()):this.hasClient()?(c.c.warn("Client %s tried to connect, but another client is already here",t.handshake.address),void t.disconnect()):(this.client=t,t.on("disconnect",()=>{delete this.client,c.c.info("Client %s has disconnected",t.handshake.address),h.default.say("Uff, ich habe die Verbindung zum Computer von Jaidchen verloren.")}),this.emit("gotClient",t),void h.default.say("Ich bin jetzt mit dem Computer von Jaidchen verbunden!"))),l.enhanceServer(this.socketServer)}hasClient(){return Boolean(this.client)}emitToClient(...t){var e;null===(e=this.client)||void 0===e||e.emit(...t)}emitToOverlay(...t){this.emitToClient("forwardToOverlay",...t)}}e.default=new p},function(t,e,n){var r,i,s=n(17),o=n(334),a=n(336),u=n(337),c=n(30);"function"==typeof Symbol&&"function"==typeof Symbol.for?(r=Symbol.for("graceful-fs.queue"),i=Symbol.for("graceful-fs.previous")):(r="___graceful-fs.queue",i="___graceful-fs.previous");var l=function(){};if(c.debuglog?l=c.debuglog("gfs4"):/\bgfs4\b/i.test(process.env.NODE_DEBUG||"")&&(l=function(){var t=c.format.apply(c,arguments);t="GFS4: "+t.split(/\n/).join("\nGFS4: "),console.error(t)}),!global[r]){var h=[];Object.defineProperty(global,r,{get:function(){return h}}),s.close=function(t){function e(e,n){return t.call(s,e,(function(t){t||f(),"function"==typeof n&&n.apply(this,arguments)}))}return Object.defineProperty(e,i,{value:t}),e}(s.close),s.closeSync=function(t){function e(e){t.apply(s,arguments),f()}return Object.defineProperty(e,i,{value:t}),e}(s.closeSync),/\bgfs4\b/i.test(process.env.NODE_DEBUG||"")&&process.on("exit",(function(){l(global[r]),n(28).equal(global[r].length,0)}))}function p(t){o(t),t.gracefulify=p,t.createReadStream=function(e,n){return new t.ReadStream(e,n)},t.createWriteStream=function(e,n){return new t.WriteStream(e,n)};var e=t.readFile;t.readFile=function(t,n,r){return"function"==typeof n&&(r=n,n=null),function t(n,r,i){return e(n,r,(function(e){!e||"EMFILE"!==e.code&&"ENFILE"!==e.code?("function"==typeof i&&i.apply(this,arguments),f()):d([t,[n,r,i]])}))}(t,n,r)};var n=t.writeFile;t.writeFile=function(t,e,r,i){return"function"==typeof r&&(i=r,r=null),function t(e,r,i,s){return n(e,r,i,(function(n){!n||"EMFILE"!==n.code&&"ENFILE"!==n.code?("function"==typeof s&&s.apply(this,arguments),f()):d([t,[e,r,i,s]])}))}(t,e,r,i)};var r=t.appendFile;r&&(t.appendFile=function(t,e,n,i){return"function"==typeof n&&(i=n,n=null),function t(e,n,i,s){return r(e,n,i,(function(r){!r||"EMFILE"!==r.code&&"ENFILE"!==r.code?("function"==typeof s&&s.apply(this,arguments),f()):d([t,[e,n,i,s]])}))}(t,e,n,i)});var i=t.readdir;function s(e){return i.apply(t,e)}if(t.readdir=function(t,e,n){var r=[t];return"function"!=typeof e?r.push(e):n=e,r.push((function(t,e){e&&e.sort&&e.sort(),!t||"EMFILE"!==t.code&&"ENFILE"!==t.code?("function"==typeof n&&n.apply(this,arguments),f()):d([s,[r]])})),s(r)},"v0.8"===process.version.substr(0,4)){var u=a(t);y=u.ReadStream,g=u.WriteStream}var c=t.ReadStream;c&&(y.prototype=Object.create(c.prototype),y.prototype.open=function(){var t=this;v(t.path,t.flags,t.mode,(function(e,n){e?(t.autoClose&&t.destroy(),t.emit("error",e)):(t.fd=n,t.emit("open",n),t.read())}))});var l=t.WriteStream;l&&(g.prototype=Object.create(l.prototype),g.prototype.open=function(){var t=this;v(t.path,t.flags,t.mode,(function(e,n){e?(t.destroy(),t.emit("error",e)):(t.fd=n,t.emit("open",n))}))}),Object.defineProperty(t,"ReadStream",{get:function(){return y},set:function(t){y=t},enumerable:!0,configurable:!0}),Object.defineProperty(t,"WriteStream",{get:function(){return g},set:function(t){g=t},enumerable:!0,configurable:!0});var h=y;Object.defineProperty(t,"FileReadStream",{get:function(){return h},set:function(t){h=t},enumerable:!0,configurable:!0});var m=g;function y(t,e){return this instanceof y?(c.apply(this,arguments),this):y.apply(Object.create(y.prototype),arguments)}function g(t,e){return this instanceof g?(l.apply(this,arguments),this):g.apply(Object.create(g.prototype),arguments)}Object.defineProperty(t,"FileWriteStream",{get:function(){return m},set:function(t){m=t},enumerable:!0,configurable:!0});var D=t.open;function v(t,e,n,r){return"function"==typeof n&&(r=n,n=null),function t(e,n,r,i){return D(e,n,r,(function(s,o){!s||"EMFILE"!==s.code&&"ENFILE"!==s.code?("function"==typeof i&&i.apply(this,arguments),f()):d([t,[e,n,r,i]])}))}(t,e,n,r)}return t.open=v,t}function d(t){l("ENQUEUE",t[0].name,t[1]),global[r].push(t)}function f(){var t=global[r].shift();t&&(l("RETRY",t[0].name,t[1]),t[0].apply(null,t[1]))}t.exports=p(u(s)),process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH&&!s.__patched&&(t.exports=p(s),s.__patched=!0)},function(t,e){(function(){t.exports={Element:1,Attribute:2,Text:3,CData:4,EntityReference:5,EntityDeclaration:6,ProcessingInstruction:7,Comment:8,Document:9,DocType:10,DocumentFragment:11,NotationDeclaration:12,Declaration:201,Raw:202,AttributeDeclaration:203,ElementDeclaration:204,Dummy:205}}).call(this)},function(t,e,n){"use strict";var r=n(41),i=["kind","resolve","construct","instanceOf","predicate","represent","defaultStyle","styleAliases"],s=["scalar","sequence","mapping"];t.exports=function(t,e){var n,o;if(e=e||{},Object.keys(e).forEach((function(e){if(-1===i.indexOf(e))throw new r('Unknown option "'+e+'" is met in definition of "'+t+'" YAML type.')})),this.tag=t,this.kind=e.kind||null,this.resolve=e.resolve||function(){return!0},this.construct=e.construct||function(t){return t},this.instanceOf=e.instanceOf||null,this.predicate=e.predicate||null,this.represent=e.represent||null,this.defaultStyle=e.defaultStyle||null,this.styleAliases=(n=e.styleAliases||null,o={},null!==n&&Object.keys(n).forEach((function(t){n[t].forEach((function(e){o[String(e)]=t}))})),o),-1===s.indexOf(this.kind))throw new r('Unknown kind "'+this.kind+'" is specified for "'+t+'" YAML type.')}},function(t,e,n){"use strict";n.r(e),e.default=new class{constructor(){this.currentProject=null,this.currentProjectRepo=null,this.projectSetDate=null}setProject(t,e=null){this.currentProject=t,this.currentProjectRepo=e,this.projectSetDate=Date.now()}clearProject(){this.currentProject=null}collectModels(){const t={},e=n(251);for(const n of e.keys())t[n.match(/\.\/(?<key>[\da-z]+)\./i).groups.key]=e(n);return t}}},function(t,e,n){"use strict";e.fromCallback=function(t){return Object.defineProperty((function(){if("function"!=typeof arguments[arguments.length-1])return new Promise((e,n)=>{arguments[arguments.length]=(t,r)=>{if(t)return n(t);e(r)},arguments.length++,t.apply(this,arguments)});t.apply(this,arguments)}),"name",{value:t.name})},e.fromPromise=function(t){return Object.defineProperty((function(){const e=arguments[arguments.length-1];if("function"!=typeof e)return t.apply(this,arguments);t.apply(this,arguments).then(t=>e(null,t),e)}),"name",{value:t.name})}},function(t,e,n){"use strict";n.r(e),n.d(e,"schema",(function(){return l}));var r=n(158),i=n(66),s=n.n(i),o=n(1),a=n.n(o),u=n(2);class c extends a.a.Model{static start(){u.default.isReady&&setInterval(c.tick,6e4)}static async tick(){const t=Object(r.measureTime)(),e={},n=s.a.freemem(),i=s.a.totalmem(),o=i-n,a=await u.default.getMyStream();a&&(c.lastTwitchStatus={averageFps:a.averageFPS,delay:a.delay,viewers:a.viewers,game:a.game,videoHeight:a.videoHeight,streamType:a.type,streamStartedAt:a.startDate,language:a.channel.broadcasterLanguage,isMature:a.channel.isMature,followers:a.channel.followers,streamTitle:a.channel.status},Object.assign(e,c.lastTwitchStatus)),e.ramUsage=Math.floor(o/i*100),e.executionTime=t().milliseconds,await c.create(e),c.currentStatus=e}}c.currentStatus=void 0,c.lastTwitchStatus=void 0;const l={averageFps:a.a.SMALLINT,delay:a.a.SMALLINT,game:a.a.STRING,videoHeight:a.a.SMALLINT,streamType:a.a.STRING(16),streamStartedAt:a.a.DATE,isMature:a.a.BOOLEAN,followers:a.a.INTEGER,streamTitle:a.a.STRING,language:a.a.STRING,viewers:a.a.INTEGER,ramUsage:{allowNull:!1,type:a.a.SMALLINT},executionTime:{allowNull:!1,type:a.a.INTEGER}};e.default=c},function(t,e,n){"use strict";const r=(0,n(12).fromCallback)(n(339)),i=n(340);t.exports={mkdirs:r,mkdirsSync:i,mkdirp:r,mkdirpSync:i,ensureDir:r,ensureDirSync:i}},function(t,e,n){(function(){var e,r,i,s,o,a,u,c,l,h,p,d,f,m,y,g,D,v={}.hasOwnProperty;D=n(23),g=D.isObject,y=D.isFunction,m=D.isEmpty,f=D.getValue,c=null,i=null,s=null,o=null,a=null,p=null,d=null,h=null,u=null,r=null,l=null,e=null,t.exports=function(){function t(t){this.parent=t,this.parent&&(this.options=this.parent.options,this.stringify=this.parent.stringify),this.value=null,this.children=[],this.baseURI=null,c||(c=n(87),i=n(89),s=n(90),o=n(91),a=n(92),p=n(97),d=n(98),h=n(99),u=n(144),r=n(9),l=n(391),n(88),e=n(392))}return Object.defineProperty(t.prototype,"nodeName",{get:function(){return this.name}}),Object.defineProperty(t.prototype,"nodeType",{get:function(){return this.type}}),Object.defineProperty(t.prototype,"nodeValue",{get:function(){return this.value}}),Object.defineProperty(t.prototype,"parentNode",{get:function(){return this.parent}}),Object.defineProperty(t.prototype,"childNodes",{get:function(){return this.childNodeList&&this.childNodeList.nodes||(this.childNodeList=new l(this.children)),this.childNodeList}}),Object.defineProperty(t.prototype,"firstChild",{get:function(){return this.children[0]||null}}),Object.defineProperty(t.prototype,"lastChild",{get:function(){return this.children[this.children.length-1]||null}}),Object.defineProperty(t.prototype,"previousSibling",{get:function(){var t;return t=this.parent.children.indexOf(this),this.parent.children[t-1]||null}}),Object.defineProperty(t.prototype,"nextSibling",{get:function(){var t;return t=this.parent.children.indexOf(this),this.parent.children[t+1]||null}}),Object.defineProperty(t.prototype,"ownerDocument",{get:function(){return this.document()||null}}),Object.defineProperty(t.prototype,"textContent",{get:function(){var t,e,n,i,s;if(this.nodeType===r.Element||this.nodeType===r.DocumentFragment){for(s="",e=0,n=(i=this.children).length;n>e;e++)(t=i[e]).textContent&&(s+=t.textContent);return s}return null},set:function(t){throw new Error("This DOM method is not implemented."+this.debugInfo())}}),t.prototype.setParent=function(t){var e,n,r,i,s;for(this.parent=t,t&&(this.options=t.options,this.stringify=t.stringify),s=[],n=0,r=(i=this.children).length;r>n;n++)e=i[n],s.push(e.setParent(this));return s},t.prototype.element=function(t,e,n){var r,i,s,o,a,u,c,l,h,p,d;if(u=null,null===e&&null==n&&(e=(h=[{},null])[0],n=h[1]),null==e&&(e={}),e=f(e),g(e)||(n=(p=[e,n])[0],e=p[1]),null!=t&&(t=f(t)),Array.isArray(t))for(s=0,c=t.length;c>s;s++)i=t[s],u=this.element(i);else if(y(t))u=this.element(t.apply());else if(g(t)){for(a in t)if(v.call(t,a))if(d=t[a],y(d)&&(d=d.apply()),!this.options.ignoreDecorators&&this.stringify.convertAttKey&&0===a.indexOf(this.stringify.convertAttKey))u=this.attribute(a.substr(this.stringify.convertAttKey.length),d);else if(!this.options.separateArrayItems&&Array.isArray(d)&&m(d))u=this.dummy();else if(g(d)&&m(d))u=this.element(a);else if(this.options.keepNullNodes||null!=d)if(!this.options.separateArrayItems&&Array.isArray(d))for(o=0,l=d.length;l>o;o++)i=d[o],(r={})[a]=i,u=this.element(r);else g(d)?!this.options.ignoreDecorators&&this.stringify.convertTextKey&&0===a.indexOf(this.stringify.convertTextKey)?u=this.element(d):(u=this.element(a)).element(d):u=this.element(a,d);else u=this.dummy()}else u=this.options.keepNullNodes||null!==n?!this.options.ignoreDecorators&&this.stringify.convertTextKey&&0===t.indexOf(this.stringify.convertTextKey)?this.text(n):!this.options.ignoreDecorators&&this.stringify.convertCDataKey&&0===t.indexOf(this.stringify.convertCDataKey)?this.cdata(n):!this.options.ignoreDecorators&&this.stringify.convertCommentKey&&0===t.indexOf(this.stringify.convertCommentKey)?this.comment(n):!this.options.ignoreDecorators&&this.stringify.convertRawKey&&0===t.indexOf(this.stringify.convertRawKey)?this.raw(n):!this.options.ignoreDecorators&&this.stringify.convertPIKey&&0===t.indexOf(this.stringify.convertPIKey)?this.instruction(t.substr(this.stringify.convertPIKey.length),n):this.node(t,e,n):this.dummy();if(null==u)throw new Error("Could not create any elements with: "+t+". "+this.debugInfo());return u},t.prototype.insertBefore=function(t,e,n){var r,i,s,o,a;if(null!=t?t.type:void 0)return o=e,(s=t).setParent(this),o?(i=children.indexOf(o),a=children.splice(i),children.push(s),Array.prototype.push.apply(children,a)):children.push(s),s;if(this.isRoot)throw new Error("Cannot insert elements at root level. "+this.debugInfo(t));return i=this.parent.children.indexOf(this),a=this.parent.children.splice(i),r=this.parent.element(t,e,n),Array.prototype.push.apply(this.parent.children,a),r},t.prototype.insertAfter=function(t,e,n){var r,i,s;if(this.isRoot)throw new Error("Cannot insert elements at root level. "+this.debugInfo(t));return i=this.parent.children.indexOf(this),s=this.parent.children.splice(i+1),r=this.parent.element(t,e,n),Array.prototype.push.apply(this.parent.children,s),r},t.prototype.remove=function(){var t;if(this.isRoot)throw new Error("Cannot remove the root element. "+this.debugInfo());return t=this.parent.children.indexOf(this),[].splice.apply(this.parent.children,[t,t-t+1].concat([])),this.parent},t.prototype.node=function(t,e,n){var r,i;return null!=t&&(t=f(t)),e||(e={}),e=f(e),g(e)||(n=(i=[e,n])[0],e=i[1]),r=new c(this,t,e),null!=n&&r.text(n),this.children.push(r),r},t.prototype.text=function(t){var e;return g(t)&&this.element(t),e=new d(this,t),this.children.push(e),this},t.prototype.cdata=function(t){var e;return e=new i(this,t),this.children.push(e),this},t.prototype.comment=function(t){var e;return e=new s(this,t),this.children.push(e),this},t.prototype.commentBefore=function(t){var e,n;return e=this.parent.children.indexOf(this),n=this.parent.children.splice(e),this.parent.comment(t),Array.prototype.push.apply(this.parent.children,n),this},t.prototype.commentAfter=function(t){var e,n;return e=this.parent.children.indexOf(this),n=this.parent.children.splice(e+1),this.parent.comment(t),Array.prototype.push.apply(this.parent.children,n),this},t.prototype.raw=function(t){var e;return e=new p(this,t),this.children.push(e),this},t.prototype.dummy=function(){return new u(this)},t.prototype.instruction=function(t,e){var n,r,i,s,o;if(null!=t&&(t=f(t)),null!=e&&(e=f(e)),Array.isArray(t))for(s=0,o=t.length;o>s;s++)n=t[s],this.instruction(n);else if(g(t))for(n in t)v.call(t,n)&&(r=t[n],this.instruction(n,r));else y(e)&&(e=e.apply()),i=new h(this,t,e),this.children.push(i);return this},t.prototype.instructionBefore=function(t,e){var n,r;return n=this.parent.children.indexOf(this),r=this.parent.children.splice(n),this.parent.instruction(t,e),Array.prototype.push.apply(this.parent.children,r),this},t.prototype.instructionAfter=function(t,e){var n,r;return n=this.parent.children.indexOf(this),r=this.parent.children.splice(n+1),this.parent.instruction(t,e),Array.prototype.push.apply(this.parent.children,r),this},t.prototype.declaration=function(t,e,n){var i,s;return i=this.document(),s=new o(i,t,e,n),0===i.children.length?i.children.unshift(s):i.children[0].type===r.Declaration?i.children[0]=s:i.children.unshift(s),i.root()||i},t.prototype.dtd=function(t,e){var n,i,s,o,u,c,l,h,p;for(n=this.document(),i=new a(n,t,e),s=o=0,c=(h=n.children).length;c>o;s=++o)if(h[s].type===r.DocType)return n.children[s]=i,i;for(s=u=0,l=(p=n.children).length;l>u;s=++u)if(p[s].isRoot)return n.children.splice(s,0,i),i;return n.children.push(i),i},t.prototype.up=function(){if(this.isRoot)throw new Error("The root node has no parent. Use doc() if you need to get the document object.");return this.parent},t.prototype.root=function(){var t;for(t=this;t;){if(t.type===r.Document)return t.rootObject;if(t.isRoot)return t;t=t.parent}},t.prototype.document=function(){var t;for(t=this;t;){if(t.type===r.Document)return t;t=t.parent}},t.prototype.end=function(t){return this.document().end(t)},t.prototype.prev=function(){var t;if(1>(t=this.parent.children.indexOf(this)))throw new Error("Already at the first node. "+this.debugInfo());return this.parent.children[t-1]},t.prototype.next=function(){var t;if(-1===(t=this.parent.children.indexOf(this))||t===this.parent.children.length-1)throw new Error("Already at the last node. "+this.debugInfo());return this.parent.children[t+1]},t.prototype.importDocument=function(t){var e;return(e=t.root().clone()).parent=this,e.isRoot=!1,this.children.push(e),this},t.prototype.debugInfo=function(t){var e,n;return null!=(t=t||this.name)||(null!=(e=this.parent)?e.name:void 0)?null==t?"parent: <"+this.parent.name+">":(null!=(n=this.parent)?n.name:void 0)?"node: <"+t+">, parent: <"+this.parent.name+">":"node: <"+t+">":""},t.prototype.ele=function(t,e,n){return this.element(t,e,n)},t.prototype.nod=function(t,e,n){return this.node(t,e,n)},t.prototype.txt=function(t){return this.text(t)},t.prototype.dat=function(t){return this.cdata(t)},t.prototype.com=function(t){return this.comment(t)},t.prototype.ins=function(t,e){return this.instruction(t,e)},t.prototype.doc=function(){return this.document()},t.prototype.dec=function(t,e,n){return this.declaration(t,e,n)},t.prototype.e=function(t,e,n){return this.element(t,e,n)},t.prototype.n=function(t,e,n){return this.node(t,e,n)},t.prototype.t=function(t){return this.text(t)},t.prototype.d=function(t){return this.cdata(t)},t.prototype.c=function(t){return this.comment(t)},t.prototype.r=function(t){return this.raw(t)},t.prototype.i=function(t,e){return this.instruction(t,e)},t.prototype.u=function(){return this.up()},t.prototype.importXMLBuilder=function(t){return this.importDocument(t)},t.prototype.replaceChild=function(t,e){throw new Error("This DOM method is not implemented."+this.debugInfo())},t.prototype.removeChild=function(t){throw new Error("This DOM method is not implemented."+this.debugInfo())},t.prototype.appendChild=function(t){throw new Error("This DOM method is not implemented."+this.debugInfo())},t.prototype.hasChildNodes=function(){return 0!==this.children.length},t.prototype.cloneNode=function(t){throw new Error("This DOM method is not implemented."+this.debugInfo())},t.prototype.normalize=function(){throw new Error("This DOM method is not implemented."+this.debugInfo())},t.prototype.isSupported=function(t,e){return!0},t.prototype.hasAttributes=function(){return 0!==this.attribs.length},t.prototype.compareDocumentPosition=function(t){var n;return this===t?0:this.document()!==t.document()?(n=e.Disconnected|e.ImplementationSpecific,.5>Math.random()?n|=e.Preceding:n|=e.Following,n):this.isAncestor(t)?e.Contains|e.Preceding:this.isDescendant(t)?e.Contains|e.Following:this.isPreceding(t)?e.Preceding:e.Following},t.prototype.isSameNode=function(t){throw new Error("This DOM method is not implemented."+this.debugInfo())},t.prototype.lookupPrefix=function(t){throw new Error("This DOM method is not implemented."+this.debugInfo())},t.prototype.isDefaultNamespace=function(t){throw new Error("This DOM method is not implemented."+this.debugInfo())},t.prototype.lookupNamespaceURI=function(t){throw new Error("This DOM method is not implemented."+this.debugInfo())},t.prototype.isEqualNode=function(t){var e,n,r;if(t.nodeType!==this.nodeType)return!1;if(t.children.length!==this.children.length)return!1;for(e=n=0,r=this.children.length-1;0>r?n>=r:r>=n;e=0>r?--n:++n)if(!this.children[e].isEqualNode(t.children[e]))return!1;return!0},t.prototype.getFeature=function(t,e){throw new Error("This DOM method is not implemented."+this.debugInfo())},t.prototype.setUserData=function(t,e,n){throw new Error("This DOM method is not implemented."+this.debugInfo())},t.prototype.getUserData=function(t){throw new Error("This DOM method is not implemented."+this.debugInfo())},t.prototype.contains=function(t){return!!t&&(t===this||this.isDescendant(t))},t.prototype.isDescendant=function(t){var e,n,r,i;for(n=0,r=(i=this.children).length;r>n;n++){if(t===(e=i[n]))return!0;if(e.isDescendant(t))return!0}return!1},t.prototype.isAncestor=function(t){return t.isDescendant(this)},t.prototype.isPreceding=function(t){var e,n;return e=this.treePosition(t),n=this.treePosition(this),-1!==e&&-1!==n&&n>e},t.prototype.isFollowing=function(t){var e,n;return e=this.treePosition(t),n=this.treePosition(this),-1!==e&&-1!==n&&e>n},t.prototype.treePosition=function(t){var e,n;return n=0,e=!1,this.foreachTreeNode(this.document(),(function(r){if(n++,!e&&r===t)return e=!0})),e?n:-1},t.prototype.foreachTreeNode=function(t,e){var n,r,i,s,o;for(t||(t=this.document()),r=0,i=(s=t.children).length;i>r;r++){if(o=e(n=s[r]))return o;if(o=this.foreachTreeNode(n,e))return o}},t}()}).call(this)},function(t,e,n){"use strict";n.d(e,"b",(function(){return s}));var r=n(46),i=n.n(r);const s=i.a.humanizer({language:"de",conjunction:" und ",serialComma:!1,maxDecimalPoints:0,units:["h","m"]});e.a=i.a.humanizer({language:"de",conjunction:" und dann noch mal ",serialComma:!1,maxDecimalPoints:0})},function(t,e){t.exports=require("fs")},function(t,e){var n=Array.isArray;t.exports=n},function(t,e){t.exports=require("events")},function(t,e,n){"use strict";n.r(e),n.d(e,"schema",(function(){return g}));var r=n(1),i=n.n(r),s=n(159),o=n.n(s),a=n(65),u=n.n(a),c=n(160),l=n.n(c),h=n(0),p=n(102),d=n(103),f=n(2),m=n(44);class y extends i.a.Model{static associate(t){y.hasMany(t.ChatMessage,{foreignKey:{allowNull:!1}}),y.hasMany(t.Video,{as:"RequestedVideos",foreignKey:"RequesterId"}),y.belongsTo(t.User,{foreignKey:{allowNull:!1}})}static async getByTwitchId(t){return await y.findOne({where:{twitchId:t}})}static async getByTwitchLogin(t){return await y.findOne({where:{loginName:t.toLowerCase()}})}static async findOrRegisterById(t,e){return y.findOrRegister({...e,key:"twitchId",value:t})}static async findOrRegisterByLogin(t,e){return y.findOrRegister({...e,key:"twitchLogin",value:t})}static async findOrRegister({key:t="twitchLogin",value:e,attributes:n,defaults:r}){const i={twitchLogin:{searchColumn:"loginName",fetchUser:t=>f.default.getUserInfoByTwitchLogin(t)},twitchId:{searchColumn:"twitchId",fetchUser:t=>f.default.getUserInfoByTwitchId(t)}},s=await y.findOne({where:{[i[t].searchColumn]:e},attributes:n});if(s)return s;const a=await i[t].fetchUser(e),u=a.name.toLowerCase(),c=a.displayName||u;if("twitchLogin"===t){const t=await y.findOne({where:{twitchId:a.id}});if(t)return h.c.info("Twitch user #%s seems to have been renamed from %s to %s",t.id,t.loginName,e),t.loginName=e,t.displayName=c,await t.save(),t}h.c.info("New Twitch user %s",c);let l=u;return await d.default.isSlugInUse(u)&&(l=o.a.generate(),h.c.warn("Can not use %s for user slug, because is it already in use, using random slug %s instead",u,l)),await y.create({displayName:c,twitchId:a.id,description:a.description,loginName:u,offlineImageUrl:a.offlinePlaceholderUrl,avatarUrl:a.profilePictureUrl,viewCount:a.views,broadcasterType:a.broadcasterType,User:{title:c,color:null==r?void 0:r.nameColor,slug:l},...r},{include:"User"})}static start(){p.default.afterCreate(async t=>{const e=await y.findByPk(t.TwitchUserId,{attributes:["id","nameColor"]});!e.nameColor&&t.nameColor?(h.c.info("Received name color of %s for the first time",t.senderDisplayName),e.nameColor=t.nameColor):e.nameColor!==t.nameColor&&(h.c.info("%s seems to have changed the name color from %s to %s",t.senderDisplayName,e.nameColor,t.nameColor),e.nameColor=t.nameColor),await e.save()})}async toTwitchClient(){const t=await u.a.withCredentials(h.a.twitchClientId,this.accessToken,m.a,{clientSecret:h.a.twitchClientSecret,refreshToken:this.refreshToken,onRefresh:t=>this.updateToken(t),expiry:this.tokenExpiryDate},{preAuth:!0,initialScopes:m.a});return this.tokenExpiryDate||(h.c.info("Initial expiry date not set for user %s. Forcing access token refresh.",this.loginName),await t.refreshAccessToken()),h.c.info("Created client for user %s",this.loginName),t}async toTwitchClientWithChat(){const t=await this.toTwitchClient(),e=await l.a.forTwitchClient(t);return await e.connect(),await e.waitForRegistration(),{apiClient:t,chatClient:e}}async updateToken(t){h.c.info("Refresh token of user %s",this.loginName),this.accessToken=t.accessToken,this.refreshToken=t.refreshToken,this.tokenExpiryDate=t.expiryDate,await this.save({fields:["accessToken","refreshToken","tokenExpiryDate"]})}getDisplayName(){return this.displayName||this.loginName||this.twitchId}}const g={broadcasterType:i.a.STRING(16),description:i.a.STRING,twitchId:{type:i.a.STRING(16),unique:!0,allowNull:!1},nameColor:i.a.STRING,displayName:i.a.STRING(64),loginName:{allowNull:!1,type:i.a.STRING(64)},offlineImageUrl:i.a.TEXT,avatarUrl:i.a.TEXT,viewCount:{allowNull:!1,type:i.a.INTEGER},accessToken:i.a.STRING,refreshToken:i.a.STRING,followDate:i.a.DATE,tokenExpiryDate:i.a.DATE,chatterRole:{allowNull:!1,type:i.a.STRING,defaultValue:"viewers"},offlineTimeMinutes:{type:i.a.INTEGER,defaultValue:0,allowNull:!1},liveWatchTimeMinutes:{type:i.a.INTEGER,defaultValue:0,allowNull:!1},vodcastWatchTimeMinutes:{type:i.a.INTEGER,defaultValue:0,allowNull:!1}};e.default=y},function(t,e){t.exports=require("zahl")},function(t,e,n){"use strict";const r=n(12).fromPromise,i=n(132);t.exports={pathExists:r((function(t){return i.access(t).then(()=>!0).catch(()=>!1)})),pathExistsSync:i.existsSync}},function(t,e){(function(){var e,n,r,i,s,o,a,u=[].slice,c={}.hasOwnProperty;e=function(){var t,e,n,r,i,o;if(o=arguments[0],i=2>arguments.length?[]:u.call(arguments,1),s(Object.assign))Object.assign.apply(null,arguments);else for(t=0,n=i.length;n>t;t++)if(null!=(r=i[t]))for(e in r)c.call(r,e)&&(o[e]=r[e]);return o},s=function(t){return!!t&&"[object Function]"===Object.prototype.toString.call(t)},o=function(t){var e;return!!t&&("function"==(e=typeof t)||"object"===e)},r=function(t){return s(Array.isArray)?Array.isArray(t):"[object Array]"===Object.prototype.toString.call(t)},i=function(t){var e;if(r(t))return!t.length;for(e in t)if(c.call(t,e))return!1;return!0},a=function(t){var e,n;return o(t)&&(n=Object.getPrototypeOf(t))&&(e=n.constructor)&&"function"==typeof e&&e instanceof e&&Function.prototype.toString.call(e)===Function.prototype.toString.call(Object)},n=function(t){return s(t.valueOf)?t.valueOf():t},t.exports.assign=e,t.exports.isFunction=s,t.exports.isObject=o,t.exports.isArray=r,t.exports.isEmpty=i,t.exports.isPlainObject=a,t.exports.getValue=n}).call(this)},function(t,e,n){"use strict";n.r(e),n.d(e,"schema",(function(){return c}));var r=n(45),i=n.n(r),s=n(1),o=n.n(s),a=n(2);class u extends o.a.Model{static async addForDate(t,e){(await u.create({date:t,message:e})).schedule()}static async addForDelay(t,e){await u.addForDate(new Date(Date.now()+t),e)}static async start(){const t=await u.getPendingMessages();for(const e of t)e.schedule()}static async getPendingMessages(){return u.findAll({where:{date:{[s.Op.gt]:Date.now()}},attributes:["id","date","message"]})}schedule(){i.a.scheduleJob(this.date,async()=>{a.default.say(this.message),await this.update({isSent:!0})})}}const c={date:{allowNull:!1,type:o.a.DATE},message:{allowNull:!1,type:o.a.STRING},isSent:{allowNull:!1,type:o.a.BOOLEAN,defaultValue:!1}};e.default=u},function(t,e){t.exports=require("emit-promise")},function(t,e,n){var r=n(50),i=n(188),s=n(189),o=r?r.toStringTag:void 0;t.exports=function(t){return null==t?void 0===t?"[object Undefined]":"[object Null]":o&&o in Object(t)?i(t):s(t)}},function(t,e){t.exports=function(t){return null!=t&&"object"==typeof t}},function(t,e){t.exports=require("assert")},function(t,e,n){"use strict";var r=n(19),i=n.n(r),s=n(16),o=n(5),a=n(7),u=n(2);class c extends i.a{constructor(){super(),this.afkMessage=null,this.afkStart=null,this.afkEnd=null,this.title=null,setInterval(()=>{this.isAfk()&&this.updateTitle()},3e4)}isAfk(){return null!==this.afkMessage}getRemainingTime(){return this.afkEnd-Date.now()}getTitlePrefix(){if(!this.isAfk())return"";const t=this.getRemainingTime();return-6e4>t?`[Schon ${o.a.duration(-t,"ms").format("h[h] m[m]")} länger weg als angesagt] `:t>6e4?`[In ${o.a.duration(t,"ms").format("h[h] m[m]")} wieder da] `:"[Demnächst zurück] "}async updateTitle(){const t=Object(u.removeTitlePrefix)(u.default.currentTitle);await u.default.setTitle(`${this.getTitlePrefix()}${t}`)}async activate(t,e){var n,r;this.afkStart=Date.now(),this.afkEnd=this.afkStart+1e3*t,this.afkMessage=e,null===(n=a.default.client)||void 0===n||n.emit("startAfk",{start:this.afkStart,end:this.afkEnd,message:this.afkMessage}),await this.updateTitle(),u.default.startAdLoop(),u.default.say(`Jaidchen geht jetzt mal weg für etwa ${r=1e3*t,Object(s.a)(r)}. Als Nachricht hat er lediglich ein "${e}" hinterlassen.`)}async deactivate(){const t=this.getRemainingTime(),e=(()=>{var e,n,r;return t>12e4?`Oh, der ist ja schon wieder da, ${e=t,Object(s.a)(e)} früher als angekündigt! KomodoHype`:t>-12e4?"Da ist er ja wieder! TPFufun":`"${this.afkMessage}", ja ja. Du wolltest doch eigentlich schon seit ${r=t,n=Math.abs(r),Object(s.a)(n)} wieder da sein. Jaidchen, wo bist du gewesen? PunOko`})();this.afkStart=null,this.afkEnd=null,this.afkMessage=null,await this.updateTitle(),u.default.stopAdLoop(),u.default.say(e)}}e.a=new c},function(t,e){t.exports=require("util")},function(t,e,n){t.exports=function(t){var e={};function n(r){if(e[r])return e[r].exports;var i=e[r]={i:r,l:!1,exports:{}};return t[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var i in t)n.d(r,i,function(e){return t[e]}.bind(null,i));return r},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=4)}([function(t,e,n){"use strict";var r=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(e,"__esModule",{value:!0});const i=r(n(1)),s=n(8),o=n(2),a=n(16);e.validatorSymbol=Symbol("validators"),e.Predicate=class{constructor(t,e={}){this.type=t,this.options=e,this.context={validators:[]},this.context=Object.assign({},this.context,this.options);const n=this.type[0].toLowerCase()+this.type.slice(1);this.addValidator({message:(t,e)=>`Expected ${e&&e.substring(this.type.length+1)||"argument"} to be of type \`