Greasy Fork is available in English.

Flow Youtube Chat

Youtubeのチャットをニコニコ風に画面上へ流すスクリプトです(再アップ,絵文字バグ修正済み)

2021/04/05時点のページです。最新版はこちら。

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください。
// ==UserScript==
// @name        Flow Youtube Chat
// @version     1.15.0
// @description Youtubeのチャットをニコニコ風に画面上へ流すスクリプトです(再アップ,絵文字バグ修正済み)
// @match       https://www.youtube.com/*
// @namespace   FlowYoutubeChatScript
// @run-at      document-end
// @grant       GM.setValue
// @grant       GM.getValue
// @grant       GM.deleteValue
// @grant       GM.listValues
// @grant       GM.setClipboard
// @noframes
// @license     AGPL-3.0-or-later
// @require     https://cdn.jsdelivr.net/npm/sweetalert2@10.10.1/dist/sweetalert2.all.min.js#sha384-OCBhaEdUu7BFgaeRVey2PDeHof2MSQRFe/e6S8Q3XrmSV7wrKpLmhPj8FOldGiaF
// @require     https://unpkg.com/loglevel@1.7.0/dist/loglevel.min.js#sha384-7gGuWfek8Ql6j/uNDFrS0BCe4x2ZihD4B68w9Eu580OVHJBV+bl3rZmEWC7q5/Gj
// @require     https://unpkg.com/rxjs@7.0.0-beta.10/dist/bundles/rxjs.umd.min.js#sha384-+BwV2u+ZJFwj586/3PlpsZdYS1U/+hT/zpjYSznHH4XzUJqgshDzZITJ+zGeWl//
// @require     https://unpkg.com/mithril@2.0.4/mithril.min.js#sha384-vo9crXih40MlEv6JWHqS7SsPiFp+76csaWQFOF2UU0/xI58Jm/ZvK/1UtpaicJT9
// @require     https://cdn.jsdelivr.net/npm/check-types@11.1.2/src/check-types.min.js#sha384-KGnImnhVjA5llfqKEbjBiY+1Mp6oa+NvW/TEY1XTPAKWNgrAwa3Qvn//MXL07wBM
// @require     https://cdn.jsdelivr.net/npm/deep-diff@1.0.2/index.min.js#sha384-Q/uiWfFlwn9XjOpL49VpFKn01EkScmaC3hh1prAn7S++WoZgXRrrjQvZ7cI7C7Zn
// @require     https://cdn.jsdelivr.net/npm/astring@1.7.0/dist/astring.min.js#sha384-QHrTlnYTIr9r51gEjAJ/fTnbEJpQzcyZFQ7HmNTK+oR/pBYw2m9y0jV0POoLH4bn
// @require     https://cdn.jsdelivr.net/npm/jsep@0.4.0/build/jsep.min.js#sha384-89PRdfFVlT2bC9VxvLdvlByyVGml9l14DjpPqZYVI9umfvV24KPZ5dY6qBOeKf2z
// @require     https://cdn.jsdelivr.net/npm/hash-it@5.0.0/dist/hash-it.min.js#sha384-FUKF3wpiG+sroVb9gRjA7xyDDUNV0AJKZMqn0pBhxQfTR46NoegCce6vE16E1cbA
// @require     https://cdn.jsdelivr.net/npm/micro-memoize@4.0.9/dist/micro-memoize.min.js#sha384-aGxbSIH2oMTKxZ93i+/iQKx5xefR8mHJW3mkbRaiSZizVoCvKS6wzndlLeQzMv9B
// ==/UserScript==

/* jshint esversion: 6 */

;(() => {
  var __webpack_modules__ = {
      378: module => {
        "use strict"
        module.exports = function equal(a, b) {
          if (a === b) return !0
          if (a && b && "object" == typeof a && "object" == typeof b) {
            if (a.constructor !== b.constructor) return !1
            var length, i, keys
            if (Array.isArray(a)) {
              if ((length = a.length) != b.length) return !1
              for (i = length; 0 != i--; ) if (!equal(a[i], b[i])) return !1
              return !0
            }
            if (a.constructor === RegExp)
              return a.source === b.source && a.flags === b.flags
            if (a.valueOf !== Object.prototype.valueOf)
              return a.valueOf() === b.valueOf()
            if (a.toString !== Object.prototype.toString)
              return a.toString() === b.toString()
            if (
              (length = (keys = Object.keys(a)).length) !==
              Object.keys(b).length
            )
              return !1
            for (i = length; 0 != i--; )
              if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return !1
            for (i = length; 0 != i--; ) {
              var key = keys[i]
              if (!equal(a[key], b[key])) return !1
            }
            return !0
          }
          return a != a && b != b
        }
      },
      815: () => {},
    },
    __webpack_module_cache__ = {}
  function __webpack_require__(moduleId) {
    if (__webpack_module_cache__[moduleId])
      return __webpack_module_cache__[moduleId].exports
    var module = (__webpack_module_cache__[moduleId] = { exports: {} })
    return (
      __webpack_modules__[moduleId](
        module,
        module.exports,
        __webpack_require__
      ),
      module.exports
    )
  }
  ;(__webpack_require__.n = module => {
    var getter =
      module && module.__esModule ? () => module.default : () => module
    return __webpack_require__.d(getter, { a: getter }), getter
  }),
    (__webpack_require__.d = (exports, definition) => {
      for (var key in definition)
        __webpack_require__.o(definition, key) &&
          !__webpack_require__.o(exports, key) &&
          Object.defineProperty(exports, key, {
            enumerable: !0,
            get: definition[key],
          })
    }),
    (__webpack_require__.o = (obj, prop) =>
      Object.prototype.hasOwnProperty.call(obj, prop)),
    (() => {
      "use strict"
      var function_getMonoid = function (M) {
        var S,
          getSemigroupM =
            ((S = M),
            function () {
              return {
                concat: function (f, g) {
                  return function (a) {
                    return S.concat(f(a), g(a))
                  }
                },
              }
            })
        return function () {
          return {
            concat: getSemigroupM().concat,
            empty: function () {
              return M.empty
            },
          }
        }
      }
      function function_identity(a) {
        return a
      }
      function constant(a) {
        return function () {
          return a
        }
      }
      var constUndefined = constant(void 0)
      function function_pipe(
        a,
        ab,
        bc,
        cd,
        de,
        ef,
        fg,
        gh,
        hi,
        ij,
        jk,
        kl,
        lm,
        mn,
        no,
        op,
        pq,
        qr,
        rs,
        st
      ) {
        switch (arguments.length) {
          case 1:
            return a
          case 2:
            return ab(a)
          case 3:
            return bc(ab(a))
          case 4:
            return cd(bc(ab(a)))
          case 5:
            return de(cd(bc(ab(a))))
          case 6:
            return ef(de(cd(bc(ab(a)))))
          case 7:
            return fg(ef(de(cd(bc(ab(a))))))
          case 8:
            return gh(fg(ef(de(cd(bc(ab(a)))))))
          case 9:
            return hi(gh(fg(ef(de(cd(bc(ab(a))))))))
          case 10:
            return ij(hi(gh(fg(ef(de(cd(bc(ab(a)))))))))
          case 11:
            return jk(ij(hi(gh(fg(ef(de(cd(bc(ab(a))))))))))
          case 12:
            return kl(jk(ij(hi(gh(fg(ef(de(cd(bc(ab(a)))))))))))
          case 13:
            return lm(kl(jk(ij(hi(gh(fg(ef(de(cd(bc(ab(a))))))))))))
          case 14:
            return mn(lm(kl(jk(ij(hi(gh(fg(ef(de(cd(bc(ab(a)))))))))))))
          case 15:
            return no(mn(lm(kl(jk(ij(hi(gh(fg(ef(de(cd(bc(ab(a))))))))))))))
          case 16:
            return op(no(mn(lm(kl(jk(ij(hi(gh(fg(ef(de(cd(bc(ab(a)))))))))))))))
          case 17:
            return pq(
              op(no(mn(lm(kl(jk(ij(hi(gh(fg(ef(de(cd(bc(ab(a)))))))))))))))
            )
          case 18:
            return qr(
              pq(op(no(mn(lm(kl(jk(ij(hi(gh(fg(ef(de(cd(bc(ab(a))))))))))))))))
            )
          case 19:
            return rs(
              qr(
                pq(
                  op(no(mn(lm(kl(jk(ij(hi(gh(fg(ef(de(cd(bc(ab(a)))))))))))))))
                )
              )
            )
          case 20:
            return st(
              rs(
                qr(
                  pq(
                    op(
                      no(mn(lm(kl(jk(ij(hi(gh(fg(ef(de(cd(bc(ab(a))))))))))))))
                    )
                  )
                )
              )
            )
        }
      }
      Object.prototype.hasOwnProperty
      function flap(F) {
        return function (a) {
          return function (fab) {
            return F.map(fab, function (f) {
              return f(a)
            })
          }
        }
      }
      var separated = function (left, right) {
          return { left, right }
        },
        Separated_map = function (f) {
          return function (fa) {
            return separated(left(fa), f(right(fa)))
          }
        },
        left =
          (flap({
            URI: "Separated",
            map: function (fa, f) {
              return function_pipe(fa, Separated_map(f))
            },
          }),
          function (s) {
            return s.left
          }),
        right = function (s) {
          return s.right
        },
        Option_isSome = function (fa) {
          return "Some" === fa._tag
        },
        isNone = function (fa) {
          return "None" === fa._tag
        },
        none = { _tag: "None" },
        some = function (a) {
          return { _tag: "Some", value: a }
        }
      function fromPredicate(predicate) {
        return function (a) {
          return predicate(a) ? some(a) : none
        }
      }
      var matchW = function (onNone, onSome) {
          return function (ma) {
            return isNone(ma) ? onNone() : onSome(ma.value)
          }
        },
        match = matchW,
        getOrElse = function (onNone) {
          return function (ma) {
            return isNone(ma) ? onNone() : ma.value
          }
        },
        fromNullable = function (a) {
          return null == a ? none : some(a)
        },
        chainNullableK = function (f) {
          return function (ma) {
            return isNone(ma) ? none : fromNullable(f(ma.value))
          }
        },
        toUndefined = match(constUndefined, function_identity),
        es6_Option_map = function (f) {
          return function (fa) {
            return isNone(fa) ? none : some(f(fa.value))
          }
        },
        chain = function (f) {
          return function (ma) {
            return isNone(ma) ? none : f(ma.value)
          }
        },
        alt = function (that) {
          return function (fa) {
            return isNone(fa) ? that() : fa
          }
        },
        filter = function (predicate) {
          return function (fa) {
            return isNone(fa) ? none : predicate(fa.value) ? fa : none
          }
        }
      function getEq(E) {
        return {
          equals: function (x, y) {
            return (
              x === y ||
              (isNone(x) ? isNone(y) : !isNone(y) && E.equals(x.value, y.value))
            )
          },
        }
      }
      const external_log_namespaceObject = log
      var external_log_default = __webpack_require__.n(
        external_log_namespaceObject
      )
      const lib = observer => value => {
        observer.next(value)
      }
      function sleep(time) {
        return (
          time || (time = 0),
          new Promise(function (res) {
            return setTimeout(res, time)
          })
        )
      }
      function randomToken() {
        return Math.random().toString(36).substring(2)
      }
      var lastMs = 0,
        additional = 0
      function microSeconds() {
        var ms = new Date().getTime()
        return ms === lastMs
          ? 1e3 * ms + ++additional
          : ((lastMs = ms), (additional = 0), 1e3 * ms)
      }
      var isNode =
        "[object process]" ===
        Object.prototype.toString.call(
          "undefined" != typeof process ? process : 0
        )
      const methods_native = {
        create: function (channelName) {
          var state = {
            messagesCallback: null,
            bc: new BroadcastChannel(channelName),
            subFns: [],
          }
          return (
            (state.bc.onmessage = function (msg) {
              state.messagesCallback && state.messagesCallback(msg.data)
            }),
            state
          )
        },
        close: function (channelState) {
          channelState.bc.close(), (channelState.subFns = [])
        },
        onMessage: function (channelState, fn) {
          channelState.messagesCallback = fn
        },
        postMessage: function (channelState, messageJson) {
          try {
            return (
              channelState.bc.postMessage(messageJson, !1), Promise.resolve()
            )
          } catch (err) {
            return Promise.reject(err)
          }
        },
        canBeUsed: function () {
          if (isNode && "undefined" == typeof window) return !1
          if ("function" == typeof BroadcastChannel) {
            if (BroadcastChannel._pubkey)
              throw new Error(
                "BroadcastChannel: Do not overwrite window.BroadcastChannel with this module, this is not a polyfill"
              )
            return !0
          }
          return !1
        },
        type: "native",
        averageResponseTime: function () {
          return 150
        },
        microSeconds,
      }
      function now() {
        return new Date().getTime()
      }
      const oblivious_set = function (ttl) {
        var set = new Set(),
          timeMap = new Map()
        ;(this.has = set.has.bind(set)),
          (this.add = function (value) {
            timeMap.set(value, now()),
              set.add(value),
              (function () {
                var olderThen = now() - ttl,
                  iterator = set[Symbol.iterator]()
                for (;;) {
                  var value = iterator.next().value
                  if (!value) return
                  if (!(timeMap.get(value) < olderThen)) return
                  timeMap.delete(value), set.delete(value)
                }
              })()
          }),
          (this.clear = function () {
            set.clear(), timeMap.clear()
          })
      }
      function options_fillOptionsWithDefaults() {
        var originalOptions =
            arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {},
          options = JSON.parse(JSON.stringify(originalOptions))
        return (
          void 0 === options.webWorkerSupport &&
            (options.webWorkerSupport = !0),
          options.idb || (options.idb = {}),
          options.idb.ttl || (options.idb.ttl = 45e3),
          options.idb.fallbackInterval || (options.idb.fallbackInterval = 150),
          originalOptions.idb &&
            "function" == typeof originalOptions.idb.onclose &&
            (options.idb.onclose = originalOptions.idb.onclose),
          options.localstorage || (options.localstorage = {}),
          options.localstorage.removeTimeout ||
            (options.localstorage.removeTimeout = 6e4),
          originalOptions.methods &&
            (options.methods = originalOptions.methods),
          options.node || (options.node = {}),
          options.node.ttl || (options.node.ttl = 12e4),
          void 0 === options.node.useFastPath &&
            (options.node.useFastPath = !0),
          options
        )
      }
      function getIdb() {
        if ("undefined" != typeof indexedDB) return indexedDB
        if ("undefined" != typeof window) {
          if (void 0 !== window.mozIndexedDB) return window.mozIndexedDB
          if (void 0 !== window.webkitIndexedDB) return window.webkitIndexedDB
          if (void 0 !== window.msIndexedDB) return window.msIndexedDB
        }
        return !1
      }
      function getMessagesHigherThan(db, lastCursorId) {
        var objectStore = db.transaction("messages").objectStore("messages"),
          ret = []
        return new Promise(function (res) {
          ;(function () {
            try {
              var keyRangeValue = IDBKeyRange.bound(lastCursorId + 1, 1 / 0)
              return objectStore.openCursor(keyRangeValue)
            } catch (e) {
              return objectStore.openCursor()
            }
          })().onsuccess = function (ev) {
            var cursor = ev.target.result
            cursor
              ? cursor.value.id < lastCursorId + 1
                ? cursor.continue(lastCursorId + 1)
                : (ret.push(cursor.value), cursor.continue())
              : res(ret)
          }
        })
      }
      function cleanOldMessages(db, ttl) {
        return (function (db, ttl) {
          var olderThen = new Date().getTime() - ttl,
            objectStore = db.transaction("messages").objectStore("messages"),
            ret = []
          return new Promise(function (res) {
            objectStore.openCursor().onsuccess = function (ev) {
              var cursor = ev.target.result
              if (cursor) {
                var msgObk = cursor.value
                if (!(msgObk.time < olderThen)) return void res(ret)
                ret.push(msgObk), cursor.continue()
              } else res(ret)
            }
          })
        })(db, ttl).then(function (tooOld) {
          return Promise.all(
            tooOld.map(function (msgObj) {
              return (function (db, id) {
                var request = db
                  .transaction(["messages"], "readwrite")
                  .objectStore("messages")
                  .delete(id)
                return new Promise(function (res) {
                  request.onsuccess = function () {
                    return res()
                  }
                })
              })(db, msgObj.id)
            })
          )
        })
      }
      function _readLoop(state) {
        state.closed ||
          readNewMessages(state)
            .then(function () {
              return sleep(state.options.idb.fallbackInterval)
            })
            .then(function () {
              return _readLoop(state)
            })
      }
      function readNewMessages(state) {
        return state.closed
          ? Promise.resolve()
          : state.messagesCallback
          ? getMessagesHigherThan(state.db, state.lastCursorId).then(function (
              newerMessages
            ) {
              return (
                newerMessages
                  .filter(function (msgObj) {
                    return !!msgObj
                  })
                  .map(function (msgObj) {
                    return (
                      msgObj.id > state.lastCursorId &&
                        (state.lastCursorId = msgObj.id),
                      msgObj
                    )
                  })
                  .filter(function (msgObj) {
                    return (function (msgObj, state) {
                      return !(
                        msgObj.uuid === state.uuid ||
                        state.eMIs.has(msgObj.id) ||
                        msgObj.data.time < state.messagesCallbackTime
                      )
                    })(msgObj, state)
                  })
                  .sort(function (msgObjA, msgObjB) {
                    return msgObjA.time - msgObjB.time
                  })
                  .forEach(function (msgObj) {
                    state.messagesCallback &&
                      (state.eMIs.add(msgObj.id),
                      state.messagesCallback(msgObj.data))
                  }),
                Promise.resolve()
              )
            })
          : Promise.resolve()
      }
      const indexed_db = {
        create: function (channelName, options) {
          return (
            (options = options_fillOptionsWithDefaults(options)),
            (function (channelName) {
              var dbName = "pubkey.broadcast-channel-0-" + channelName,
                openRequest = getIdb().open(dbName, 1)
              return (
                (openRequest.onupgradeneeded = function (ev) {
                  ev.target.result.createObjectStore("messages", {
                    keyPath: "id",
                    autoIncrement: !0,
                  })
                }),
                new Promise(function (res, rej) {
                  ;(openRequest.onerror = function (ev) {
                    return rej(ev)
                  }),
                    (openRequest.onsuccess = function () {
                      res(openRequest.result)
                    })
                })
              )
            })(channelName).then(function (db) {
              var state = {
                closed: !1,
                lastCursorId: 0,
                channelName,
                options,
                uuid: randomToken(),
                eMIs: new oblivious_set(2 * options.idb.ttl),
                writeBlockPromise: Promise.resolve(),
                messagesCallback: null,
                readQueuePromises: [],
                db,
              }
              return (
                (db.onclose = function () {
                  ;(state.closed = !0),
                    options.idb.onclose && options.idb.onclose()
                }),
                _readLoop(state),
                state
              )
            })
          )
        },
        close: function (channelState) {
          ;(channelState.closed = !0), channelState.db.close()
        },
        onMessage: function (channelState, fn, time) {
          ;(channelState.messagesCallbackTime = time),
            (channelState.messagesCallback = fn),
            readNewMessages(channelState)
        },
        postMessage: function (channelState, messageJson) {
          return (
            (channelState.writeBlockPromise = channelState.writeBlockPromise
              .then(function () {
                return (function (db, readerUuid, messageJson) {
                  var writeObject = {
                      uuid: readerUuid,
                      time: new Date().getTime(),
                      data: messageJson,
                    },
                    transaction = db.transaction(["messages"], "readwrite")
                  return new Promise(function (res, rej) {
                    ;(transaction.oncomplete = function () {
                      return res()
                    }),
                      (transaction.onerror = function (ev) {
                        return rej(ev)
                      }),
                      transaction.objectStore("messages").add(writeObject)
                  })
                })(channelState.db, channelState.uuid, messageJson)
              })
              .then(function () {
                0 ===
                  (function (min, max) {
                    return Math.floor(Math.random() * (max - min + 1) + min)
                  })(0, 10) &&
                  cleanOldMessages(
                    channelState.db,
                    channelState.options.idb.ttl
                  )
              })),
            channelState.writeBlockPromise
          )
        },
        canBeUsed: function () {
          return !isNode && !!getIdb()
        },
        type: "idb",
        averageResponseTime: function (options) {
          return 2 * options.idb.fallbackInterval
        },
        microSeconds,
      }
      function getLocalStorage() {
        var localStorage
        if ("undefined" == typeof window) return null
        try {
          ;(localStorage = window.localStorage),
            (localStorage =
              window["ie8-eventlistener/storage"] || window.localStorage)
        } catch (e) {}
        return localStorage
      }
      function storageKey(channelName) {
        return "pubkey.broadcastChannel-" + channelName
      }
      function localstorage_canBeUsed() {
        if (isNode) return !1
        var ls = getLocalStorage()
        if (!ls) return !1
        try {
          var key = "__broadcastchannel_check"
          ls.setItem(key, "works"), ls.removeItem(key)
        } catch (e) {
          return !1
        }
        return !0
      }
      const localstorage = {
        create: function (channelName, options) {
          if (
            ((options = options_fillOptionsWithDefaults(options)),
            !localstorage_canBeUsed())
          )
            throw new Error("BroadcastChannel: localstorage cannot be used")
          var uuid = randomToken(),
            eMIs = new oblivious_set(options.localstorage.removeTimeout),
            state = { channelName, uuid, eMIs }
          return (
            (state.listener = (function (channelName, fn) {
              var key = storageKey(channelName),
                listener = function (ev) {
                  ev.key === key && fn(JSON.parse(ev.newValue))
                }
              return window.addEventListener("storage", listener), listener
            })(channelName, function (msgObj) {
              state.messagesCallback &&
                msgObj.uuid !== uuid &&
                msgObj.token &&
                !eMIs.has(msgObj.token) &&
                ((msgObj.data.time &&
                  msgObj.data.time < state.messagesCallbackTime) ||
                  (eMIs.add(msgObj.token), state.messagesCallback(msgObj.data)))
            })),
            state
          )
        },
        close: function (channelState) {
          var listener
          ;(listener = channelState.listener),
            window.removeEventListener("storage", listener)
        },
        onMessage: function (channelState, fn, time) {
          ;(channelState.messagesCallbackTime = time),
            (channelState.messagesCallback = fn)
        },
        postMessage: function (channelState, messageJson) {
          return new Promise(function (res) {
            sleep().then(function () {
              var key = storageKey(channelState.channelName),
                writeObj = {
                  token: randomToken(),
                  time: new Date().getTime(),
                  data: messageJson,
                  uuid: channelState.uuid,
                },
                value = JSON.stringify(writeObj)
              getLocalStorage().setItem(key, value)
              var ev = document.createEvent("Event")
              ev.initEvent("storage", !0, !0),
                (ev.key = key),
                (ev.newValue = value),
                window.dispatchEvent(ev),
                res()
            })
          })
        },
        canBeUsed: localstorage_canBeUsed,
        type: "localstorage",
        averageResponseTime: function () {
          var userAgent = navigator.userAgent.toLowerCase()
          return userAgent.includes("safari") && !userAgent.includes("chrome")
            ? 240
            : 120
        },
        microSeconds,
      }
      var simulate_microSeconds = microSeconds,
        SIMULATE_CHANNELS = new Set()
      const simulate = {
        create: function (channelName) {
          var state = { name: channelName, messagesCallback: null }
          return SIMULATE_CHANNELS.add(state), state
        },
        close: function (channelState) {
          SIMULATE_CHANNELS.delete(channelState)
        },
        onMessage: function (channelState, fn) {
          channelState.messagesCallback = fn
        },
        postMessage: function (channelState, messageJson) {
          return new Promise(function (res) {
            return setTimeout(function () {
              Array.from(SIMULATE_CHANNELS)
                .filter(function (channel) {
                  return channel.name === channelState.name
                })
                .filter(function (channel) {
                  return channel !== channelState
                })
                .filter(function (channel) {
                  return !!channel.messagesCallback
                })
                .forEach(function (channel) {
                  return channel.messagesCallback(messageJson)
                }),
                res()
            }, 5)
          })
        },
        canBeUsed: function () {
          return !0
        },
        type: "simulate",
        averageResponseTime: function () {
          return 5
        },
        microSeconds: simulate_microSeconds,
      }
      var METHODS = [methods_native, indexed_db, localstorage]
      if (isNode) {
        var NodeMethod = __webpack_require__(815)
        "function" == typeof NodeMethod.canBeUsed && METHODS.push(NodeMethod)
      }
      var ENFORCED_OPTIONS,
        broadcast_channel_BroadcastChannel = function (name, options) {
          var channel, maybePromise, obj
          ;(this.name = name),
            ENFORCED_OPTIONS && (options = ENFORCED_OPTIONS),
            (this.options = options_fillOptionsWithDefaults(options)),
            (this.method = (function (options) {
              var chooseMethods = []
                .concat(options.methods, METHODS)
                .filter(Boolean)
              if (options.type) {
                if ("simulate" === options.type) return simulate
                var ret = chooseMethods.find(function (m) {
                  return m.type === options.type
                })
                if (ret) return ret
                throw new Error("method-type " + options.type + " not found")
              }
              options.webWorkerSupport ||
                isNode ||
                (chooseMethods = chooseMethods.filter(function (m) {
                  return "idb" !== m.type
                }))
              var useMethod = chooseMethods.find(function (method) {
                return method.canBeUsed()
              })
              if (useMethod) return useMethod
              throw new Error(
                "No useable methode found:" +
                  JSON.stringify(
                    METHODS.map(function (m) {
                      return m.type
                    })
                  )
              )
            })(this.options)),
            (this._iL = !1),
            (this._onML = null),
            (this._addEL = { message: [], internal: [] }),
            (this._uMP = new Set()),
            (this._befC = []),
            (this._prepP = null),
            (maybePromise = (channel = this).method.create(
              channel.name,
              channel.options
            )),
            (obj = maybePromise) && "function" == typeof obj.then
              ? ((channel._prepP = maybePromise),
                maybePromise.then(function (s) {
                  channel._state = s
                }))
              : (channel._state = maybePromise)
        }
      function _post(broadcastChannel, type, msg) {
        var msgObj = {
          time: broadcastChannel.method.microSeconds(),
          type,
          data: msg,
        }
        return (broadcastChannel._prepP
          ? broadcastChannel._prepP
          : Promise.resolve()
        ).then(function () {
          var sendPromise = broadcastChannel.method.postMessage(
            broadcastChannel._state,
            msgObj
          )
          return (
            broadcastChannel._uMP.add(sendPromise),
            sendPromise.catch().then(function () {
              return broadcastChannel._uMP.delete(sendPromise)
            }),
            sendPromise
          )
        })
      }
      function _hasMessageListeners(channel) {
        return (
          channel._addEL.message.length > 0 ||
          channel._addEL.internal.length > 0
        )
      }
      function _addListenerObject(channel, type, obj) {
        channel._addEL[type].push(obj),
          (function (channel) {
            if (!channel._iL && _hasMessageListeners(channel)) {
              var listenerFn = function (msgObj) {
                  channel._addEL[msgObj.type].forEach(function (obj) {
                    msgObj.time >= obj.time && obj.fn(msgObj.data)
                  })
                },
                time = channel.method.microSeconds()
              channel._prepP
                ? channel._prepP.then(function () {
                    ;(channel._iL = !0),
                      channel.method.onMessage(channel._state, listenerFn, time)
                  })
                : ((channel._iL = !0),
                  channel.method.onMessage(channel._state, listenerFn, time))
            }
          })(channel)
      }
      function _removeListenerObject(channel, type, obj) {
        ;(channel._addEL[type] = channel._addEL[type].filter(function (o) {
          return o !== obj
        })),
          (function (channel) {
            if (channel._iL && !_hasMessageListeners(channel)) {
              channel._iL = !1
              var time = channel.method.microSeconds()
              channel.method.onMessage(channel._state, null, time)
            }
          })(channel)
      }
      ;(broadcast_channel_BroadcastChannel._pubkey = !0),
        (broadcast_channel_BroadcastChannel.prototype = {
          postMessage: function (msg) {
            if (this.closed)
              throw new Error(
                "BroadcastChannel.postMessage(): Cannot post message after channel has closed"
              )
            return _post(this, "message", msg)
          },
          postInternal: function (msg) {
            return _post(this, "internal", msg)
          },
          set onmessage(fn) {
            var listenObj = { time: this.method.microSeconds(), fn }
            _removeListenerObject(this, "message", this._onML),
              fn && "function" == typeof fn
                ? ((this._onML = listenObj),
                  _addListenerObject(this, "message", listenObj))
                : (this._onML = null)
          },
          addEventListener: function (type, fn) {
            _addListenerObject(this, type, {
              time: this.method.microSeconds(),
              fn,
            })
          },
          removeEventListener: function (type, fn) {
            _removeListenerObject(
              this,
              type,
              this._addEL[type].find(function (obj) {
                return obj.fn === fn
              })
            )
          },
          close: function () {
            var _this = this
            if (!this.closed) {
              this.closed = !0
              var awaitPrepare = this._prepP ? this._prepP : Promise.resolve()
              return (
                (this._onML = null),
                (this._addEL.message = []),
                awaitPrepare
                  .then(function () {
                    return Promise.all(Array.from(_this._uMP))
                  })
                  .then(function () {
                    return Promise.all(
                      _this._befC.map(function (fn) {
                        return fn()
                      })
                    )
                  })
                  .then(function () {
                    return _this.method.close(_this._state)
                  })
              )
            }
          },
          get type() {
            return this.method.type
          },
        })
      const external_DeepDiff_namespaceObject = DeepDiff,
        external_jsep_namespaceObject = jsep
      var external_jsep_default = __webpack_require__.n(
          external_jsep_namespaceObject
        ),
        u = {
          "||": function (e, r) {
            return e || r
          },
          "&&": function (e, r) {
            return e && r
          },
          "|": function (e, r) {
            return e | r
          },
          "^": function (e, r) {
            return e ^ r
          },
          "&": function (e, r) {
            return e & r
          },
          "==": function (e, r) {
            return e == r
          },
          "!=": function (e, r) {
            return e != r
          },
          "===": function (e, r) {
            return e === r
          },
          "!==": function (e, r) {
            return e !== r
          },
          "<": function (e, r) {
            return e < r
          },
          ">": function (e, r) {
            return e > r
          },
          "<=": function (e, r) {
            return e <= r
          },
          ">=": function (e, r) {
            return e >= r
          },
          "<<": function (e, r) {
            return e << r
          },
          ">>": function (e, r) {
            return e >> r
          },
          ">>>": function (e, r) {
            return e >>> r
          },
          "+": function (e, r) {
            return e + r
          },
          "-": function (e, r) {
            return e - r
          },
          "*": function (e, r) {
            return e * r
          },
          "/": function (e, r) {
            return e / r
          },
          "%": function (e, r) {
            return e % r
          },
        },
        i = {
          "-": function (e) {
            return -e
          },
          "+": function (e) {
            return +e
          },
          "~": function (e) {
            return ~e
          },
          "!": function (e) {
            return !e
          },
        }
      function s(e, r) {
        return e.map(function (e) {
          return a(e, r)
        })
      }
      function c(e, r) {
        var n = a(e.object, r)
        return e.computed ? [n, n[a(e.property, r)]] : [n, n[e.property.name]]
      }
      function a(e, r) {
        var n = e
        switch (n.type) {
          case "ArrayExpression":
            return s(n.elements, r)
          case "BinaryExpression":
            return u[n.operator](a(n.left, r), a(n.right, r))
          case "CallExpression":
            var t, o, l
            if (
              ("MemberExpression" === n.callee.type
                ? ((t = (l = c(n.callee, r))[0]), (o = l[1]))
                : (o = a(n.callee, r)),
              "function" != typeof o)
            )
              return
            return o.apply(t, s(n.arguments, r))
          case "ConditionalExpression":
            return a(n.test, r) ? a(n.consequent, r) : a(n.alternate, r)
          case "Identifier":
            return r[n.name]
          case "Literal":
            return n.value
          case "LogicalExpression":
            return "||" === n.operator
              ? a(n.left, r) || a(n.right, r)
              : "&&" === n.operator
              ? a(n.left, r) && a(n.right, r)
              : u[n.operator](a(n.left, r), a(n.right, r))
          case "MemberExpression":
            return c(n, r)[1]
          case "ThisExpression":
            return r
          case "UnaryExpression":
            return i[n.operator](a(n.argument, r))
          default:
            return
        }
      }
      var eqStrict = {
          equals: function (a, b) {
            return a === b
          },
        },
        eqString = eqStrict,
        IO_map = function (ma, f) {
          return function () {
            return f(ma())
          }
        },
        IO_of = constant,
        IO_Functor = { URI: "IO", map: IO_map },
        IO_sequenceArray =
          (flap(IO_Functor),
          (function (f) {
            return (function (f) {
              return function (as) {
                return function () {
                  return as.map(function (a, i) {
                    return f(i, a)()
                  })
                }
              }
            })(function (_, a) {
              return f(a)
            })
          })(function_identity)),
        ReadonlyNonEmptyArray_empty = [],
        isNonEmpty = function (as) {
          return as.length > 0
        },
        append = function (end) {
          return function (init) {
            return concat(init, [end])
          }
        },
        uniq = function (E) {
          return function (as) {
            if (1 === as.length) return as
            for (
              var out = [head(as)],
                _loop_1 = function (a) {
                  out.every(function (o) {
                    return !E.equals(o, a)
                  }) && out.push(a)
                },
                _i = 0,
                rest_1 = tail(as);
              _i < rest_1.length;
              _i++
            ) {
              _loop_1(rest_1[_i])
            }
            return out
          }
        }
      function concat(first, second) {
        return first.concat(second)
      }
      var ReadonlyNonEmptyArray_map = function (fa, f) {
          return function_pipe(fa, es6_ReadonlyNonEmptyArray_map(f))
        },
        es6_ReadonlyNonEmptyArray_map = function (f) {
          return mapWithIndex(function (_, a) {
            return f(a)
          })
        },
        mapWithIndex = function (f) {
          return function (as) {
            for (var out = [f(0, head(as))], i = 1; i < as.length; i++)
              out.push(f(i, as[i]))
            return out
          }
        },
        extract = function (as) {
          return as[0]
        },
        ReadonlyNonEmptyArray_Functor = {
          URI: "ReadonlyNonEmptyArray",
          map: ReadonlyNonEmptyArray_map,
        },
        head = (flap(ReadonlyNonEmptyArray_Functor), extract),
        tail = function (as) {
          return as.slice(1)
        }
      var ReadonlyArray_append = append,
        isEmpty = function (as) {
          return 0 === as.length
        },
        ReadonlyArray_isNonEmpty = isNonEmpty
      var ReadonlyArray_map = function (fa, f) {
          return function_pipe(fa, es6_ReadonlyArray_map(f))
        },
        es6_ReadonlyArray_chain = function (f) {
          return function (ma) {
            return function_pipe(
              ma,
              (function (f) {
                return function (as) {
                  if (isEmpty(as)) return ReadonlyArray_empty
                  for (var out = [], i = 0; i < as.length; i++)
                    out.push.apply(out, f(i, as[i]))
                  return out
                }
              })(function (_, a) {
                return f(a)
              })
            )
          }
        },
        es6_ReadonlyArray_map = function (f) {
          return function (fa) {
            return fa.map(function (a) {
              return f(a)
            })
          }
        },
        es6_ReadonlyArray_filter = function (predicate) {
          return function (fa) {
            return fa.filter(predicate)
          }
        },
        filterMapWithIndex = function (f) {
          return function (fa) {
            for (var out = [], i = 0; i < fa.length; i++) {
              var optionB = f(i, fa[i])
              Option_isSome(optionB) && out.push(optionB.value)
            }
            return out
          }
        },
        es6_ReadonlyArray_filterMap = function (f) {
          return filterMapWithIndex(function (_, a) {
            return f(a)
          })
        },
        ReadonlyArray_compact = es6_ReadonlyArray_filterMap(function_identity),
        ReadonlyArray_Functor = {
          URI: "ReadonlyArray",
          map: ReadonlyArray_map,
        },
        toArray =
          (flap(ReadonlyArray_Functor),
          function (as) {
            return as.slice()
          }),
        ReadonlyArray_empty = ReadonlyNonEmptyArray_empty,
        ReadonlyArray_some = function (predicate) {
          return function (as) {
            return as.some(predicate)
          }
        }
      const external_m_namespaceObject = m
      var external_m_default = __webpack_require__.n(external_m_namespaceObject)
      const external_rxjs_namespaceObject = rxjs,
        external_rxjs_operators_namespaceObject = rxjs.operators,
        package_namespaceObject_i8 = "1.15.0",
        indirectConfig = async (gmKey, defaultVal, toItem, toGm) => {
          const val = await GM.getValue(gmKey)
          return {
            gmKey,
            val: void 0 !== val ? toItem(val) : defaultVal,
            defaultVal,
            toGm,
          }
        },
        simpleConfig = async (gmKey, defaultVal) => {
          var _a
          return {
            gmKey,
            val:
              null !== (_a = await GM.getValue(gmKey)) && void 0 !== _a
                ? _a
                : defaultVal,
            defaultVal,
            toGm: x => x,
          }
        },
        lineConfigArgs = [
          [],
          x => x.split(/\r\n|\n/).filter(s => "" !== s),
          x => x.join("\n"),
        ],
        chatApp = () =>
          function_pipe(
            fromNullable(document.querySelector("#chatframe")),
            filter(x => {
              var _a
              const state =
                null === (_a = x.contentDocument) || void 0 === _a
                  ? void 0
                  : _a.readyState
              return "loading" === state || "complete" === state
            }),
            chainNullableK(x => x.contentDocument),
            alt(() => some(document)),
            chainNullableK(x => x.querySelector("yt-live-chat-app"))
          ),
        mountComponent = x => {
          ;(x.root.style.display = "contents"),
            external_m_default().mount(x.root, x.comp)
        }
      var semigroupVoid = (function (a) {
          return {
            concat: function () {
              return a
            },
          }
        })(void 0),
        Semigroup_concatAll = function (S) {
          return function (startWith) {
            return function (as) {
              return as.reduce(S.concat, startWith)
            }
          }
        }
      semigroupVoid.concat
      var Monoid_concatAll = function (M) {
          return Semigroup_concatAll(M)(M.empty)
        },
        monoidAll = {
          concat: function (x, y) {
            return x && y
          },
          empty: !0,
        },
        monoidAny = {
          concat: function (x, y) {
            return x || y
          },
          empty: !1,
        }
      var Eq = eqString
      const external_Swal_namespaceObject = Swal
      var external_Swal_default = __webpack_require__.n(
        external_Swal_namespaceObject
      )
      const addBanButton_button = document.createElement("button")
      addBanButton_button.classList.add(
        "style-scope",
        "yt-icon-button",
        "fyc_button",
        "fyc_ngbutton"
      ),
        (addBanButton_button.style.padding = "0px"),
        (addBanButton_button.style.width = "20px"),
        (addBanButton_button.style.height = "20px"),
        (addBanButton_button.style.fill = "#fff"),
        addBanButton_button.setAttribute(
          "aria-label",
          "NGに入れる(Ban this user)"
        ),
        (addBanButton_button.innerHTML =
          '<svg class="style-scope yt-icon" style="width: 100%; height: 75%; fill: var(--yt-spec-text-secondary);" viewBox="0 0 512 512"><path d="M440 78A256 256 0 1 0 73 435 256 256 0 0 0 440 78zm-99 35L113 341C37 179 212 44 341 113zM177 405l228-228c76 162-99 297-228 228z" fill-rule="evenodd"/></svg>')
      const addBanButton = (chat, id, getConfig, setConfig) => {
          var _a
          if (chat.children.namedItem("card")) return
          const buttonClone = addBanButton_button.cloneNode(!0)
          ;(buttonClone.onclick = () => {
            const users = getConfig.bannedUsers()
            users.includes(id) ||
              (setConfig.bannedUsers(
                function_pipe(
                  users,
                  (function (E) {
                    var f = uniq(E)
                    return function (as) {
                      return ReadonlyArray_isNonEmpty(as) ? f(as) : as
                    }
                  })(Eq),
                  ReadonlyArray_append(id),
                  toArray
                )
              ),
              external_m_default().redraw(),
              external_Swal_default()
                .mixin({
                  toast: !0,
                  position: "bottom-left",
                  timer: 2500,
                  timerProgressBar: !0,
                  showConfirmButton: !1,
                  didOpen: toast => {
                    toast.addEventListener(
                      "mouseenter",
                      external_Swal_default().stopTimer
                    ),
                      toast.addEventListener(
                        "mouseleave",
                        external_Swal_default().resumeTimer
                      )
                  },
                })
                .fire({ title: `Added Banned User: ${id}`, icon: "success" })),
              (chat.style.display = "none")
          }),
            null === (_a = chat.querySelector("#content #message")) ||
              void 0 === _a ||
              _a.append(buttonClone)
        },
        textStyle = { fontFamily: "inherit" },
        chatNode = (data, getConfig) =>
          function_pipe(
            [
              function_pipe(
                data.authorName,
                filter(x => x.visible),
                es6_Option_map(x =>
                  external_m_default()(
                    "span",
                    {
                      style: {
                        color: toUndefined(data.textColor),
                        fontSize: "smaller",
                        ...textStyle,
                      },
                    },
                    `${x.content}: `
                  )
                )
              ),
              function_pipe(
                data.message,
                es6_Option_map(x =>
                  ((message, getConfig) => {
                    var _a
                    const eleWin =
                        null !== (_a = message.ownerDocument.defaultView) &&
                        void 0 !== _a
                          ? _a
                          : window,
                      maxChatLength = getConfig.maxChatLength(),
                      vnodes = []
                    let length = 0
                    return (
                      Array.from(message.childNodes).some(node => {
                        var _a, _b
                        if (
                          !getConfig.textOnly() &&
                          node instanceof eleWin.HTMLImageElement
                        ) {
                          const { src, alt } = node
                          vnodes.push(
                            external_m_default()("img", {
                              style: { height: "1em", width: "1em" },
                              src,
                              alt,
                            })
                          ),
                            (length += 1)
                        } else if (node instanceof eleWin.HTMLAnchorElement) {
                          const beginning = (null !== (_a = node.textContent) &&
                          void 0 !== _a
                            ? _a
                            : ""
                          ).slice(0, maxChatLength)
                          vnodes.push(
                            external_m_default()(
                              "span",
                              {
                                style: {
                                  fontSize: "smaller",
                                  textDecoration: "underline",
                                  ...textStyle,
                                },
                              },
                              beginning
                            )
                          ),
                            (length += beginning.length)
                        } else {
                          const beginning = (null !== (_b = node.textContent) &&
                          void 0 !== _b
                            ? _b
                            : ""
                          ).slice(0, maxChatLength)
                          vnodes.push(
                            external_m_default().fragment({}, beginning)
                          ),
                            (length += beginning.length)
                        }
                        return length >= maxChatLength
                      }),
                      { vnodes, length }
                    )
                  })(x, getConfig)
                ),
                es6_Option_map(x =>
                  external_m_default()(
                    "span",
                    {
                      style: {
                        color: toUndefined(data.textColor),
                        ...textStyle,
                      },
                    },
                    x.vnodes
                  )
                )
              ),
              function_pipe(
                data.paymentInfo,
                filter(x => x.visible),
                es6_Option_map(x =>
                  external_m_default()(
                    "span",
                    {
                      style: {
                        color: toUndefined(data.paidColor),
                        fontSize: "smaller",
                        ...textStyle,
                      },
                    },
                    external_m_default()(
                      "strong",
                      { style: textStyle },
                      x.content
                    )
                  )
                )
              ),
            ],
            ReadonlyArray_compact
          ),
        external_window_hash_it_namespaceObject = window["hash-it"]
      var external_window_hash_it_default = __webpack_require__.n(
        external_window_hash_it_namespaceObject
      )
      const external_window_micro_memoize_namespaceObject =
        window["micro-memoize"]
      var external_window_micro_memoize_default = __webpack_require__.n(
        external_window_micro_memoize_namespaceObject
      )
      const getFlowChatProgress = chat => {
          var _a, _b
          return (
            (null !==
              (_b =
                null === (_a = chat.animation) || void 0 === _a
                  ? void 0
                  : _a.currentTime) && void 0 !== _b
              ? _b
              : 0) / chat.animationDuration
          )
        },
        getFlowChatRect = (chat, mainState) => {
          const x =
            mainState.playerRect.width -
            (chat.width + mainState.playerRect.width) *
              getFlowChatProgress(chat)
          return new DOMRect(x, chat.y, chat.width, chat.height)
        },
        getChatLane = (flowChat, progress, flowChats, mainState, getConfig) => {
          const playerWidth = mainState.playerRect.width,
            chatRect = getFlowChatRect(flowChat, mainState),
            chatWidth = chatRect.width,
            chatHeight = chatRect.height,
            chatX = chatRect.x,
            chatIndex = flowChats.indexOf(flowChat),
            movingChats =
              ((as = flowChats
                .slice(0, chatIndex >= 0 ? chatIndex : void 0)
                .filter(chat => !chat.animationEnded)
                .sort((a, b) => a.lane - b.lane)),
              isEmpty(as) ? ReadonlyArray_empty : as.slice())
          var as
          const tooCloseTo = external_window_micro_memoize_default()(
              i => {
                const otherRect = getFlowChatRect(movingChats[i], mainState),
                  otherWidth = otherRect.width,
                  otherX = otherRect.x,
                  gap =
                    (chatHeight * otherWidth * chatWidth) ** 0.333 *
                    getConfig.minSpacing()
                return (
                  (playerWidth - otherX) / (playerWidth + otherWidth) -
                    progress <
                    (chatWidth + gap) / (playerWidth + chatWidth) ||
                  otherX + otherWidth + gap > chatX
                )
              },
              { maxSize: 1e3 }
            ),
            occupyInfo = [
              ...movingChats.map((x, i) => ({
                tooClose: () => tooCloseTo(i),
                lane: x.lane,
              })),
              { tooClose: () => !0, lane: getConfig.laneCount() },
            ],
            index = occupyInfo.findIndex(x => x.lane >= flowChat.lane),
            rightFreeLane = occupyInfo
              .slice(index)
              .findIndex(x => x.tooClose()),
            leftFreeLane = function_pipe(
              occupyInfo.slice(0, index),
              ((predicate = x => x.tooClose()),
              function (as) {
                for (var i = as.length - 1; i >= 0; i--)
                  if (predicate(as[i])) return some(i)
                return none
              }),
              getOrElse(() => -1)
            )
          var predicate
          let formerLaneInterval = 0
          leftFreeLane < flowChat.lane &&
            flowChat.lane < rightFreeLane &&
            (formerLaneInterval = Math.min(
              Math.max(
                formerLaneInterval,
                Math.min(
                  flowChat.lane - leftFreeLane,
                  rightFreeLane - flowChat.lane
                )
              ),
              1
            ))
          let maxInterval = 0,
            maxIntervalLane = 0,
            lastLane = -1
          for (let i = 0; i < occupyInfo.length; i += 1)
            if (occupyInfo[i].tooClose()) {
              const nextLane = occupyInfo[i].lane,
                interLane = Math.min(
                  Math.max((lastLane + nextLane) / 2, 0),
                  getConfig.laneCount() - 1
                ),
                newInterval = Math.min(
                  interLane - lastLane,
                  nextLane - interLane,
                  1
                )
              if (
                newInterval - maxInterval > 0.001 &&
                ((maxIntervalLane = Math.max(lastLane + newInterval, 0)),
                (maxInterval = newInterval),
                maxInterval > 0.999)
              )
                break
              lastLane = nextLane
            }
          return {
            lane:
              Math.abs(formerLaneInterval - maxInterval) < 0.001
                ? flowChat.lane
                : maxIntervalLane,
            interval: maxInterval,
          }
        },
        setChatPlayState = (flowChat, mainState, getConfig) => {
          !flowChat.animationEnded &&
            flowChat.animation &&
            (mainState.chatPlaying
              ? flowChat.animation.play()
              : flowChat.animation.pause(),
            (flowChat.animation.playbackRate = getConfig.flowSpeed() / 15))
        },
        getSize = external_window_micro_memoize_default()(
          ele => {
            const rect = ele.getBoundingClientRect()
            return [rect.width, rect.height]
          },
          {
            maxSize: 2e3,
            transformKey: args => args.map(external_window_hash_it_default()),
          }
        ),
        setChatAnimation = (chat, chats, mainState, getConfig) => {
          var _a
          if (chat.animationEnded) return !1
          if (((chat.animationDuration = 6400), !chat.animation)) {
            ;(chat.width = 2), (chat.height = 2)
            const { interval } = getChatLane(
              chat,
              0,
              chats,
              mainState,
              getConfig
            )
            if (getConfig.noOverlap() && interval < 0.999) return !1
          }
          ;[chat.width, chat.height] = getSize(chat.element)
          const progress = getFlowChatProgress(chat),
            { lane, interval } = getChatLane(
              chat,
              progress,
              chats,
              mainState,
              getConfig
            )
          if (getConfig.noOverlap() && interval < 0.999)
            return (
              null === (_a = chat.animation) || void 0 === _a || _a.finish(),
              (chat.animation = void 0),
              !1
            )
          chat.lane = lane
          const laneY = ((lane, mainState, getConfig) => {
            const laneCount = getConfig.laneCount(),
              laneR = lane % (2 * laneCount - 1),
              playerHeight = mainState.playerRect.height
            return (
              Math.round(
                100 *
                  (laneR < laneCount
                    ? (playerHeight * (laneR % laneCount)) / laneCount + 4
                    : playerHeight *
                      ((laneR % laneCount) / laneCount + 1 / (2 * laneCount)))
              ) / 100
            )
          })(chat.lane, mainState, getConfig)
          chat.animation && chat.animation.cancel(),
            (chat.animation = chat.element.animate(
              [
                {
                  transform: `translate(${mainState.playerRect.width}px, ${laneY}px)`,
                },
                { transform: `translate(${-chat.width}px, ${laneY}px)` },
              ],
              { duration: 6400, easing: getConfig.timingFunction() }
            )),
            (chat.animation.onfinish = () => {
              chat.animationEnded = !0
            }),
            (chat.y = laneY)
          const newTime = 6400 * progress
          return (
            (chat.animation.currentTime = newTime),
            setChatPlayState(chat, mainState, getConfig),
            !0
          )
        },
        setChatStyle = (chat, mainState, getConfig) => {
          const fontSize = ((mainState, getConfig) =>
              Math.round(
                Math.max(getConfig.fontSize() - 0.2, 0.01) *
                  (mainState.playerRect.height / getConfig.laneCount()) *
                  100
              ) / 100)(mainState, getConfig),
            { style } = chat.element
          ;(style.visibility = getConfig.displayChats() ? "visible" : "hidden"),
            (style.color =
              "owner" === chat.authorType
                ? getConfig.ownerColor()
                : "moderator" === chat.authorType
                ? getConfig.moderatorColor()
                : "member" === chat.authorType
                ? getConfig.memberColor()
                : getConfig.color()),
            (style.fontSize = `${fontSize}px`),
            (style.fontWeight = getConfig.fontWeight().toString()),
            (style.fontFamily = getConfig.font()),
            (style.opacity = getConfig.chatOpacity().toString())
          const offset = getConfig.shadowFontWeight()
          ;(style.textShadow = `-${offset}px -${offset}px #0009, ${offset}px -${offset}px #0009, -${offset}px ${offset}px #0009, ${offset}px ${offset}px #0009`),
            (style.transform = `translate(${mainState.playerRect.width}px, -${
              2 * fontSize
            }px)`)
        }
      var MonoidAny = monoidAny
      const basicOperators = {
          some: ReadonlyArray_some,
          every: function (predicate) {
            return function (as) {
              return as.every(predicate)
            }
          },
          size: function (as) {
            return as.length
          },
          filter: es6_ReadonlyArray_filter,
          compact: ReadonlyArray_compact,
          allPredicates: Monoid_concatAll(function_getMonoid(monoidAll)()),
          anyPredicates: Monoid_concatAll(function_getMonoid(MonoidAny)()),
          matchesWords: words => text =>
            function_pipe(
              words,
              ReadonlyArray_some(x => text.content.includes(x))
            ),
          matchesRegexes: regexes => text =>
            function_pipe(
              regexes,
              ReadonlyArray_some(x =>
                Boolean(text.content.match(RegExp(x, "u")))
              )
            ),
          isVisible: x => x.visible,
        },
        evalChatFilter = (expression, data) =>
          a(
            expression,
            (data => ({
              ...basicOperators,
              authorName: data.authorName,
              message: function_pipe(
                data.message,
                es6_Option_map(x => ({ visible: !0, content: x.innerHTML }))
              ),
              messageText: function_pipe(
                data.message,
                es6_Option_map(x => {
                  var _a
                  return {
                    visible: !0,
                    content:
                      null !== (_a = x.textContent) && void 0 !== _a ? _a : "",
                  }
                })
              ),
              paymentInfo: data.paymentInfo,
            }))(data)
          ),
        assert_lib = check.assert,
        tapNonNull = x => (assert_lib(null != x), x),
        onChatFieldMutate = (
          chatScrn,
          flowChats,
          mainState,
          getConfig,
          setConfig,
          mainLog
        ) => mutations => {
          function_pipe(
            mutations,
            es6_ReadonlyArray_chain(e => Array.from(e.addedNodes)),
            es6_ReadonlyArray_filter(x => x.children.length > 0)
          ).forEach(chat => {
            const chatData = (chat => {
                var _a, _b, _c
                const authorType = chat.querySelector(".owner")
                    ? "owner"
                    : chat.querySelector(".moderator")
                    ? "moderator"
                    : chat.querySelector(".member")
                    ? "member"
                    : "normal",
                  authorName = fromNullable(
                    null === (_a = chat.querySelector("#author-name")) ||
                      void 0 === _a
                      ? void 0
                      : _a.textContent
                  ),
                  message = fromNullable(chat.querySelector("#message")),
                  isCard = Boolean(chat.querySelector("#card")),
                  isPaidNormal =
                    !!isCard &&
                    Boolean(
                      chat.querySelector(
                        [
                          ".style-scope",
                          ".yt-live-chat-paid-message-renderer",
                        ].join("")
                      )
                    ),
                  isPaidSticker =
                    !!isCard &&
                    Boolean(
                      chat.querySelector(
                        [
                          ".style-scope",
                          ".yt-live-chat-paid-sticker-renderer",
                        ].join("")
                      )
                    ),
                  paymentInfo = fromNullable(
                    isCard
                      ? null ===
                          (_b = chat.querySelector(
                            ["#purchase-amount", "#purchase-amount-chip"].join(
                              ", "
                            )
                          )) || void 0 === _b
                        ? void 0
                        : _b.textContent
                      : void 0
                  ),
                  textColor = fromNullable(
                    isPaidNormal
                      ? window
                          .getComputedStyle(
                            tapNonNull(chat.querySelector("#header"))
                          )
                          .getPropertyValue("background-color")
                      : isPaidSticker
                      ? window
                          .getComputedStyle(chat)
                          .getPropertyValue(
                            "--yt-live-chat-paid-sticker-chip-background-color"
                          )
                      : void 0
                  ),
                  paidColor = fromNullable(
                    isPaidNormal
                      ? window
                          .getComputedStyle(
                            tapNonNull(chat.querySelector("#content"))
                          )
                          .getPropertyValue("background-color")
                      : isPaidSticker
                      ? window
                          .getComputedStyle(chat)
                          .getPropertyValue(
                            "--yt-live-chat-paid-sticker-background-color"
                          )
                      : void 0
                  ),
                  authorPhotoMatches =
                    null ===
                      (_c = chat.querySelector(
                        ["#author-photo", "img"].join(" ")
                      )) || void 0 === _c
                      ? void 0
                      : _c.src.match(/ytc\/(.*)=/)
                return {
                  authorType,
                  authorID: fromNullable(
                    null == authorPhotoMatches
                      ? void 0
                      : authorPhotoMatches[authorPhotoMatches.length - 1]
                  ),
                  authorName,
                  message,
                  paymentInfo,
                  textColor,
                  paidColor,
                }
              })(chat),
              displayData = ((data, getConfig) => ({
                authorType: data.authorType,
                authorName: function_pipe(
                  data.authorName,
                  es6_Option_map(x => ({
                    visible:
                      ("moderator" === data.authorType &&
                        getConfig.displayModName()) ||
                      (Option_isSome(data.paymentInfo) &&
                        getConfig.displaySuperChatAuthor()),
                    content: x,
                  }))
                ),
                message: data.message,
                paymentInfo: function_pipe(
                  data.paymentInfo,
                  es6_Option_map(x => ({ visible: !0, content: x }))
                ),
                textColor: data.textColor,
                paidColor: data.paidColor,
              }))(chatData, getConfig)
            var predicate
            ;((data, mainState, getConfig, mainLog) =>
              function_pipe(
                data,
                fromPredicate(() =>
                  function_pipe(
                    mainState.filterExp,
                    es6_Option_map(x => evalChatFilter(x, data)),
                    getOrElse(() => !1)
                  )
                ),
                chain(x => x.message),
                match(
                  () => () => !1,
                  x => () => (
                    mainLog(`Banned chat: ${JSON.stringify(x.innerHTML)}`), !0
                  )
                )
              )())(displayData, mainState, 0, mainLog) ||
            function_pipe(
              chatData.authorID,
              ((predicate = x =>
                ((authorID, getConfig, mainLog) =>
                  getConfig
                    .bannedUsers()
                    .some(
                      user =>
                        !(
                          authorID !== user ||
                          (mainLog(`Banned User: "${authorID}"`), 0)
                        )
                    ))(x, getConfig, mainLog)),
              function (ma) {
                return !isNone(ma) && predicate(ma.value)
              })
            )
              ? (chat.style.display = "none")
              : (getConfig.createChats() &&
                  !chat.querySelector(
                    ".yt-live-chat-viewer-engagement-message-renderer"
                  ) &&
                  ((data, flowChats, chatScrn, mainState, getConfig) => {
                    var _a
                    let element
                    const offScreenChatIndex = flowChats.findIndex(
                      chat =>
                        chat.animationEnded ||
                        flowChats.length >= getConfig.maxChatCount()
                    )
                    if (-1 !== offScreenChatIndex) {
                      element = flowChats[offScreenChatIndex].element
                      const [oldChat] = flowChats.splice(offScreenChatIndex, 1)
                      null === (_a = oldChat.animation) ||
                        void 0 === _a ||
                        _a.cancel()
                    } else
                      external_log_default().debug("CreateFlowChat"),
                        (element = document.createElement("span")),
                        chatScrn.append(element)
                    element.classList.add("fyc_chat")
                    const flowChat = {
                      element,
                      lane: -1,
                      animation: void 0,
                      animationDuration: 0,
                      animationEnded: !1,
                      authorType: data.authorType,
                      width: 0,
                      height: 0,
                      y: 0,
                    }
                    external_m_default().render(
                      element,
                      chatNode(data, getConfig).slice()
                    ),
                      setChatStyle(flowChat, mainState, getConfig),
                      setChatAnimation(
                        flowChat,
                        flowChats,
                        mainState,
                        getConfig
                      )
                        ? flowChats.push(flowChat)
                        : flowChat.element.remove()
                  })(displayData, flowChats, chatScrn, mainState, getConfig),
                function_pipe(
                  chatData.authorID,
                  filter(
                    () =>
                      getConfig.createBanButton() &&
                      !chat.querySelector(".owner")
                  ),
                  match(
                    () => () => {},
                    x => () => addBanButton(chat, x, getConfig, setConfig)
                  )
                )(),
                getConfig.simplifyChatField() &&
                  (chat => {
                    if (
                      chat.querySelector(
                        ".style-scope.yt-live-chat-paid-message-renderer"
                      ) ||
                      chat.querySelector(".owner")
                    )
                      return
                    chat.style.borderBottom =
                      "1px solid var(--yt-spec-text-secondary)"
                    const authorPhoto = chat.querySelector("#author-photo")
                    authorPhoto && (authorPhoto.style.display = "none")
                    const authorChip = chat.querySelector(
                      "yt-live-chat-author-chip.style-scope.yt-live-chat-text-message-renderer"
                    )
                    authorChip && (authorChip.style.display = "none")
                  })(chat))
          })
        },
        removeOldChats = (flowChats, maxChatCount) => {
          flowChats.sort((a, b) =>
            a.animationEnded === b.animationEnded
              ? 0
              : a.animationEnded
              ? -1
              : 1
          ),
            flowChats
              .splice(0, Math.max(0, flowChats.length - maxChatCount))
              .forEach(x => {
                external_log_default().debug("RemoveChat"), x.element.remove()
              })
        }
      var fast_deep_equal = __webpack_require__(378),
        fast_deep_equal_default = __webpack_require__.n(fast_deep_equal)
      const textRecord = {
          font: ["Font", "フォント"],
          color: ["Color(Normal)", "色(通常)"],
          ownerColor: ["Color(Owner)", "色(オーナー)"],
          moderatorColor: ["Color(Moderator)", "色(モデレーター)"],
          memberColor: ["Color(Member)", "色(メンバー)"],
          feedback: ["Feedback", "バグ報告と要望"],
          eventLog: ["Event log", "イベントログ"],
          giveFeedback: [
            "Give your feedbacks here(Please attach the event log if they're bug related)",
            "バグ報告、要望はこちら(バグの場合は、イベントログを添付してください)",
          ],
          chatOpacity: ["Opacity", "不透明度"],
          fontSize: ["Size", "サイズ"],
          fontWeight: ["Weight", "太さ"],
          shadowFontWeight: ["Weight(Shadow)", "太さ(影)"],
          flowSpeed: ["Speed", "速度"],
          maxChatCount: ["Max number of chats", "最大表示数"],
          maxChatLength: ["Max number of characters", "最大文字数"],
          laneCount: ["Number of rows", "行数"],
          bannedWords: ["Banned Words", "NGワード"],
          bannedWordRegexs: ["Banned Words(Regex)", "NGワード(正規表現)"],
          bannedUsers: ["Banned Users", "NGユーザー"],
          simplifyChatField: ["Simplify", "簡略化する"],
          createBanButton: ["Show ban button", "NGボタンを表示する"],
          displayModName: [
            "Show moderator's name",
            "モデレータの名前を表示する",
          ],
          displaySuperChatAuthor: [
            "Show super chat author",
            "スパチャの作成者を表示する",
          ],
          createChats: ["Display flowing chats", "チャットを流す"],
          textOnly: ["Text only(ignore emojis)", "文字のみ(絵文字を無視する)"],
          error: ["Error", "エラー"],
          video: ["Video", "画面"],
          chatField: ["Chat Window", "チャット欄"],
          useStepTiming: ["Move chat in steps", "チャットを段階的に動かす"],
          timingStepCount: ["└Step Count", "└段階数"],
          chatFilter: ["Chat Filter", "チャットフィルター"],
          flowChat: ["Flow Chat", "チャット流れ"],
          clearFlowChats: ["Clear Flowing Chats", "流れるチャットをクリアする"],
          flowNewChatIf: [
            "A new chat will appear if all of the followings are met:",
            "新しいチャットは以下のすべてを満たす場合に流れます:",
          ],
          noOverlap: ["└Chats won't overlap", "└他のチャットと重ならない"],
          minSpacing: ["Min spacing between chats", "チャットの最小間隔"],
          fieldScale: ["Scale", "拡大率"],
          copy: ["Copy", "コピーする"],
          showChat: ["Show Chats", "チャット非表示"],
          hideChat: ["Hide Chats", "チャット表示"],
        },
        getLang = getConfig => key =>
          textRecord[key]["FYC_EN" === getConfig.lang() ? 0 : 1],
        settingPanel_option = (value, label) =>
          external_m_default()("option", { value }, label),
        settingRow = (label, content) =>
          external_m_default()("div", [
            external_m_default()("span", label),
            external_m_default()("div", content),
          ]),
        textColorRow = (color, textStyle, oninput) =>
          external_m_default()("div", [
            external_m_default()("input", {
              style: { width: "36px", verticalAlign: "middle" },
              type: "color",
              value: color,
              oninput,
            }),
            external_m_default()("input", {
              style: { verticalAlign: "middle", width: "5.5em" },
              maxlength: 20,
              value: color,
              oninput,
            }),
            external_m_default()(
              "span",
              { style: { ...textStyle, color } },
              "Aa1あア亜"
            ),
          ]),
        rangeRow = (min, max, step, value, oninput) =>
          external_m_default()("div", [
            external_m_default()("input", {
              style: { width: "150px", verticalAlign: "middle" },
              type: "range",
              min,
              max,
              step,
              value,
              oninput,
            }),
            external_m_default()("input", {
              style: {
                width: "30px",
                backgroundColor: "transparent",
                color: "inherit",
                borderWidth: "1px",
                verticalAlign: "middle",
              },
              inputmode: "decimal",
              value,
              onchange: oninput,
            }),
          ]),
        textAreaStyle = {
          resize: "horizontal",
          boxSizing: "border-box",
          width: "100%",
        },
        panelBoxStyle = width => ({ flex: `0 0 ${width}px`, margin: "2px" }),
        inputRowStyle = { width: "70%", boxSizing: "border-box" },
        textAreaRow = (rows, value, onchange) =>
          external_m_default()(
            "textarea",
            { rows: 18, style: textAreaStyle, onchange },
            value.join("\n")
          ),
        getInputValue = e => {
          const target = e.currentTarget
          if (
            target instanceof HTMLSelectElement ||
            target instanceof HTMLTextAreaElement ||
            target instanceof HTMLInputElement
          )
            return target.value
          throw Error("Event target type isn't acceptable.")
        },
        getInputChecked = e => {
          return ((constructor = HTMLInputElement),
          (x = e.currentTarget),
          assert_lib(x instanceof constructor),
          x).checked
          var constructor, x
        },
        langOptions = [
          ["FYC_EN", "English"],
          ["FYC_JA", "日本語"],
        ],
        fontOptions = currentFont => [
          ["", "Default", "デフォルト"],
          ["arial", "Arial", "Arial"],
          ["arial black", "Arial Black", "Arial Black"],
          ["arial narrow", "Arial Narrow", "Arial Narrow"],
          ["Century", "Century", "Century"],
          ["Comic Sans MS", "Comic Sans MS", "Comic Sans MS"],
          ["Courier", "Courier", "Courier"],
          ["cursive", "cursive", "cursive"],
          ["fantasy", "fantasy", "fantasy"],
          ["Impact", "Impact", "Impact"],
          ["Meiryo", "Meiryo", "メイリオ"],
          ["Meiryo UI", "Meiryo UI", "メイリオ UI"],
          ["monospace", "monospace", "monospace"],
          ["Monotype Corsiva", "Monotype Corsiva", "Monotype Corsiva"],
          ["MS PGothic", "MS PGothic", "MS Pゴシック"],
          ["MS Gothic", "MS Gothic", "MS ゴシック"],
          ["MS Sans Serif", "MS Sans Serif", "MS Sans Serif"],
          ["MS Serif", "MS Serif", "MS Serif"],
          ["MS UI Gothic", "MS UI Gothic", "MS UI Gothic"],
          ["sans-serif", "Sans-serif", "Sans-serif"],
          ["serif", "Serif", "Serif"],
          ["Times New Roman", "Times New Roman", "Times New Roman"],
          ["Yu Gothic", "Yu Gothic", "遊ゴシック"],
          ["YuGothic", "YuGothic", "游ゴシック体"],
          [currentFont, "Custom", "カスタム"],
        ],
        settingPanel = (flowChats, mainState, state, getConfig, setConfig) => {
          var _a, _b
          const panelState = {
              bannedWordRegexs: getConfig.bannedWordRegexs(),
              bannedWordRegexsValid: !0,
              bannedWordRegexsError: "",
              currentTab: 0,
              timingStepCount: parseInt(
                null !==
                  (_b =
                    null ===
                      (_a = getConfig
                        .timingFunction()
                        .match(/^steps\((\d+),.+/)) || void 0 === _a
                      ? void 0
                      : _a[1]) && void 0 !== _b
                  ? _b
                  : "150",
                10
              ),
            },
            stepTiming = stepCount => `steps(${stepCount}, jump-end)`,
            getState = {
              ...getConfig,
              bannedWordRegexs: () => {
                const local = panelState.bannedWordRegexs,
                  global = getConfig.bannedWordRegexs()
                return (
                  panelState.bannedWordRegexsValid &&
                    !fast_deep_equal_default()(local, global) &&
                    (panelState.bannedWordRegexs = global),
                  panelState.bannedWordRegexs
                )
              },
              bannedWordRegexsValid: () => panelState.bannedWordRegexsValid,
              bannedWordRegexsError: () => panelState.bannedWordRegexsError,
              currentTab: () => panelState.currentTab,
              timingStepCount: () => panelState.timingStepCount,
              useStepTiming: () =>
                Boolean(getConfig.timingFunction().match(/^steps\(.+/)),
            },
            setState = {
              ...setConfig,
              bannedWordRegexs: async val => {
                panelState.bannedWordRegexs = val
                let valid = !0
                ;(panelState.bannedWordRegexsError = ""),
                  panelState.bannedWordRegexs.forEach(regex => {
                    try {
                      RegExp(regex, "u")
                    } catch (error) {
                      ;(panelState.bannedWordRegexsError += `${error} in ${regex};`),
                        (valid = !1)
                    }
                  }),
                  valid && setConfig.bannedWordRegexs(val),
                  (panelState.bannedWordRegexsValid = valid)
              },
              currentTab: async val => {
                panelState.currentTab = val
              },
              timingStepCount: async val => {
                ;(panelState.timingStepCount = val),
                  setConfig.timingFunction(stepTiming(val))
              },
              useStepTiming: async val =>
                setConfig.timingFunction(
                  val ? stepTiming(panelState.timingStepCount) : "linear"
                ),
            },
            getText = getLang(getConfig),
            ss = function_pipe(
              [
                "lang",
                "font",
                "color",
                "ownerColor",
                "moderatorColor",
                "memberColor",
                "chatOpacity",
                "fontSize",
                "fontWeight",
                "shadowFontWeight",
                "flowSpeed",
                "minSpacing",
                "fieldScale",
                "maxChatCount",
                "maxChatLength",
                "laneCount",
                "bannedWords",
                "bannedWordRegexs",
                "bannedUsers",
                "createChats",
                "textOnly",
                "displayModName",
                "displaySuperChatAuthor",
                "noOverlap",
                "simplifyChatField",
                "createBanButton",
                "useStepTiming",
                "timingStepCount",
                "clearFlowChats",
                "currentTab",
                "copy",
              ],
              es6_ReadonlyArray_map(x => [
                x,
                new external_rxjs_namespaceObject.Subject(),
              ]),
              Object.fromEntries
            ),
            checkboxNode = label =>
              ((label, checked, onchange) =>
                external_m_default()(
                  "div",
                  external_m_default()("label", [
                    label,
                    external_m_default()("input", {
                      type: "checkbox",
                      checked,
                      onchange,
                    }),
                  ])
                ))(getText(label), getState[label](), lib(ss[label])),
            textColorNode = label =>
              settingRow(getText(label), [
                textColorRow(
                  getState[label](),
                  {
                    fontFamily: getConfig.font(),
                    fontWeight: getConfig.fontWeight().toString(),
                  },
                  lib(ss[label])
                ),
              ]),
            rangeNode = (label, min, max, step) =>
              settingRow(getText(label), [
                rangeRow(min, max, step, getState[label](), lib(ss[label])),
              ]),
            buttonNode = label =>
              external_m_default()(
                "button",
                { type: "button", onclick: lib(ss[label]) },
                getText(label)
              ),
            textAreaNode = (label, rows) =>
              settingRow(getText(label), [
                textAreaRow(0, getState[label](), lib(ss[label])),
              ]),
            updateString = key =>
              ss[key].pipe(
                (0, external_rxjs_operators_namespaceObject.map)(getInputValue),
                (0, external_rxjs_operators_namespaceObject.tap)(setState[key])
              ),
            updateNumber = key =>
              ss[key].pipe(
                (0, external_rxjs_operators_namespaceObject.map)(getInputValue),
                (0, external_rxjs_operators_namespaceObject.map)(parseFloat),
                (0, external_rxjs_operators_namespaceObject.tap)(setState[key])
              ),
            updateInt = key =>
              ss[key].pipe(
                (0, external_rxjs_operators_namespaceObject.map)(getInputValue),
                (0, external_rxjs_operators_namespaceObject.map)(x =>
                  parseInt(x, 10)
                ),
                (0, external_rxjs_operators_namespaceObject.tap)(setState[key])
              ),
            updateBool = key =>
              ss[key].pipe(
                (0, external_rxjs_operators_namespaceObject.map)(
                  getInputChecked
                ),
                (0, external_rxjs_operators_namespaceObject.tap)(setState[key])
              ),
            updateStrings = key =>
              ss[key].pipe(
                (0, external_rxjs_operators_namespaceObject.map)(getInputValue),
                (0, external_rxjs_operators_namespaceObject.map)(x =>
                  x.split(/\r\n|\n/).filter(str => "" !== str)
                ),
                (0, external_rxjs_operators_namespaceObject.tap)(setState[key])
              )
          return (
            (0, external_rxjs_namespaceObject.merge)(
              (0, external_rxjs_namespaceObject.merge)(
                (0, external_rxjs_namespaceObject.merge)(
                  updateString("font"),
                  updateNumber("fontSize"),
                  updateNumber("fontWeight"),
                  updateInt("laneCount"),
                  updateNumber("minSpacing")
                ).pipe(
                  (0, external_rxjs_operators_namespaceObject.mapTo)({
                    setStyle: !0,
                    setAnimation: !0,
                  })
                ),
                (0, external_rxjs_namespaceObject.merge)(
                  updateString("color"),
                  updateString("ownerColor"),
                  updateString("moderatorColor"),
                  updateString("memberColor"),
                  updateNumber("chatOpacity"),
                  updateNumber("shadowFontWeight")
                ).pipe(
                  (0, external_rxjs_operators_namespaceObject.mapTo)({
                    setStyle: !0,
                  })
                ),
                (0, external_rxjs_namespaceObject.merge)(
                  updateNumber("flowSpeed")
                ).pipe(
                  (0, external_rxjs_operators_namespaceObject.mapTo)({
                    setPlayState: !0,
                  })
                ),
                (0, external_rxjs_namespaceObject.merge)(
                  updateInt("maxChatCount").pipe(
                    (0, external_rxjs_operators_namespaceObject.tap)(x =>
                      removeOldChats(flowChats, x)
                    )
                  ),
                  updateBool("noOverlap"),
                  updateBool("useStepTiming"),
                  updateInt("timingStepCount")
                ).pipe(
                  (0, external_rxjs_operators_namespaceObject.mapTo)({
                    setAnimation: !0,
                  })
                )
              ).pipe(
                (0, external_rxjs_operators_namespaceObject.throttleTime)(
                  180,
                  void 0,
                  { leading: !0, trailing: !0 }
                ),
                (0, external_rxjs_operators_namespaceObject.tap)(x => {
                  flowChats
                    .filter(chat => !chat.animationEnded)
                    .forEach(chat => {
                      const config = {
                        setStyle: !1,
                        setAnimation: !1,
                        setPlayState: !1,
                        ...x,
                      }
                      config.setStyle &&
                        setChatStyle(chat, mainState, getConfig),
                        config.setAnimation
                          ? setChatAnimation(
                              chat,
                              flowChats,
                              mainState,
                              getConfig
                            )
                          : config.setPlayState &&
                            setChatPlayState(chat, mainState, getConfig)
                    })
                })
              ),
              updateString("lang"),
              ss.currentTab.pipe(
                (0, external_rxjs_operators_namespaceObject.tap)(
                  setState.currentTab
                )
              ),
              updateInt("maxChatLength"),
              updateBool("simplifyChatField"),
              updateBool("createBanButton"),
              updateBool("createChats"),
              updateBool("displayModName"),
              updateBool("displaySuperChatAuthor"),
              updateBool("textOnly"),
              updateNumber("fieldScale"),
              updateStrings("bannedWords"),
              updateStrings("bannedWordRegexs"),
              updateStrings("bannedUsers"),
              ss.clearFlowChats.pipe(
                (0, external_rxjs_operators_namespaceObject.tap)(() =>
                  removeOldChats(flowChats, 0)
                )
              ),
              ss.copy.pipe(
                (0, external_rxjs_operators_namespaceObject.tap)(() =>
                  GM.setClipboard(mainState.log)
                )
              )
            ).subscribe(),
            {
              view: () => {
                return external_m_default()(
                  "div",
                  {
                    className: "fyc_panel",
                    style: {
                      visibility: state.showPanel ? "visible" : "hidden",
                      backgroundColor: "rgba(30,30,30,0.9)",
                      zIndex: 5,
                      position: "absolute",
                      bottom: "40px",
                      right: "0px",
                      color: "#fff",
                      fontSize: "14px",
                      width: "660px",
                      border: "solid 1px #666",
                      fontFamily: "MS PGothic",
                      lineHeight: "1.2",
                    },
                  },
                  [
                    external_m_default()(
                      "div",
                      { style: { float: "right", margin: "3px 3px 0 0" } },
                      [
                        "🌐",
                        external_m_default()(
                          "select",
                          {
                            selectedIndex: langOptions.findIndex(
                              x => x[0] === getState.lang()
                            ),
                            onchange: lib(ss.lang),
                          },
                          langOptions.map(x => settingPanel_option(...x))
                        ),
                      ]
                    ),
                    ((style = {
                      container: { height: "364px" },
                      label: { padding: "6px" },
                      labelFocus: { background: "#666" },
                      tab: { display: "flex", padding: "6px" },
                    }),
                    (labels = [
                      getText("flowChat"),
                      getText("chatFilter"),
                      getText("chatField"),
                      getText("feedback"),
                    ]),
                    (tabs = [
                      [
                        external_m_default()(
                          "div",
                          { style: panelBoxStyle(212) },
                          [
                            settingRow(getText("font"), [
                              external_m_default()(
                                "select",
                                {
                                  style: inputRowStyle,
                                  selectedIndex: fontOptions(
                                    getState.font()
                                  ).findIndex(x => x[0] === getState.font()),
                                  onchange: lib(ss.font),
                                },
                                fontOptions(getState.font()).map(x =>
                                  settingPanel_option(
                                    x[0],
                                    "FYC_JA" === getState.lang() ? x[2] : x[1]
                                  )
                                )
                              ),
                            ]),
                            external_m_default()("input", {
                              style: inputRowStyle,
                              maxlength: 20,
                              value: getState.font(),
                              oninput: lib(ss.font),
                            }),
                            textColorNode("color"),
                            textColorNode("ownerColor"),
                            textColorNode("moderatorColor"),
                            textColorNode("memberColor"),
                          ]
                        ),
                        external_m_default()(
                          "div",
                          { style: panelBoxStyle(212) },
                          [
                            rangeNode("chatOpacity", 0, 1, 0.05),
                            rangeNode("fontSize", 0.3, 2, 0.05),
                            rangeNode("fontWeight", 10, 1e3, 10),
                            rangeNode("shadowFontWeight", 0, 3, 0.1),
                            rangeNode("flowSpeed", 1, 50, 1),
                            rangeNode("maxChatCount", 5, 200, 5),
                            rangeNode("maxChatLength", 5, 200, 5),
                            rangeNode("laneCount", 1, 25, 1),
                          ]
                        ),
                        external_m_default()(
                          "div",
                          { style: panelBoxStyle(212) },
                          [
                            rangeNode("minSpacing", 0, 2.5, 0.1),
                            checkboxNode("useStepTiming"),
                            external_m_default()(
                              "div",
                              {
                                style: {
                                  ...(getState.useStepTiming()
                                    ? {}
                                    : { opacity: "0.5" }),
                                },
                              },
                              rangeNode("timingStepCount", 1, 400, 1)
                            ),
                            checkboxNode("createChats"),
                            checkboxNode("displayModName"),
                            checkboxNode("displaySuperChatAuthor"),
                            checkboxNode("textOnly"),
                            external_m_default()(
                              "span",
                              getText("flowNewChatIf")
                            ),
                            checkboxNode("noOverlap"),
                            buttonNode("clearFlowChats"),
                          ]
                        ),
                      ],
                      [
                        external_m_default()(
                          "div",
                          { style: panelBoxStyle(212) },
                          textAreaNode("bannedWords")
                        ),
                        external_m_default()(
                          "div",
                          { style: panelBoxStyle(212) },
                          settingRow(getText("bannedWordRegexs"), [
                            external_m_default()(
                              "span",
                              getState.bannedWordRegexsValid()
                                ? ""
                                : `${getText(
                                    "error"
                                  )}: ${getState.bannedWordRegexsError()}`
                            ),
                            textAreaRow(
                              0,
                              getState.bannedWordRegexs(),
                              lib(ss.bannedWordRegexs)
                            ),
                          ])
                        ),
                        external_m_default()(
                          "div",
                          { style: panelBoxStyle(212) },
                          textAreaNode("bannedUsers")
                        ),
                      ],
                      [
                        external_m_default()(
                          "div",
                          { style: panelBoxStyle(644) },
                          [
                            rangeNode("fieldScale", 0.7, 1.5, 0.05),
                            checkboxNode("simplifyChatField"),
                            checkboxNode("createBanButton"),
                          ]
                        ),
                      ],
                      [
                        external_m_default()(
                          "div",
                          { style: panelBoxStyle(644) },
                          [
                            external_m_default()(
                              "div",
                              { style: { float: "right" } },
                              external_m_default()(
                                "a",
                                {
                                  style: { color: "#f0f" },
                                  href:
                                    "https://greasyfork.org/en/scripts/411442-flow-youtube-chat/feedback",
                                  target: "_blank",
                                },
                                getText("giveFeedback")
                              )
                            ),
                            external_m_default()("div", [
                              external_m_default()("span", getText("eventLog")),
                              buttonNode("copy"),
                              external_m_default()(
                                "div",
                                external_m_default()(
                                  "textarea",
                                  {
                                    rows: 18,
                                    style: textAreaStyle,
                                    readOnly: !0,
                                    onclick: () => {},
                                  },
                                  mainState.log
                                )
                              ),
                            ]),
                          ]
                        ),
                      ],
                    ]),
                    (currentTab = getState.currentTab()),
                    (ontabSelect = lib(ss.currentTab)),
                    external_m_default()("div", [
                      external_m_default()(
                        "div",
                        ...labels.map((x, i) =>
                          external_m_default()(
                            "span",
                            {
                              style: {
                                ...style.label,
                                ...(currentTab === i ? style.labelFocus : {}),
                                display: "inline-block",
                              },
                              onclick: () => ontabSelect(i),
                            },
                            x
                          )
                        )
                      ),
                      external_m_default()(
                        "div",
                        {
                          style: {
                            ...style.container,
                            overflow: "hidden auto",
                          },
                        },
                        ...tabs.map((x, i) => {
                          var _a
                          return external_m_default()(
                            "div",
                            {
                              style: {
                                ...style.tab,
                                display:
                                  i === currentTab
                                    ? null !== (_a = style.tab.display) &&
                                      void 0 !== _a
                                      ? _a
                                      : "block"
                                    : "none",
                              },
                            },
                            x
                          )
                        })
                      ),
                    ])),
                  ]
                )
                var style, labels, tabs, currentTab, ontabSelect
              },
            }
          )
        },
        settingComponent = (flowChats, mainState, getConfig, setConfig) => {
          const state = { showPanel: !1 },
            panel = settingPanel(
              flowChats,
              mainState,
              state,
              getConfig,
              setConfig
            ),
            toggleButton = ((state, getConfig) => {
              const click$ = new external_rxjs_namespaceObject.Subject()
              return (
                click$
                  .pipe(
                    (0, external_rxjs_operators_namespaceObject.tap)(() => {
                      state.showPanel = !state.showPanel
                    })
                  )
                  .subscribe(),
                {
                  view: () =>
                    external_m_default()(
                      "button",
                      {
                        className: "fyc_button",
                        style: {
                          background: "rgba(0,0,0,0)",
                          marginLeft: "10px",
                          whiteSpace: "nowrap",
                        },
                        onclick: lib(click$),
                      },
                      [
                        external_m_default()(
                          "svg",
                          {
                            preserveAspectRatio: "xMidYMid meet",
                            viewBox: "0 0 640 640",
                            width: "15",
                            height: "15",
                            style: { position: "relative", top: "1px" },
                          },
                          [
                            external_m_default()(
                              "defs",
                              external_m_default()("path", {
                                id: "d1TbzTC1zI",
                                d:
                                  "M135 58c25 14 67 30 82 35-7 49 16 109-15 149-50 71-19 184 64 213 74 31 165-18 183-95-3-38 23-62 58-36l120 55c-39 10-106 35-72 85 40 38 1 71-29 98-29 53-70-17-109-5-46 22-25 109-96 85h-55c-24-31-21-103-80-84-32 32-70 31-93-9l-35-36c4-40 57-96-6-120-45 5-58-32-52-68 2-19-4-41 3-59 35-15 100-22 77-79-48-43 1-84 35-115 5-6 12-12 20-14zM577 2c52 3 72 62 62 106-5 51 19 117-27 155-18 24 8 49 11 74-39-8-98-46-146-60-55-1-111 2-167-2-52-15-57-76-52-121S242 52 282 18c38-30 88-11 132-16h163z",
                              })
                            ),
                            external_m_default()("use", {
                              "xlink:href": "#d1TbzTC1zI",
                              opacity: "1",
                              fill: "var(--iron-icon-fill-color, currentcolor)",
                              "fill-opacity": "1",
                            }),
                          ]
                        ),
                        external_m_default()(
                          "span",
                          {
                            style: {
                              position: "relative",
                              top: "-2px",
                              marginLeft: "8px,",
                            },
                          },
                          "FYC_JA" === getConfig.lang() ? "設定" : "Settings"
                        ),
                      ]
                    ),
                }
              )
            })(state, getConfig)
          return {
            view: () => [
              external_m_default()(panel),
              external_m_default()(toggleButton),
            ],
          }
        },
        initialize = async (mainState, mainLog) => {
          const consoleLog = (a, ...b) => {
            mainLog(a, ...b),
              external_log_default().info(`【FYC】 ${a}`),
              b.length > 0 && external_log_default().info(...b)
          }
          mainLog("Version", package_namespaceObject_i8),
            mainLog("User Agent", window.navigator.userAgent)
          const userConfig = await (async () => ({
            lang: await simpleConfig("FYC_LANG", "FYC_EN"),
            font: await simpleConfig("FYC_FONT", "MS PGothic"),
            chatOpacity: await simpleConfig("FYC_OPACITY", 0.8),
            color: await simpleConfig("FYC_COLOR", "#ffffff"),
            ownerColor: await simpleConfig("FYC_COLOR_OWNER", "#ffd600"),
            moderatorColor: await simpleConfig(
              "FYC_COLOR_MODERATOR",
              "#a74fff"
            ),
            memberColor: await simpleConfig("FYC_COLOR_MEMBER", "#9fffff"),
            fontSize: await simpleConfig("FYC_SIZE", 1),
            fontWeight: await simpleConfig("FYC_WEIGHT", 730),
            shadowFontWeight: await simpleConfig("FYC_WEIGHT_SHADOW", 1),
            maxChatCount: await simpleConfig("FYC_LIMIT", 40),
            flowSpeed: await simpleConfig("FYC_SPEED", 18),
            maxChatLength: await simpleConfig("FYC_MAX", 100),
            laneCount: await simpleConfig("FYC_LANE_DIV", 12),
            bannedWords: await indirectConfig(
              "FYC_NG_WORDS",
              ...lineConfigArgs
            ),
            bannedWordRegexs: await indirectConfig(
              "FYC_NG_REG_WORDS",
              ...lineConfigArgs
            ),
            bannedUsers: await indirectConfig(
              "FYC_NG_USERS",
              ...lineConfigArgs
            ),
            createChats: await simpleConfig("FYC_TOGGLE_CREATE_COMMENTS", !0),
            noOverlap: await simpleConfig("FYC_NO_OVERLAP", !0),
            createBanButton: await simpleConfig("FYC_NG_BUTTON", !0),
            simplifyChatField: await simpleConfig("FYC_SIMPLE_CHAT_FIELD", !1),
            displayModName: await simpleConfig(
              "FYC_DISPLAY_MODERATOR_NAME",
              !0
            ),
            displaySuperChatAuthor: await simpleConfig(
              "FYC_DISPLAY_SUPER_CHAT_AUTHOR",
              !0
            ),
            textOnly: await simpleConfig("FYC_TEXT_ONLY", !1),
            timingFunction: await simpleConfig("FYC_TIMING_FUNCTION", "linear"),
            displayChats: await simpleConfig("FYC_DISPLAY_COMMENTS", !0),
            minSpacing: await simpleConfig("FYC_MIN_SPACING", 0.5),
            fieldScale: await simpleConfig("FYC_FIELD_SCALE", 1),
          }))()
          mainLog("UserConfig", JSON.stringify(userConfig))
          const configKeys = Object.keys(userConfig),
            getConfig = function_pipe(
              configKeys,
              es6_ReadonlyArray_map(x => [x, () => userConfig[x].val]),
              Object.fromEntries
            ),
            configSubject = function_pipe(
              configKeys,
              es6_ReadonlyArray_map(x => [
                x,
                new external_rxjs_namespaceObject.Subject(),
              ]),
              Object.fromEntries
            ),
            channel = new broadcast_channel_BroadcastChannel(
              "fyc-0615654655528523"
            ),
            setConfigPlain = function_pipe(
              configKeys,
              es6_ReadonlyArray_map(x => [
                x,
                async val => {
                  ;(userConfig[x].val = val), configSubject[x].next(val)
                },
              ]),
              Object.fromEntries
            ),
            setConfig = function_pipe(
              configKeys,
              es6_ReadonlyArray_map(x => [
                x,
                async val => {
                  setConfigPlain[x](val)
                  const item = userConfig[x]
                  channel.postMessage([x, val]),
                    await GM.setValue(item.gmKey, item.toGm(val))
                },
              ]),
              Object.fromEntries
            ),
            reinitSubject = new external_rxjs_namespaceObject.Subject(),
            reinitialize = () => {
              requestAnimationFrame(() => lib(reinitSubject)())
            },
            chatScreen = (() => {
              const element = document.createElement("div")
              return (
                (element.style.pointerEvents = "none"),
                (element.style.zIndex = "30"),
                element
              )
            })(),
            css = (() => {
              const element = document.createElement("style")
              return (
                (element.innerHTML =
                  ".fyc_chat {\n    line-height: 1;\n    z-index: 30;\n    position: absolute;\n    user-select: none;\n    white-space: nowrap;\n    will-change: transform;\n  }\n  .fyc_chat > img {\n    vertical-align: text-top;\n  }\n  .fyc_button {\n    display: inline-block;\n    border-style: none;\n    z-index: 4;\n    font-weight: 500;\n    color: var(--yt-spec-text-secondary);\n  }"),
                element
              )
            })(),
            flowChats = [],
            observePair = con => {
              const subject = new external_rxjs_namespaceObject.Subject()
              return { subject, observer: new con(lib(subject)) }
            },
            documentMutationPair = observePair(MutationObserver),
            chatFieldMutationPair = observePair(MutationObserver),
            playerResizePair = observePair(ResizeObserver),
            simpleWrap = comp => ({
              comp,
              root: document.createElement("span"),
            }),
            wrappedToggleChatBtn = simpleWrap(
              ((flowChats, getConfig, setConfig) => {
                const click$ = new external_rxjs_namespaceObject.Subject()
                click$
                  .pipe(
                    (0, external_rxjs_operators_namespaceObject.tap)(() => {
                      const newDisplay = !getConfig.displayChats()
                      flowChats.forEach(x => {
                        x.element.style.visibility = newDisplay
                          ? "visible"
                          : "hidden"
                      }),
                        setConfig.displayChats(newDisplay)
                    })
                  )
                  .subscribe()
                const getText = getLang(getConfig),
                  label = () =>
                    getText(getConfig.displayChats() ? "hideChat" : "showChat")
                return {
                  view: () =>
                    external_m_default()(
                      "button",
                      {
                        className: ["ytp-button"].join(" "),
                        style: {
                          background: "none",
                          border: "none",
                          cursor: "pointer",
                          float: "left",
                          fontSize: "1em",
                          height: "4em",
                          outline: "none",
                          overflow: "visible",
                          padding: "0 0 0em",
                          position: "relative",
                          width: "3em",
                        },
                        type: "button",
                        "aria-label": label(),
                        title: label(),
                        onclick: lib(click$),
                      },
                      [
                        external_m_default()(
                          "svg",
                          { style: { width: "100%" }, viewBox: "0 0 36 36" },
                          [
                            external_m_default()("path", {
                              className: ["chat-button-path"].join(" "),
                              d:
                                "m11 12h17q1 0 1 1v9q0 1-1 1h-1v2l-4-2h-12q-1 0-1-1v-9q0-1 1-1z",
                              fill: "#fff",
                              "fill-opacity": getConfig.displayChats()
                                ? "1"
                                : "0",
                              stroke: "#fff",
                              "stroke-width": "2",
                            }),
                          ]
                        ),
                      ]
                    ),
                }
              })(flowChats, getConfig, setConfig)
            ),
            wrappedSetting = simpleWrap(
              settingComponent(flowChats, mainState, getConfig, setConfig)
            ),
            livePage = {
              toggleChatBtnParent: () =>
                fromNullable(document.querySelector(".ytp-right-controls")),
              settingNextElement: () =>
                fromNullable(
                  document.querySelector(
                    "#menu-container .dropdown-trigger.ytd-menu-renderer"
                  )
                ),
              player: () =>
                fromNullable(document.querySelector("#movie_player")),
              video: () =>
                fromNullable(
                  document.querySelector("video.video-stream.html5-main-video")
                ),
              chatField: () =>
                function_pipe(
                  chatApp(),
                  chainNullableK(x =>
                    x.querySelector("#items.yt-live-chat-item-list-renderer")
                  )
                ),
              chatScroller: () =>
                function_pipe(
                  chatApp(),
                  chainNullableK(x =>
                    x.querySelector(
                      "#item-scroller.yt-live-chat-item-list-renderer"
                    )
                  )
                ),
              offlineSlate: () =>
                fromNullable(document.querySelector(".ytp-offline-slate")),
            },
            liveElementKeys = Object.keys(livePage),
            live = function_pipe(
              liveElementKeys,
              es6_ReadonlyArray_map(x => {
                return [x, ((key = x), { ele: none, read: livePage[key] })]
                var key
              }),
              Object.fromEntries
            ),
            eq = getEq(eqStrict).equals
          reinitSubject
            .pipe(
              (0, external_rxjs_operators_namespaceObject.observeOn)(
                external_rxjs_namespaceObject.asyncScheduler
              ),
              (0, external_rxjs_operators_namespaceObject.delay)(100),
              (0, external_rxjs_operators_namespaceObject.tap)(() =>
                consoleLog("Init")
              ),
              (0, external_rxjs_operators_namespaceObject.switchMap)(() =>
                (0, external_rxjs_namespaceObject.interval)(700).pipe(
                  (0, external_rxjs_operators_namespaceObject.filter)(() =>
                    function_pipe(
                      liveElementKeys,
                      es6_ReadonlyArray_map(key =>
                        function_pipe(
                          live[key].read(),
                          fromPredicate(newEle => !eq(live[key].ele, newEle)),
                          es6_Option_map(x => () => (
                            (live[key].ele = x),
                            consoleLog(`${key} changed`),
                            !0
                          )),
                          getOrElse(() => IO_of(!1))
                        )
                      ),
                      IO_sequenceArray,
                      (function (f) {
                        return function (fa) {
                          return IO_map(fa, f)
                        }
                      })(ReadonlyArray_some(Boolean))
                    )()
                  ),
                  (0, external_rxjs_operators_namespaceObject.startWith)(0)
                )
              ),
              (0, external_rxjs_operators_namespaceObject.tap)(() => {
                consoleLog("Loading..."),
                  removeOldChats(flowChats, 0),
                  documentMutationPair.observer.disconnect(),
                  documentMutationPair.observer.observe(document, {
                    childList: !0,
                    subtree: !0,
                  }),
                  chatFieldMutationPair.observer.disconnect(),
                  playerResizePair.observer.disconnect(),
                  document.head.append(css),
                  function_pipe(
                    [
                      function_pipe(
                        live.chatField.ele,
                        es6_Option_map(x => () => {
                          var chatField
                          ;((chatField = x),
                          () =>
                            function_pipe(
                              fromNullable(chatField.parentElement),
                              es6_Option_map(x => () => {
                                x.style.overflow = "unset"
                              })
                            ))(),
                            chatFieldMutationPair.observer.observe(x, {
                              childList: !0,
                            })
                        })
                      ),
                      function_pipe(
                        live.player.ele,
                        es6_Option_map(x => () => {
                          playerResizePair.observer.observe(x),
                            x.insertAdjacentElement("afterbegin", chatScreen)
                        })
                      ),
                      function_pipe(
                        live.toggleChatBtnParent.ele,
                        es6_Option_map(x => () => {
                          x.append(wrappedToggleChatBtn.root),
                            mountComponent(wrappedToggleChatBtn)
                        })
                      ),
                      function_pipe(
                        live.settingNextElement.ele,
                        es6_Option_map(x => () => {
                          x.insertAdjacentElement(
                            "beforebegin",
                            wrappedSetting.root
                          ),
                            mountComponent(wrappedSetting)
                        })
                      ),
                    ],
                    ReadonlyArray_compact,
                    ReadonlyArray_append(
                      function_pipe(
                        live.video.ele,
                        filter(x => !x.paused),
                        alt(() => live.offlineSlate.ele),
                        Option_isSome,
                        x => () => {
                          mainState.chatPlaying = x
                        }
                      )
                    ),
                    IO_sequenceArray
                  )()
              }),
              (0, external_rxjs_operators_namespaceObject.switchMap)(() =>
                (0, external_rxjs_namespaceObject.merge)(
                  (0, external_rxjs_namespaceObject.fromEvent)(
                    channel,
                    "message"
                  ).pipe(
                    (0, external_rxjs_operators_namespaceObject.tap)(
                      ([key, val]) => {
                        ;[
                          "bannedWords",
                          "bannedWordRegexs",
                          "bannedUsers",
                          "simplifyChatField",
                          "createBanButton",
                          "fieldScale",
                        ].includes(key) &&
                          (setConfigPlain[key](val),
                          external_m_default().redraw())
                      }
                    )
                  ),
                  ...function_pipe(
                    configKeys,
                    es6_ReadonlyArray_map(key =>
                      configSubject[key].pipe(
                        (0, external_rxjs_operators_namespaceObject.startWith)(
                          getConfig[key]()
                        ),
                        (0,
                        external_rxjs_operators_namespaceObject.bufferCount)(
                          2,
                          1
                        ),
                        (0,
                        external_rxjs_operators_namespaceObject.map)(([x, y]) =>
                          (0, external_DeepDiff_namespaceObject.diff)(x, y)
                        ),
                        (0, external_rxjs_operators_namespaceObject.tap)(x =>
                          mainLog(`Config ${key}`, JSON.stringify(x))
                        )
                      )
                    )
                  ),
                  (0, external_rxjs_namespaceObject.merge)(
                    configSubject.bannedWordRegexs,
                    configSubject.bannedWords
                  ).pipe(
                    (0, external_rxjs_operators_namespaceObject.startWith)(
                      void 0
                    ),
                    (0, external_rxjs_operators_namespaceObject.tap)(() => {
                      mainState.filterExp = some(
                        external_jsep_default()(
                          `\nsome(anyPredicates([\n  matchesRegexes(${JSON.stringify(
                            getConfig.bannedWordRegexs()
                          )}),\n  matchesWords(${JSON.stringify(
                            getConfig.bannedWords()
                          )})\n]))(compact([\n  messageText,\n  paymentInfo\n]))\n        `
                        )
                      )
                    })
                  ),
                  configSubject.fieldScale.pipe(
                    (0, external_rxjs_operators_namespaceObject.startWith)(
                      getConfig.fieldScale()
                    ),
                    (0, external_rxjs_operators_namespaceObject.tap)(scale =>
                      function_pipe(
                        live.chatField.ele,
                        match(
                          () => () => {},
                          field =>
                            function_pipe(
                              [
                                function_pipe(
                                  fromNullable(field.parentElement),
                                  es6_Option_map(x => () => {
                                    ;(x.style.transformOrigin =
                                      (scale >= 1 ? "top" : "bottom") +
                                      " left"),
                                      (x.style.transform = `scale(${scale})`),
                                      (x.style.width = 100 / scale + "%"),
                                      (x.style.height = `${field.offsetHeight}px`)
                                  })
                                ),
                                function_pipe(
                                  live.chatScroller.ele,
                                  es6_Option_map(scroller => () => {
                                    scroller.scrollTop = scroller.scrollHeight
                                  })
                                ),
                              ],
                              ReadonlyArray_compact,
                              IO_sequenceArray
                            )
                        )
                      )()
                    )
                  ),
                  function_pipe(
                    live.video.ele,
                    match(
                      () => external_rxjs_namespaceObject.EMPTY,
                      x => {
                        return ((video = x),
                        (0, external_rxjs_namespaceObject.merge)(
                          (0, external_rxjs_namespaceObject.fromEvent)(
                            video,
                            "playing"
                          ).pipe(
                            (0, external_rxjs_operators_namespaceObject.mapTo)(
                              !0
                            )
                          ),
                          (0, external_rxjs_namespaceObject.fromEvent)(
                            video,
                            "waiting"
                          ).pipe(
                            (0, external_rxjs_operators_namespaceObject.mapTo)(
                              !1
                            )
                          ),
                          (0, external_rxjs_namespaceObject.fromEvent)(
                            video,
                            "pause"
                          ).pipe(
                            (0, external_rxjs_operators_namespaceObject.mapTo)(
                              !1
                            )
                          )
                        )).pipe(
                          (0, external_rxjs_operators_namespaceObject.map)(
                            playing =>
                              playing || Option_isSome(live.offlineSlate.ele)
                          ),
                          (0, external_rxjs_operators_namespaceObject.tap)(
                            chatPlaying => {
                              ;(mainState.chatPlaying = chatPlaying),
                                flowChats.forEach(chat => {
                                  setChatPlayState(chat, mainState, getConfig)
                                })
                            }
                          )
                        )
                        var video
                      }
                    )
                  ),
                  chatFieldMutationPair.subject.pipe(
                    (0, external_rxjs_operators_namespaceObject.tap)(
                      onChatFieldMutate(
                        chatScreen,
                        flowChats,
                        mainState,
                        getConfig,
                        setConfig,
                        mainLog
                      )
                    )
                  ),
                  documentMutationPair.subject.pipe(
                    (0, external_rxjs_operators_namespaceObject.map)(
                      () => window.location.href
                    ),
                    (0,
                    external_rxjs_operators_namespaceObject.distinctUntilChanged)(),
                    (0, external_rxjs_operators_namespaceObject.skip)(1),
                    (0, external_rxjs_operators_namespaceObject.tap)(x => {
                      consoleLog("URL Changed", x),
                        removeOldChats(flowChats, 0),
                        consoleLog("Wait for 1700ms...")
                    }),
                    (0, external_rxjs_operators_namespaceObject.delay)(1700),
                    (0, external_rxjs_operators_namespaceObject.tap)(() =>
                      reinitialize()
                    )
                  ),
                  playerResizePair.subject.pipe(
                    (0,
                    external_rxjs_operators_namespaceObject.throttleTime)(
                      500,
                      void 0,
                      { leading: !0, trailing: !0 }
                    ),
                    (0, external_rxjs_operators_namespaceObject.startWith)([]),
                    (0, external_rxjs_operators_namespaceObject.map)(
                      () => live.player.ele
                    ),
                    (0, external_rxjs_operators_namespaceObject.map)(
                      es6_Option_map(x => x.getBoundingClientRect())
                    ),
                    (0, external_rxjs_operators_namespaceObject.tap)(x =>
                      ((rect, flowChats, mainState, getConfig, mainLog) =>
                        function_pipe(
                          rect,
                          match(
                            () => () => {},
                            x => () => {
                              mainLog("Resize detected"),
                                (mainState.playerRect = x),
                                flowChats.forEach(chat => {
                                  setChatStyle(chat, mainState, getConfig),
                                    setChatAnimation(
                                      chat,
                                      flowChats,
                                      mainState,
                                      getConfig
                                    )
                                })
                            }
                          )
                        )())(x, flowChats, mainState, getConfig, mainLog)
                    )
                  )
                )
              ),
              (0, external_rxjs_operators_namespaceObject.retryWhen)(e =>
                e.pipe(
                  (0, external_rxjs_operators_namespaceObject.tap)(() => {
                    consoleLog("Errored", e)
                  }),
                  (0, external_rxjs_operators_namespaceObject.delay)(5e3),
                  (0, external_rxjs_operators_namespaceObject.tap)(x => {
                    consoleLog(x), reinitialize()
                  })
                )
              )
            )
            .subscribe({
              error: x => consoleLog("Stream error", x),
              complete: () => consoleLog("Stream complete"),
            }),
            reinitialize()
        }
      ;(async () => {
        external_log_namespaceObject.setLevel("info")
        const mainState = {
          chatPlaying: !0,
          playerRect: new DOMRect(24, 80, 839, 472),
          log: "",
          filterExp: none,
        }
        try {
          await initialize(
            mainState,
            (mainState => (a, ...b) => {
              ;(mainState.log += `${a}${b.length > 0 ? ": " : ""}${b.join(
                ", "
              )}\n`),
                mainState.log.length > 22e3 &&
                  (mainState.log = `${mainState.log.slice(0, 6e3)}\n`)
            })(mainState)
          )
        } catch (error) {
          external_log_namespaceObject.info("【FYC】 Error", error)
        }
      })()
    })()
})()