{"version":3,"file":"ArtalkLite.cjs","sources":["../src/lib/utils.ts","../src/i18n/en.ts","../src/i18n/external.ts","../src/i18n/index.ts","../src/i18n/zh-CN.ts","../../../node_modules/.pnpm/insane@2.6.2/node_modules/insane/she.js","../../../node_modules/.pnpm/assignment@2.0.0/node_modules/assignment/assignment.js","../../../node_modules/.pnpm/insane@2.6.2/node_modules/insane/lowercase.js","../../../node_modules/.pnpm/insane@2.6.2/node_modules/insane/toMap.js","../../../node_modules/.pnpm/insane@2.6.2/node_modules/insane/attributes.js","../../../node_modules/.pnpm/insane@2.6.2/node_modules/insane/elements.js","../../../node_modules/.pnpm/insane@2.6.2/node_modules/insane/parser.js","../../../node_modules/.pnpm/insane@2.6.2/node_modules/insane/sanitizer.js","../../../node_modules/.pnpm/insane@2.6.2/node_modules/insane/insane.js","../../../node_modules/.pnpm/insane@2.6.2/node_modules/insane/defaults.js","../src/lib/sanitizer.ts","../../../node_modules/.pnpm/hanabi@0.4.0/node_modules/hanabi/dist/hanabi.js","../src/lib/highlight.ts","../src/lib/marked-renderer.ts","../src/lib/marked.ts","../src/context.ts","../src/lib/injection/container.ts","../src/lib/merge-deep.ts","../src/defaults.ts","../src/config.ts","../src/plugins/stat.ts","../src/api/v2.ts","../src/api/fetch.ts","../src/api/index.ts","../src/plugins/editor/_plug.ts","../src/plugins/editor/local-storage.ts","../src/plugins/editor/submit-add.ts","../src/plugins/editor/submit.ts","../src/plugins/editor/mover.ts","../src/lib/ui.ts","../src/plugins/editor/emoticons.ts","../src/plugins/editor/upload.ts","../src/plugins/editor/preview.ts","../src/plugins/editor/index.ts","../src/plugins/editor/header-event.ts","../src/plugins/editor/header-user.ts","../src/plugins/editor/header-link.ts","../src/plugins/editor/textarea.ts","../src/plugins/editor/submit-btn.ts","../src/plugins/editor/state-reply.ts","../src/plugins/editor/state-edit.ts","../src/plugins/editor/closable.ts","../src/plugins/editor/_kit.ts","../src/lib/event-manager.ts","../src/plugins/editor-kit.ts","../src/plugins/list/goto-focus.ts","../src/components/error-dialog.ts","../src/plugins/list/error-dialog.ts","../src/plugins/list/index.ts","../src/plugins/list/fetch.ts","../src/plugins/list/loading.ts","../src/plugins/list/unread.ts","../src/plugins/list/with-editor.ts","../src/plugins/list/count.ts","../src/plugins/list/sidebar-btn.ts","../src/plugins/list/unread-badge.ts","../src/plugins/list/dropdown.ts","../src/plugins/list/goto-dispatcher.ts","../src/plugins/list/no-comment.ts","../src/plugins/list/copyright.ts","../src/plugins/list/time-ticking.ts","../src/plugins/list/reach-bottom.ts","../src/plugins/list/goto-first.ts","../src/plugins/version-check.ts","../src/plugins/dark-mode.ts","../src/plugins/page-vote.ts","../src/services/api.ts","../src/lib/user.ts","../src/components/checker/captcha-renders.ts","../src/components/checker/captcha.ts","../src/components/checker/admin.ts","../src/components/dialog.ts","../src/components/checker/index.ts","../src/services/checkers.ts","../src/editor/ui.ts","../src/editor/state.ts","../src/editor/editor.ts","../src/editor/editor.html?raw","../src/data.ts","../src/layer/layer.ts","../src/layer/scrollbar-helper.ts","../src/layer/wrap.ts","../src/layer/layer-manager.ts","../src/list/layout/nest.ts","../src/list/nest.ts","../src/list/layout/flat.ts","../src/list/layout/index.ts","../src/comment/height-limit.ts","../src/comment/renders/header.ts","../src/components/action-btn.ts","../src/comment/renders/actions.ts","../src/comment/renders/index.ts","../src/comment/renders/avatar.ts","../src/comment/renders/content.ts","../src/comment/renders/reply-at.ts","../src/comment/renders/reply-to.ts","../src/comment/renders/pending.ts","../src/comment/render.ts","../src/comment/comment.html?raw","../src/comment/actions.ts","../src/comment/comment-node.ts","../src/lib/detect.ts","../src/components/read-more-btn.ts","../src/list/paginator/read-more.ts","../src/components/pagination.ts","../src/list/paginator/up-down.ts","../src/list/page.ts","../src/list/list.ts","../src/list/list.html?raw","../src/list/comment.ts","../src/layer/sidebar-layer.ts","../src/layer/sidebar-layer.html?raw","../src/services/sidebar.ts","../src/plugins/index.ts","../src/services/index.ts","../src/services/data.ts","../src/api/handler.ts","../src/services/i18n.ts","../src/services/user.ts","../src/services/editor.ts","../src/services/list.ts","../src/services/layer.ts","../src/plugins/markdown.ts","../src/plugins/admin-only-elem.ts","../src/plugins/notifies.ts","../src/mount.ts","../src/plugins/mount-error.ts","../src/lib/watch-conf.ts","../src/artalk.ts","../src/services/events.ts","../src/services/config.ts","../src/main.ts"],"sourcesContent":["export function createElement<E extends HTMLElement = HTMLElement>(htmlStr: string = ''): E {\n  const div = document.createElement('div')\n  div.innerHTML = htmlStr.trim()\n  return (div.firstElementChild || div) as E\n}\n\nexport function getHeight(el: HTMLElement): number {\n  const num = parseFloat(getComputedStyle(el, null).height.replace('px', ''))\n  return num || 0 // NaN -> 0\n}\n\nexport function htmlEncode(str: string) {\n  const temp = document.createElement('div')\n  temp.innerText = str\n  const output = temp.innerHTML\n  return output\n}\n\nexport function htmlDecode(str: string) {\n  const temp = document.createElement('div')\n  temp.innerHTML = str\n  const output = temp.innerText\n  return output\n}\n\nexport function getQueryParam(name: string) {\n  const match = RegExp(`[?&]${name}=([^&]*)`).exec(window.location.search)\n  return match && decodeURIComponent(match[1].replace(/\\+/g, ' '))\n}\n\nexport function getOffset(el: HTMLElement, relativeTo?: HTMLElement) {\n  const getOffsetRecursive = (element: HTMLElement): { top: number; left: number } => {\n    const rect = element.getBoundingClientRect()\n    const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft\n    const scrollTop = window.pageYOffset || document.documentElement.scrollTop\n    return {\n      top: rect.top + scrollTop,\n      left: rect.left + scrollLeft,\n    }\n  }\n\n  const elOffset = getOffsetRecursive(el)\n  if (!relativeTo) return elOffset\n\n  const relativeToOffset = getOffsetRecursive(relativeTo)\n\n  return {\n    top: elOffset.top - relativeToOffset.top,\n    left: elOffset.left - relativeToOffset.left,\n  }\n}\n\nexport function padWithZeros(vNumber: number, width: number) {\n  let numAsString = vNumber.toString()\n  while (numAsString.length < width) {\n    numAsString = `0${numAsString}`\n  }\n  return numAsString\n}\n\nexport function dateFormat(date: Date) {\n  const vDay = padWithZeros(date.getDate(), 2)\n  const vMonth = padWithZeros(date.getMonth() + 1, 2)\n  const vYear = padWithZeros(date.getFullYear(), 2)\n  // var vHour = padWithZeros(date.getHours(), 2);\n  // var vMinute = padWithZeros(date.getMinutes(), 2);\n  // var vSecond = padWithZeros(date.getSeconds(), 2);\n  return `${vYear}-${vMonth}-${vDay}`\n}\n\nexport function timeAgo(date: Date, $t = (n: any) => n) {\n  try {\n    const oldTime = date.getTime()\n    const currTime = new Date().getTime()\n    const diffValue = currTime - oldTime\n\n    const days = Math.floor(diffValue / (24 * 3600 * 1000))\n    if (days === 0) {\n      // 计算相差小时数\n      const leave1 = diffValue % (24 * 3600 * 1000) // 计算天数后剩余的毫秒数\n      const hours = Math.floor(leave1 / (3600 * 1000))\n      if (hours === 0) {\n        // 计算相差分钟数\n        const leave2 = leave1 % (3600 * 1000) // 计算小时数后剩余的毫秒数\n        const minutes = Math.floor(leave2 / (60 * 1000))\n        if (minutes === 0) {\n          // 计算相差秒数\n          const leave3 = leave2 % (60 * 1000) // 计算分钟数后剩余的毫秒数\n          const seconds = Math.round(leave3 / 1000)\n          if (seconds < 10) return $t('now')\n          return `${seconds} ${$t('seconds')}`\n        }\n        return `${minutes} ${$t('minutes')}`\n      }\n      return `${hours} ${$t('hours')}`\n    }\n    if (days < 0) return $t('now')\n\n    if (days < 8) {\n      return `${days} ${$t('days')}`\n    }\n\n    return dateFormat(date)\n  } catch (error) {\n    console.error(error)\n    return ' - '\n  }\n}\n\nexport function getGravatarURL(opts: { params: string; mirror: string; emailHash: string }) {\n  return `${opts.mirror.replace(/\\/$/, '')}/${opts.emailHash}?${opts.params.replace(/^\\?/, '')}`\n}\n\nexport function sleep(ms: number) {\n  return new Promise((resolve) => {\n    setTimeout(resolve, ms)\n  })\n}\n\n/** 版本号比较（a < b :-1 | 0 | b < a :1） */\nexport function versionCompare(a: string, b: string) {\n  const pa = a.split('.')\n  const pb = b.split('.')\n  for (let i = 0; i < 3; i++) {\n    const na = Number(pa[i])\n    const nb = Number(pb[i])\n    if (na > nb) return 1\n    if (nb > na) return -1\n    if (!Number.isNaN(na) && Number.isNaN(nb)) return 1\n    if (Number.isNaN(na) && !Number.isNaN(nb)) return -1\n  }\n  return 0\n}\n\n/** 获取修正后的 UserAgent */\nexport async function getCorrectUserAgent() {\n  const uaRaw = navigator.userAgent\n  if (!(navigator as any).userAgentData || !(navigator as any).userAgentData.getHighEntropyValues) {\n    return uaRaw\n  }\n\n  // @link https://web.dev/migrate-to-ua-ch/\n  // @link https://web.dev/user-agent-client-hints/\n  const uaData = (navigator as any).userAgentData\n  let uaGot: any = null\n  try {\n    uaGot = await uaData.getHighEntropyValues(['platformVersion'])\n  } catch (err) {\n    console.error(err)\n    return uaRaw\n  }\n  const majorPlatformVersion = Number(uaGot.platformVersion.split('.')[0])\n\n  if (uaData.platform === 'Windows') {\n    if (majorPlatformVersion >= 13) {\n      // @link https://docs.microsoft.com/en-us/microsoft-edge/web-platform/how-to-detect-win11\n      // @date 2022-4-29\n      // Win 11 样本：\"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36\"\n      return uaRaw.replace(/Windows NT 10.0/, 'Windows NT 11.0')\n    }\n  }\n  if (uaData.platform === 'macOS') {\n    if (majorPlatformVersion >= 11) {\n      // 11 => BigSur\n      // @date 2022-4-29\n      // (Intel Chip) macOS 12.3 样本：\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36\"\n      // (Arm Chip) macOS 样本：\"Mozilla/5.0 (Macintosh; ARM Mac OS X 10_15_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.2 Safari/605.1.15\"\n      return uaRaw.replace(\n        /(Mac OS X \\d+_\\d+_\\d+|Mac OS X)/,\n        `Mac OS X ${uaGot.platformVersion.replace(/\\./g, '_')}`,\n      )\n    }\n  }\n\n  return uaRaw\n}\n\n/** 是否为完整的 URL */\nexport function isValidURL(urlRaw: string) {\n  // @link https://www.rfc-editor.org/rfc/rfc3986\n  let url: URL\n  try {\n    url = new URL(urlRaw)\n  } catch (_) {\n    return false\n  }\n  return url.protocol === 'http:' || url.protocol === 'https:'\n}\n\n/** 获取基于 conf.server 的 URL */\nexport function getURLBasedOnApi(opts: { base: string; path: string }) {\n  return getURLBasedOn(opts.base, opts.path)\n}\n\n/** 获取基于某个 baseURL 的 URL */\nexport function getURLBasedOn(baseURL: string, path: string) {\n  return `${baseURL.replace(/\\/$/, '')}/${path.replace(/^\\//, '')}`\n}\n","const en = {\n  /* Editor */\n  placeholder: 'Leave a comment',\n  noComment: 'No Comment',\n  send: 'Send',\n  signIn: 'Sign in',\n  signUp: 'Sign up',\n  save: 'Save',\n  nick: 'Nickname',\n  email: 'Email',\n  link: 'Website',\n  emoticon: 'Emoji',\n  preview: 'Preview',\n  uploadImage: 'Upload Image',\n  uploadFail: 'Upload Failed',\n  commentFail: 'Failed to comment',\n  restoredMsg: 'Content has been restored',\n  onlyAdminCanReply: 'Only admin can reply',\n  uploadLoginMsg: 'Please fill in your name and email to upload',\n\n  /* List */\n  counter: '{count} Comments',\n  sortLatest: 'Latest',\n  sortOldest: 'Oldest',\n  sortBest: 'Best',\n  sortAuthor: 'Author',\n  openComment: 'Open Comment',\n  closeComment: 'Close Comment',\n  listLoadFailMsg: 'Failed to load comments',\n  listRetry: 'Retry',\n  loadMore: 'Load More',\n\n  /* Comment */\n  admin: 'Admin',\n  reply: 'Reply',\n  voteUp: 'Up',\n  voteDown: 'Down',\n  voteFail: 'Vote Failed',\n  readMore: 'Read More',\n  actionConfirm: 'Confirm',\n  collapse: 'Collapse',\n  collapsed: 'Collapsed',\n  collapsedMsg: 'This comment has been collapsed',\n  expand: 'Expand',\n  approved: 'Approved',\n  pending: 'Pending',\n  pendingMsg: 'Pending, visible only to commenter.',\n  edit: 'Edit',\n  editCancel: 'Cancel Edit',\n  delete: 'Delete',\n  deleteConfirm: 'Confirm',\n  pin: 'Pin',\n  unpin: 'Unpin',\n\n  /* Time */\n  seconds: 'seconds ago',\n  minutes: 'minutes ago',\n  hours: 'hours ago',\n  days: 'days ago',\n  now: 'just now',\n\n  /* Checker */\n  adminCheck: 'Enter admin password:',\n  captchaCheck: 'Enter the CAPTCHA to continue:',\n  confirm: 'Confirm',\n  cancel: 'Cancel',\n\n  /* Sidebar */\n  msgCenter: 'Messages',\n  ctrlCenter: 'Dashboard',\n\n  /* Auth */\n  userProfile: 'Profile',\n  noAccountPrompt: \"Don't have an account?\",\n  haveAccountPrompt: 'Already have an account?',\n  forgetPassword: 'Forget Password',\n  resetPassword: 'Reset Password',\n  changePassword: 'Change Password',\n  confirmPassword: 'Confirm Password',\n  passwordMismatch: 'Passwords do not match',\n  verificationCode: 'Verification Code',\n  verifySend: 'Send Code',\n  verifyResend: 'Resend',\n  waitSeconds: 'Wait {seconds}s',\n  emailVerified: 'Email has been verified',\n  password: 'Password',\n  username: 'Username',\n  nextStep: 'Next Step',\n  skipVerify: 'Skip verification',\n  logoutConfirm: 'Are you sure to logout?',\n  accountMergeNotice: 'Your email has multiple accounts with different id.',\n  accountMergeSelectOne: 'Please select one you want to merge all the data into it.',\n  accountMergeConfirm: 'All data will be merged into one account, the id is {id}.',\n  dismiss: 'Dismiss',\n  merge: 'Merge',\n\n  /* General */\n  client: 'Client',\n  server: 'Server',\n  loading: 'Loading',\n  loadFail: 'Load Failed',\n  editing: 'Editing',\n  editFail: 'Edit Failed',\n  deleting: 'Deleting',\n  deleteFail: 'Delete Failed',\n  reqGot: 'Request got',\n  reqAborted: 'Request timed out or terminated unexpectedly',\n  updateMsg: 'Please update Artalk {name} to get the best experience!',\n  currentVersion: 'Current Version',\n  ignore: 'Ignore',\n  open: 'Open',\n  openName: 'Open {name}',\n}\n\nexport type I18n = typeof en\nexport type I18nKeys = keyof I18n\n\nexport default en\n","import type { I18n } from '.'\n\nexport const GLOBAL_LOCALES_KEY = 'ArtalkI18n'\n\nexport function defineLocaleExternal(lang: string, locale: I18n, aliases?: string[]) {\n  if (!window[GLOBAL_LOCALES_KEY]) window[GLOBAL_LOCALES_KEY] = {}\n  window[GLOBAL_LOCALES_KEY][lang] = locale\n  if (aliases)\n    aliases.forEach((l) => {\n      window[GLOBAL_LOCALES_KEY][l] = locale\n    })\n  return locale\n}\n","import * as Utils from '../lib/utils'\nimport en, { I18n, I18nKeys } from './en'\nimport zhCN from './zh-CN'\nimport { GLOBAL_LOCALES_KEY } from './external'\n\nexport type * from './en'\n\n// @note the key of language is followed by `ISO 639`\n// https://en.wikipedia.org/wiki/ISO_639\n// https://datatracker.ietf.org/doc/html/rfc5646#section-2.1\nexport const internal = {\n  en,\n  'en-US': en,\n  'zh-CN': zhCN,\n}\n\n/**\n * find a locale object by language name\n */\nexport function findLocaleSet(lang: string): I18n {\n  // normalize a key of language to `ISO 639`\n  lang = lang.replace(\n    /^([a-zA-Z]+)(-[a-zA-Z]+)?$/,\n    (_, p1: string, p2: string) => p1.toLowerCase() + (p2 || '').toUpperCase(),\n  )\n\n  // internal finding\n  if (internal[lang]) {\n    return internal[lang]\n  }\n\n  // external finding\n  if (window[GLOBAL_LOCALES_KEY] && window[GLOBAL_LOCALES_KEY][lang]) {\n    return window[GLOBAL_LOCALES_KEY][lang]\n  }\n\n  // case when not found:\n  // use `en` by default\n  return internal.en\n}\n\n/**\n * System locale setting\n */\nlet LocaleConf: I18n | string = 'en'\nlet LocaleDict: I18n = findLocaleSet(LocaleConf) // en by default\n\n/**\n * Set system locale\n */\nexport function setLocale(locale: I18n | string) {\n  if (locale === LocaleConf) return\n  LocaleConf = locale\n  LocaleDict = typeof locale === 'string' ? findLocaleSet(locale) : locale\n}\n\n/**\n * Get an i18n message by key\n */\nexport function t(key: I18nKeys, args: { [key: string]: string } = {}) {\n  let str = LocaleDict?.[key] || key\n  str = str.replace(/\\{\\s*(\\w+?)\\s*\\}/g, (_, token) => args[token] || '')\n\n  return Utils.htmlEncode(str)\n}\n\nexport default t\n","import type { I18n } from '.'\n\nconst zhCN: I18n = {\n  /* Editor */\n  placeholder: '键入内容...',\n  noComment: '「此时无声胜有声」',\n  send: '发送',\n  signIn: '登录',\n  signUp: '注册',\n  save: '保存',\n  nick: '昵称',\n  email: '邮箱',\n  link: '网址',\n  emoticon: '表情',\n  preview: '预览',\n  uploadImage: '上传图片',\n  uploadFail: '上传失败',\n  commentFail: '评论失败',\n  restoredMsg: '内容已自动恢复',\n  onlyAdminCanReply: '仅管理员可评论',\n  uploadLoginMsg: '填入你的名字邮箱才能上传哦',\n\n  /* List */\n  counter: '{count} 条评论',\n  sortLatest: '最新',\n  sortOldest: '最早',\n  sortBest: '最热',\n  sortAuthor: '作者',\n  openComment: '打开评论',\n  closeComment: '关闭评论',\n  listLoadFailMsg: '无法获取评论列表数据',\n  listRetry: '点击重新获取',\n  loadMore: '加载更多',\n\n  /* Comment */\n  admin: '管理员',\n  reply: '回复',\n  voteUp: '赞同',\n  voteDown: '反对',\n  voteFail: '投票失败',\n  readMore: '阅读更多',\n  actionConfirm: '确认操作',\n  collapse: '折叠',\n  collapsed: '已折叠',\n  collapsedMsg: '该评论已被系统或管理员折叠',\n  expand: '展开',\n  approved: '已审',\n  pending: '待审',\n  pendingMsg: '审核中，仅本人可见。',\n  edit: '编辑',\n  editCancel: '取消编辑',\n  delete: '删除',\n  deleteConfirm: '确认删除',\n  pin: '置顶',\n  unpin: '取消置顶',\n\n  /* Time */\n  seconds: '秒前',\n  minutes: '分钟前',\n  hours: '小时前',\n  days: '天前',\n  now: '刚刚',\n\n  /* Checker */\n  adminCheck: '键入密码来验证管理员身份：',\n  captchaCheck: '键入验证码继续：',\n  confirm: '确认',\n  cancel: '取消',\n\n  /* Sidebar */\n  msgCenter: '通知中心',\n  ctrlCenter: '控制中心',\n\n  /* Auth */\n  userProfile: '个人资料',\n  noAccountPrompt: '没有账号？',\n  haveAccountPrompt: '已有账号？',\n  forgetPassword: '忘记密码',\n  resetPassword: '重置密码',\n  changePassword: '修改密码',\n  confirmPassword: '确认密码',\n  passwordMismatch: '两次输入的密码不一致',\n  verificationCode: '验证码',\n  verifySend: '发送验证码',\n  verifyResend: '重新发送',\n  waitSeconds: '等待 {seconds}秒',\n  emailVerified: '邮箱已验证',\n  password: '密码',\n  username: '用户名',\n  nextStep: '下一步',\n  skipVerify: '跳过验证',\n  logoutConfirm: '确定要退出登录吗？',\n  accountMergeNotice: '您的电子邮件下有多个不同 ID 的账户。',\n  accountMergeSelectOne: '请选择将所有数据合并到其中的一个。',\n  accountMergeConfirm: '所有数据将合并到 ID 为 {id} 的账户中。',\n  dismiss: '忽略',\n  merge: '合并',\n\n  /* General */\n  client: '客户端',\n  server: '服务器',\n  loading: '加载中',\n  loadFail: '加载失败',\n  editing: '修改中',\n  editFail: '修改失败',\n  deleting: '删除中',\n  deleteFail: '删除失败',\n  reqGot: '请求响应',\n  reqAborted: '请求超时或意外终止',\n  updateMsg: '请更新 Artalk {name} 以获得更好的体验！',\n  currentVersion: '当前版本',\n  ignore: '忽略',\n  open: '打开',\n  openName: '打开{name}',\n}\n\nexport default zhCN\n","'use strict';\n\nvar escapes = {\n  '&': '&amp;',\n  '<': '&lt;',\n  '>': '&gt;',\n  '\"': '&quot;',\n  \"'\": '&#39;'\n};\nvar unescapes = {\n  '&amp;': '&',\n  '&lt;': '<',\n  '&gt;': '>',\n  '&quot;': '\"',\n  '&#39;': \"'\"\n};\nvar rescaped = /(&amp;|&lt;|&gt;|&quot;|&#39;)/g;\nvar runescaped = /[&<>\"']/g;\n\nfunction escapeHtmlChar (match) {\n  return escapes[match];\n}\nfunction unescapeHtmlChar (match) {\n  return unescapes[match];\n}\n\nfunction escapeHtml (text) {\n  return text == null ? '' : String(text).replace(runescaped, escapeHtmlChar);\n}\n\nfunction unescapeHtml (html) {\n  return html == null ? '' : String(html).replace(rescaped, unescapeHtmlChar);\n}\n\nescapeHtml.options = unescapeHtml.options = {};\n\nmodule.exports = {\n  encode: escapeHtml,\n  escape: escapeHtml,\n  decode: unescapeHtml,\n  unescape: unescapeHtml,\n  version: '1.0.0-browser'\n};\n","'use strict';\n\nfunction assignment (result) {\n  var stack = Array.prototype.slice.call(arguments, 1);\n  var item;\n  var key;\n  while (stack.length) {\n    item = stack.shift();\n    for (key in item) {\n      if (item.hasOwnProperty(key)) {\n        if (Object.prototype.toString.call(result[key]) === '[object Object]') {\n          result[key] = assignment(result[key], item[key]);\n        } else {\n          result[key] = item[key];\n        }\n      }\n    }\n  }\n  return result;\n}\n\nmodule.exports = assignment;\n","'use strict';\n\nmodule.exports = function lowercase (string) {\n  return typeof string === 'string' ? string.toLowerCase() : string;\n};\n","'use strict';\n\nfunction toMap (list) {\n  return list.reduce(asKey, {});\n}\n\nfunction asKey (accumulator, item) {\n  accumulator[item] = true;\n  return accumulator;\n}\n\nmodule.exports = toMap;\n","'use strict';\n\nvar toMap = require('./toMap');\nvar uris = ['background', 'base', 'cite', 'href', 'longdesc', 'src', 'usemap'];\n\nmodule.exports = {\n  uris: toMap(uris) // attributes that have an href and hence need to be sanitized\n};\n","'use strict';\n\nvar toMap = require('./toMap');\nvar voids = ['area', 'br', 'col', 'hr', 'img', 'wbr', 'input', 'base', 'basefont', 'link', 'meta'];\n\nmodule.exports = {\n  voids: toMap(voids)\n};\n","'use strict';\n\nvar he = require('he');\nvar lowercase = require('./lowercase');\nvar attributes = require('./attributes');\nvar elements = require('./elements');\nvar rstart = /^<\\s*([\\w:-]+)((?:\\s+[\\w:-]+(?:\\s*=\\s*(?:(?:\"[^\"]*\")|(?:'[^']*')|[^>\\s]+))?)*)\\s*(\\/?)\\s*>/;\nvar rend = /^<\\s*\\/\\s*([\\w:-]+)[^>]*>/;\nvar rattrs = /([\\w:-]+)(?:\\s*=\\s*(?:(?:\"((?:[^\"])*)\")|(?:'((?:[^'])*)')|([^>\\s]+)))?/g;\nvar rtag = /^</;\nvar rtagend = /^<\\s*\\//;\n\nfunction createStack () {\n  var stack = [];\n  stack.lastItem = function lastItem () {\n    return stack[stack.length - 1];\n  };\n  return stack;\n}\n\nfunction parser (html, handler) {\n  var stack = createStack();\n  var last = html;\n  var chars;\n\n  while (html) {\n    parsePart();\n  }\n  parseEndTag(); // clean up any remaining tags\n\n  function parsePart () {\n    chars = true;\n    parseTag();\n\n    var same = html === last;\n    last = html;\n\n    if (same) { // discard, because it's invalid\n      html = '';\n    }\n  }\n\n  function parseTag () {\n    if (html.substr(0, 4) === '<!--') { // comments\n      parseComment();\n    } else if (rtagend.test(html)) {\n      parseEdge(rend, parseEndTag);\n    } else if (rtag.test(html)) {\n      parseEdge(rstart, parseStartTag);\n    }\n    parseTagDecode();\n  }\n\n  function parseEdge (regex, parser) {\n    var match = html.match(regex);\n    if (match) {\n      html = html.substring(match[0].length);\n      match[0].replace(regex, parser);\n      chars = false;\n    }\n  }\n\n  function parseComment () {\n    var index = html.indexOf('-->');\n    if (index >= 0) {\n      if (handler.comment) {\n        handler.comment(html.substring(4, index));\n      }\n      html = html.substring(index + 3);\n      chars = false;\n    }\n  }\n\n  function parseTagDecode () {\n    if (!chars) {\n      return;\n    }\n    var text;\n    var index = html.indexOf('<');\n    if (index >= 0) {\n      text = html.substring(0, index);\n      html = html.substring(index);\n    } else {\n      text = html;\n      html = '';\n    }\n    if (handler.chars) {\n      handler.chars(text);\n    }\n  }\n\n  function parseStartTag (tag, tagName, rest, unary) {\n    var attrs = {};\n    var low = lowercase(tagName);\n    var u = elements.voids[low] || !!unary;\n\n    rest.replace(rattrs, attrReplacer);\n\n    if (!u) {\n      stack.push(low);\n    }\n    if (handler.start) {\n      handler.start(low, attrs, u);\n    }\n\n    function attrReplacer (match, name, doubleQuotedValue, singleQuotedValue, unquotedValue) {\n      if (doubleQuotedValue === void 0 && singleQuotedValue === void 0 && unquotedValue === void 0) {\n        attrs[name] = void 0; // attribute is like <button disabled></button>\n      } else {\n        attrs[name] = he.decode(doubleQuotedValue || singleQuotedValue || unquotedValue || '');\n      }\n    }\n  }\n\n  function parseEndTag (tag, tagName) {\n    var i;\n    var pos = 0;\n    var low = lowercase(tagName);\n    if (low) {\n      for (pos = stack.length - 1; pos >= 0; pos--) {\n        if (stack[pos] === low) {\n          break; // find the closest opened tag of the same type\n        }\n      }\n    }\n    if (pos >= 0) {\n      for (i = stack.length - 1; i >= pos; i--) {\n        if (handler.end) { // close all the open elements, up the stack\n          handler.end(stack[i]);\n        }\n      }\n      stack.length = pos;\n    }\n  }\n}\n\nmodule.exports = parser;\n","'use strict';\n\nvar he = require('he');\nvar lowercase = require('./lowercase');\nvar attributes = require('./attributes');\nvar elements = require('./elements');\n\nfunction sanitizer (buffer, options) {\n  var last;\n  var context;\n  var o = options || {};\n\n  reset();\n\n  return {\n    start: start,\n    end: end,\n    chars: chars\n  };\n\n  function out (value) {\n    buffer.push(value);\n  }\n\n  function start (tag, attrs, unary) {\n    var low = lowercase(tag);\n\n    if (context.ignoring) {\n      ignore(low); return;\n    }\n    if ((o.allowedTags || []).indexOf(low) === -1) {\n      ignore(low); return;\n    }\n    if (o.filter && !o.filter({ tag: low, attrs: attrs })) {\n      ignore(low); return;\n    }\n\n    out('<');\n    out(low);\n    Object.keys(attrs).forEach(parse);\n    out(unary ? '/>' : '>');\n\n    function parse (key) {\n      var value = attrs[key];\n      var classesOk = (o.allowedClasses || {})[low] || [];\n      var attrsOk = (o.allowedAttributes || {})[low] || [];\n      var valid;\n      var lkey = lowercase(key);\n      if (lkey === 'class' && attrsOk.indexOf(lkey) === -1) {\n        value = value.split(' ').filter(isValidClass).join(' ').trim();\n        valid = value.length;\n      } else {\n        valid = attrsOk.indexOf(lkey) !== -1 && (attributes.uris[lkey] !== true || testUrl(value));\n      }\n      if (valid) {\n        out(' ');\n        out(key);\n        if (typeof value === 'string') {\n          out('=\"');\n          out(he.encode(value));\n          out('\"');\n        }\n      }\n      function isValidClass (className) {\n        return classesOk && classesOk.indexOf(className) !== -1;\n      }\n    }\n  }\n\n  function end (tag) {\n    var low = lowercase(tag);\n    var allowed = (o.allowedTags || []).indexOf(low) !== -1;\n    if (allowed) {\n      if (context.ignoring === false) {\n        out('</');\n        out(low);\n        out('>');\n      } else {\n        unignore(low);\n      }\n    } else {\n      unignore(low);\n    }\n  }\n\n  function testUrl (text) {\n    var start = text[0];\n    if (start === '#' || start === '/') {\n      return true;\n    }\n    var colon = text.indexOf(':');\n    if (colon === -1) {\n      return true;\n    }\n    var questionmark = text.indexOf('?');\n    if (questionmark !== -1 && colon > questionmark) {\n      return true;\n    }\n    var hash = text.indexOf('#');\n    if (hash !== -1 && colon > hash) {\n      return true;\n    }\n    return o.allowedSchemes.some(matches);\n\n    function matches (scheme) {\n      return text.indexOf(scheme + ':') === 0;\n    }\n  }\n\n  function chars (text) {\n    if (context.ignoring === false) {\n      out(o.transformText ? o.transformText(text) : text);\n    }\n  }\n\n  function ignore (tag) {\n    if (elements.voids[tag]) {\n      return;\n    }\n    if (context.ignoring === false) {\n      context = { ignoring: tag, depth: 1 };\n    } else if (context.ignoring === tag) {\n      context.depth++;\n    }\n  }\n\n  function unignore (tag) {\n    if (context.ignoring === tag) {\n      if (--context.depth <= 0) {\n        reset();\n      }\n    }\n  }\n\n  function reset () {\n    context = { ignoring: false, depth: 0 };\n  }\n}\n\nmodule.exports = sanitizer;\n","'use strict';\n\nvar he = require('he');\nvar assign = require('assignment');\nvar parser = require('./parser');\nvar sanitizer = require('./sanitizer');\nvar defaults = require('./defaults');\n\nfunction insane (html, options, strict) {\n  var buffer = [];\n  var configuration = strict === true ? options : assign({}, defaults, options);\n  var handler = sanitizer(buffer, configuration);\n\n  parser(html, handler);\n\n  return buffer.join('');\n}\n\ninsane.defaults = defaults;\nmodule.exports = insane;\n","'use strict';\n\nvar defaults = {\n  allowedAttributes: {\n    a: ['href', 'name', 'target', 'title', 'aria-label'],\n    iframe: ['allowfullscreen', 'frameborder', 'src'],\n    img: ['src', 'alt', 'title', 'aria-label']\n  },\n  allowedClasses: {},\n  allowedSchemes: ['http', 'https', 'mailto'],\n  allowedTags: [\n    'a', 'abbr', 'article', 'b', 'blockquote', 'br', 'caption', 'code', 'del', 'details', 'div', 'em',\n    'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'ins', 'kbd', 'li', 'main', 'mark',\n    'ol', 'p', 'pre', 'section', 'span', 'strike', 'strong', 'sub', 'summary', 'sup', 'table',\n    'tbody', 'td', 'th', 'thead', 'tr', 'u', 'ul'\n  ],\n  filter: null\n};\n\nmodule.exports = defaults;\n","import insane from 'insane'\n\nconst insaneOptions = {\n  allowedClasses: {},\n  // @refer CVE-2018-8495\n  // @link https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-8495\n  // @link https://leucosite.com/Microsoft-Edge-RCE/\n  // @link https://medium.com/@knownsec404team/analysis-of-the-security-issues-of-url-scheme-in-pc-from-cve-2018-8495-934478a36756\n  allowedSchemes: [\n    'http',\n    'https',\n    'mailto',\n    'data', // for support base64 encoded image (安全性有待考虑)\n  ],\n  allowedTags: [\n    'a',\n    'abbr',\n    'article',\n    'b',\n    'blockquote',\n    'br',\n    'caption',\n    'code',\n    'del',\n    'details',\n    'div',\n    'em',\n    'h1',\n    'h2',\n    'h3',\n    'h4',\n    'h5',\n    'h6',\n    'hr',\n    'i',\n    'img',\n    'ins',\n    'kbd',\n    'li',\n    'main',\n    'mark',\n    'ol',\n    'p',\n    'pre',\n    'section',\n    'span',\n    'strike',\n    'strong',\n    'sub',\n    'summary',\n    'sup',\n    'table',\n    'tbody',\n    'td',\n    'th',\n    'thead',\n    'tr',\n    'u',\n    'ul',\n  ],\n  allowedAttributes: {\n    '*': ['title', 'accesskey'],\n    a: ['href', 'name', 'target', 'aria-label', 'rel'],\n    img: ['src', 'alt', 'title', 'atk-emoticon', 'aria-label', 'data-src', 'class', 'loading'],\n    // for code highlight\n    code: ['class'],\n    span: ['class', 'style'],\n  },\n  filter: (node) => {\n    // class whitelist\n    const allowed = [\n      ['code', /^hljs\\W+language-(.*)$/],\n      ['span', /^(hljs-.*)$/],\n      ['img', /^lazyload$/],\n    ]\n    allowed.forEach(([tag, reg]) => {\n      if (node.tag === tag && !!node.attrs.class && !(reg as RegExp).test(node.attrs.class)) {\n        delete node.attrs.class\n      }\n    })\n\n    // allow <span> set color sty\n    if (\n      node.tag === 'span' &&\n      !!node.attrs.style &&\n      !/^color:(\\W+)?#[0-9a-f]{3,6};?$/i.test(node.attrs.style)\n    ) {\n      delete node.attrs.style\n    }\n\n    return true\n  },\n}\n\nexport function sanitize(content: string): string {\n  // @link https://github.com/markedjs/marked/discussions/1232\n  // @link https://gist.github.com/lionel-rowe/bb384465ba4e4c81a9c8dada84167225\n  return insane(content, insaneOptions)\n}\n","(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n  typeof define === 'function' && define.amd ? define(factory) :\n  (global.hanabi = factory());\n}(this, (function () { 'use strict';\n\nfunction createCommonjsModule(fn, module) {\n\treturn module = { exports: {} }, fn(module, module.exports), module.exports;\n}\n\nvar index$1 = createCommonjsModule(function (module) {\n'use strict';\n\nvar comment = module.exports = function () {\n\treturn new RegExp('(?:' + comment.line().source + ')|(?:' + comment.block().source + ')', 'gm');\n};\n\ncomment.line = function () {\n\treturn /(?:^|\\s)\\/\\/(.+?)$/gm;\n};\n\ncomment.block = function () {\n\treturn /\\/\\*([\\S\\s]*?)\\*\\//gm;\n};\n});\n\nvar defaultColors = ['23AC69', '91C132', 'F19726', 'E8552D', '1AAB8E', 'E1147F', '2980C1', '1BA1E6', '9FA0A0', 'F19726', 'E30B20', 'E30B20', 'A3338B'];\n\nvar index = function (input, ref) {\n  if ( ref === void 0 ) ref = {};\n  var colors = ref.colors; if ( colors === void 0 ) colors = defaultColors;\n\n  var index = 0;\n  var cache = {};\n  var wordRe = /[\\u4E00-\\u9FFF\\u3400-\\u4dbf\\uf900-\\ufaff\\u3040-\\u309f\\uac00-\\ud7af\\u0400-\\u04FF]+|\\w+/;\n  var leftAngleRe = /</;\n\n  var re = new RegExp((\"(\" + (wordRe.source) + \"|\" + (leftAngleRe.source) + \")|(\" + (index$1().source) + \")\"), 'gmi');\n  return input\n  .replace(re, function (m, word, cm) {\n    if (cm) {\n      return toComment(cm)\n    }\n\n    if (word === '<') {\n      return '&lt;'\n    }\n    var color;\n    if (cache[word]) {\n      color = cache[word];\n    } else {\n      color = colors[index];\n      cache[word] = color;\n    }\n\n    var out = \"<span style=\\\"color: #\" + color + \"\\\">\" + word + \"</span>\";\n    index = ++index % colors.length;\n    return out\n  })\n};\n\nfunction toComment(cm) {\n  return (\"<span style=\\\"color: slategray\\\">\" + cm + \"</span>\")\n}\n\nreturn index;\n\n})));\n","import hanabi from 'hanabi'\n\nexport function renderCode(code: string) {\n  return hanabi(code)\n}\n","import { marked, Tokens } from 'marked'\nimport { renderCode } from './highlight'\nimport type { Config } from '@/types'\n\nexport interface RendererOptions {\n  imgLazyLoad: Config['imgLazyLoad']\n}\n\nexport function getRenderer(options: RendererOptions) {\n  const renderer = new marked.Renderer()\n  renderer.link = markedLinkRenderer(renderer, renderer.link)\n  renderer.code = markedCodeRenderer()\n  renderer.image = markedImageRenderer(renderer, renderer.image, options)\n  return renderer\n}\n\nconst markedLinkRenderer =\n  (renderer: any, orgLinkRenderer: (args: Tokens.Link) => string) => (args: Tokens.Link) => {\n    const getLinkOrigin = (link: string) => {\n      try {\n        return new URL(link).origin\n      } catch {\n        return ''\n      }\n    }\n    const isSameOriginLink = getLinkOrigin(args.href) === window.location.origin\n    const html = orgLinkRenderer.call(renderer, args)\n    return html.replace(\n      /^<a /,\n      `<a target=\"_blank\" ${!isSameOriginLink ? `rel=\"noreferrer noopener nofollow\"` : ''} `,\n    )\n  }\n\nconst markedCodeRenderer =\n  () =>\n  ({ lang, text }: Tokens.Code): string => {\n    // Colorize the block only if the language is known to highlight.js\n    const realLang = !lang ? 'plaintext' : lang\n    let colorized = text\n    if ((window as any).hljs) {\n      if (realLang && (window as any).hljs.getLanguage(realLang)) {\n        colorized = (window as any).hljs.highlight(realLang, text).value\n      }\n    } else {\n      colorized = renderCode(text)\n    }\n\n    return (\n      `<pre rel=\"${realLang}\">\\n` +\n      `<code class=\"hljs language-${realLang}\">${colorized.replace(/&amp;/g, '&')}</code>\\n` +\n      `</pre>`\n    )\n  }\n\nconst markedImageRenderer =\n  (\n    renderer: any,\n    orgImageRenderer: (args: Tokens.Image) => string,\n    { imgLazyLoad }: RendererOptions,\n  ) =>\n  (args: Tokens.Image): string => {\n    const html = orgImageRenderer.call(renderer, args)\n    if (!imgLazyLoad) return html\n    if (imgLazyLoad === 'native' || (imgLazyLoad as any) === true)\n      return html.replace(/^<img /, '<img class=\"lazyload\" loading=\"lazy\" ')\n    if (imgLazyLoad === 'data-src')\n      return html.replace(/^<img /, '<img class=\"lazyload\" ').replace('src=', 'data-src=')\n    return html\n  }\n","import { Marked } from 'marked'\nimport type { MarkedOptions } from 'marked'\n\nimport { sanitize } from './sanitizer'\nimport { renderCode } from './highlight'\nimport { getRenderer } from './marked-renderer'\nimport type { Config } from '@/types'\n\ntype Replacer = (raw: string) => string\n\nlet instance: Marked | undefined\nlet replacers: Replacer[] = []\n\nconst markedOptions: MarkedOptions = {\n  gfm: true,\n  breaks: true,\n  async: false,\n}\n\n/** Get Marked instance */\nexport function getInstance() {\n  return instance\n}\n\nexport function setReplacers(arr: Replacer[]) {\n  replacers = arr\n}\n\nexport interface MarkedInitOptions {\n  markedOptions: Config['markedOptions']\n  imgLazyLoad: Config['imgLazyLoad']\n}\n\n/** 初始化 marked */\nexport function initMarked(options: MarkedInitOptions) {\n  try {\n    if (!Marked.name) return\n  } catch {\n    return\n  }\n\n  // @see https://github.com/markedjs/marked/blob/4afb228d956a415624c4e5554bb8f25d047676fe/src/Tokenizer.js#L329\n  const marked = new Marked()\n  marked.setOptions({\n    renderer: getRenderer({\n      imgLazyLoad: options.imgLazyLoad,\n    }),\n    ...markedOptions,\n    ...options.markedOptions,\n  })\n\n  instance = marked\n}\n\n/** 解析 markdown */\nexport default function marked(src: string): string {\n  let markedContent = getInstance()?.parse(src) as string\n  if (!markedContent) {\n    // 无 Markdown 模式简单处理\n    markedContent = simpleMarked(src)\n  }\n\n  let dest = sanitize(markedContent)\n\n  // 内容替换器\n  replacers.forEach((replacer) => {\n    if (typeof replacer === 'function') dest = replacer(dest)\n  })\n\n  return dest\n}\n\nfunction simpleMarked(src: string) {\n  return (\n    src\n      // .replace(/\\*\\*(.*?)\\*\\*/g, '<strong>$1</strong>')\n      .replace(\n        /```\\s*([^]+?.*?[^]+?[^]+?)```/g,\n        (_, code) => `<pre><code>${renderCode(code)}</code></pre>`,\n      )\n      // .replace(/`([^`]+?)`/g, '<code>$1</code>')\n      .replace(/!\\[(.*?)\\]\\((.*?)\\)/g, (_, alt, imgSrc) => `<img src=\"${imgSrc}\" alt=\"${alt}\" />`)\n      .replace(\n        /\\[(.*?)\\]\\((.*?)\\)/g,\n        (_, text, link) => `<a href=\"${link}\" target=\"_blank\">${text}</a>`,\n      )\n      .replace(/\\n/g, '<br>')\n  )\n}\n","import type {\n  Config,\n  ConfigPartial,\n  CommentData,\n  ListFetchParams,\n  Context as IContext,\n  SidebarShowPayload,\n  Services,\n} from './types'\nimport * as I18n from './i18n'\nimport * as marked from './lib/marked'\nimport { createInjectionContainer } from './lib/injection'\nimport type { CheckerCaptchaPayload, CheckerPayload } from './components/checker'\n\n/**\n * Artalk Context\n */\nclass Context implements IContext {\n  private _deps = createInjectionContainer<Services>()\n\n  constructor(private _$root: HTMLElement) {}\n\n  getEl(): HTMLElement {\n    return this._$root\n  }\n\n  destroy(): void {\n    this.trigger('unmounted')\n    while (this._$root.firstChild) {\n      this._$root.removeChild(this._$root.firstChild)\n    }\n  }\n\n  // -------------------------------------------------------------------\n  //  Dependency Injection\n  // -------------------------------------------------------------------\n  provide: IContext['provide'] = (key, impl, deps, opts) => {\n    this._deps.provide(key, impl, deps, opts)\n  }\n\n  inject: IContext['inject'] = (key) => {\n    return this._deps.inject(key)\n  }\n  get = this.inject\n\n  // -------------------------------------------------------------------\n  //  Event Manager\n  // -------------------------------------------------------------------\n  on: IContext['on'] = (name, handler) => {\n    this.inject('events').on(name, handler)\n  }\n\n  off: IContext['off'] = (name, handler) => {\n    this.inject('events').off(name, handler)\n  }\n\n  trigger: IContext['trigger'] = (name, payload) => {\n    this.inject('events').trigger(name, payload)\n  }\n\n  // -------------------------------------------------------------------\n  //  Configurations\n  // -------------------------------------------------------------------\n  getConf(): Config {\n    return this.inject('config').get()\n  }\n\n  updateConf(conf: ConfigPartial): void {\n    this.inject('config').update(conf)\n  }\n\n  watchConf<T extends (keyof Config)[]>(\n    keys: T,\n    effect: (conf: Pick<Config, T[number]>) => void,\n  ): void {\n    this.inject('config').watchConf(keys, effect)\n  }\n\n  getMarked() {\n    return marked.getInstance()\n  }\n\n  setDarkMode(darkMode: boolean | 'auto'): void {\n    this.updateConf({ darkMode })\n  }\n\n  get conf() {\n    return this.getConf()\n  }\n  set conf(val) {\n    console.error('Cannot set config directly, please call updateConf()')\n  }\n  get $root() {\n    return this.getEl()\n  }\n  set $root(val) {\n    console.error('set $root is prohibited')\n  }\n\n  // -------------------------------------------------------------------\n  //  I18n: Internationalization\n  // -------------------------------------------------------------------\n  $t(key: I18n.I18nKeys, args: { [key: string]: string } = {}): string {\n    return I18n.t(key, args)\n  }\n\n  // -------------------------------------------------------------------\n  //  HTTP API Client\n  // -------------------------------------------------------------------\n  getApi() {\n    return this.inject('api')\n  }\n\n  getApiHandlers() {\n    return this.inject('apiHandlers')\n  }\n\n  // -------------------------------------------------------------------\n  //  User Manager\n  // -------------------------------------------------------------------\n  getUser() {\n    return this.inject('user')\n  }\n\n  // -------------------------------------------------------------------\n  //  Data Manager\n  // -------------------------------------------------------------------\n  getData() {\n    return this.inject('data')\n  }\n\n  fetch(params: Partial<ListFetchParams>): void {\n    this.getData().fetchComments(params)\n  }\n\n  reload(): void {\n    this.getData().fetchComments({ offset: 0 })\n  }\n\n  // -------------------------------------------------------------------\n  //  List\n  // -------------------------------------------------------------------\n  listGotoFirst(): void {\n    this.trigger('list-goto-first')\n  }\n\n  getCommentList = this.getCommentNodes\n  getCommentNodes() {\n    return this.inject('list').getCommentNodes()\n  }\n\n  getCommentDataList = this.getComments\n  getComments() {\n    return this.getData().getComments()\n  }\n\n  // -------------------------------------------------------------------\n  //  Editor\n  // -------------------------------------------------------------------\n  replyComment(commentData: CommentData, $comment: HTMLElement): void {\n    this.inject('editor').setReplyComment(commentData, $comment)\n  }\n\n  editComment(commentData: CommentData, $comment: HTMLElement): void {\n    this.inject('editor').setEditComment(commentData, $comment)\n  }\n\n  editorShowLoading(): void {\n    this.inject('editor').showLoading()\n  }\n\n  editorHideLoading(): void {\n    this.inject('editor').hideLoading()\n  }\n\n  editorShowNotify(msg, type): void {\n    this.inject('editor').showNotify(msg, type)\n  }\n\n  editorResetState(): void {\n    this.inject('editor').resetState()\n  }\n\n  // -------------------------------------------------------------------\n  //  Sidebar\n  // -------------------------------------------------------------------\n  showSidebar(payload?: SidebarShowPayload): void {\n    this.inject('sidebar').show(payload)\n  }\n\n  hideSidebar(): void {\n    this.inject('sidebar').hide()\n  }\n\n  // -------------------------------------------------------------------\n  //  Checker\n  // -------------------------------------------------------------------\n  checkAdmin(payload: CheckerPayload): Promise<void> {\n    return this.inject('checkers').checkAdmin(payload)\n  }\n\n  checkCaptcha(payload: CheckerCaptchaPayload): Promise<void> {\n    return this.inject('checkers').checkCaptcha(payload)\n  }\n}\n\nexport default Context\n","type PrimitiveKey = string | number | symbol\ntype Services = { [key: PrimitiveKey]: any }\n\nexport type Constructor<T, S = Services, D extends readonly (keyof S)[] = any> = (\n  ...args: { [K in keyof D]: D[K] extends keyof S ? S[D[K]] : never }\n) => T\n\nexport type Lifecycle = 'transient' | 'singleton'\n\nexport interface Provider<T, S = Services> {\n  /** Implementation constructor */\n  impl: Constructor<T>\n\n  /** Dependency constructors */\n  deps: readonly (keyof S)[]\n\n  /** Lifecycle */\n  lifecycle: Lifecycle\n}\n\nexport interface ProvideFuncOptions {\n  /** Lifecycle (default: 'singleton') */\n  lifecycle?: Lifecycle\n}\n\nexport interface DependencyContainer<S = Services> {\n  provide<K extends keyof S, T extends S[K] = any, D extends readonly (keyof S)[] = any>(\n    key: K,\n    impl: Constructor<T, S, D>,\n    deps?: D,\n    opts?: ProvideFuncOptions,\n  ): void\n\n  inject<T = undefined, K extends keyof S = any>(key: K): T extends undefined ? S[K] : T\n}\n\nexport function createInjectionContainer<S = Services>(): DependencyContainer<S> {\n  const providers = new Map<PrimitiveKey, Provider<any, S>>()\n  const initializedDeps = new Map<PrimitiveKey, any>()\n\n  const provide: DependencyContainer<S>['provide'] = (key, impl, deps, opts = {}) => {\n    providers.set(key, { impl, deps: deps || [], lifecycle: opts.lifecycle || 'singleton' })\n  }\n\n  const inject: DependencyContainer<S>['inject'] = (key) => {\n    const provider = providers.get(key)\n    if (!provider) {\n      throw new Error(`No provide for ${String(key)}`)\n    }\n\n    if (provider.lifecycle === 'singleton' && initializedDeps.has(key)) {\n      return initializedDeps.get(key)\n    }\n\n    const { impl, deps } = provider\n    const params = deps.map((d) => inject(d))\n    const resolved = impl(...params)\n\n    initializedDeps.set(key, resolved)\n\n    return resolved\n  }\n\n  return { provide, inject }\n}\n","/**\n * Performs a deep merge of objects and returns new object.\n * Does not modify objects (immutable) and merges arrays via concatenation.\n *\n * @param objects - Objects to merge\n * @returns New object with merged key/values\n */\nexport function mergeDeep<T>(...objects: any[]): T {\n  const isObject = (obj: any) => obj && typeof obj === 'object' && obj.constructor === Object\n\n  return objects.reduce((prev, obj) => {\n    Object.keys(obj ?? {}).forEach((key) => {\n      // Avoid prototype pollution\n      if (key === '__proto__' || key === 'constructor' || key === 'prototype') {\n        return\n      }\n\n      const pVal = prev[key]\n      const oVal = obj[key]\n\n      if (Array.isArray(pVal) && Array.isArray(oVal)) {\n        prev[key] = pVal.concat(...oVal)\n      } else if (isObject(pVal) && isObject(oVal)) {\n        prev[key] = mergeDeep(pVal, oVal)\n      } else {\n        prev[key] = oVal\n      }\n    })\n\n    return prev\n  }, {})\n}\n","import type { Config } from '@/types'\n\nexport const Defaults: Readonly<RequiredExcept<Config, ExcludedKeys>> = {\n  el: '',\n  pageKey: '',\n  pageTitle: '',\n  server: '',\n  site: '',\n\n  placeholder: '',\n  noComment: '',\n  sendBtn: '',\n  darkMode: false,\n  editorTravel: true,\n\n  flatMode: 'auto',\n  nestMax: 2,\n  nestSort: 'DATE_ASC',\n\n  emoticons: ARTALK_LITE\n    ? false\n    : 'https://cdn.jsdelivr.net/gh/ArtalkJS/Emoticons/grps/default.json',\n\n  pageVote: true,\n\n  vote: ARTALK_LITE ? false : true,\n  voteDown: false,\n  uaBadge: ARTALK_LITE ? false : true,\n  listSort: true,\n  preview: ARTALK_LITE ? false : true,\n  countEl: '.artalk-comment-count',\n  pvEl: '.artalk-pv-count',\n  statPageKeyAttr: 'data-page-key',\n\n  gravatar: {\n    mirror: 'https://www.gravatar.com/avatar/',\n    params: 'sha256=1&d=mp&s=240',\n  },\n\n  pagination: {\n    pageSize: 20,\n    readMore: true,\n    autoLoad: true,\n  },\n\n  heightLimit: {\n    content: 300,\n    children: 400,\n    scrollable: false,\n  },\n\n  imgUpload: true,\n  imgLazyLoad: false,\n  reqTimeout: 15000,\n  versionCheck: true,\n  useBackendConf: true,\n  preferRemoteConf: false,\n  listUnreadHighlight: false,\n  pvAdd: true,\n  fetchCommentsOnInit: true,\n\n  locale: 'en',\n  apiVersion: '',\n  pluginURLs: [],\n  markedReplacers: [],\n  markedOptions: {},\n}\n\ntype RequiredExcept<T, K extends keyof T> = Required<Omit<T, K>> & Pick<T, K>\ntype FunctionKeys<T> = Exclude<\n  { [K in keyof T]: NonNullable<T[K]> extends (...args: any[]) => any ? K : never }[keyof T],\n  undefined\n>\ntype ExcludedKeys = FunctionKeys<Config>\n","import type { ApiOptions } from './api/options'\nimport { mergeDeep } from './lib/merge-deep'\nimport type { ApiHandlers } from './api'\nimport { Defaults } from './defaults'\nimport type { Config, ConfigPartial, UserManager } from '@/types'\n\n/**\n * Handle the custom config which is provided by the user\n *\n * @param customConf - The custom config object which is provided by the user\n * @param full - If `full` is `true`, the return value will be the complete config for Artalk instance creation\n * @returns The config for Artalk instance creation\n */\nexport function handelCustomConf(customConf: ConfigPartial, full: true): Config\nexport function handelCustomConf(customConf: ConfigPartial, full?: false): ConfigPartial\nexport function handelCustomConf(customConf: ConfigPartial, full = false) {\n  // Merge default config\n  const conf: ConfigPartial = full ? mergeDeep(Defaults, customConf) : customConf\n\n  // Default pageKey\n  if (conf.pageKey === '') conf.pageKey = `${window.location.pathname}` // @see http://bl.ocks.org/abernier/3070589\n\n  // Default pageTitle\n  if (conf.pageTitle === '') conf.pageTitle = `${document.title}`\n\n  // Server\n  if (conf.server) conf.server = conf.server.replace(/\\/$/, '').replace(/\\/api\\/?$/, '')\n\n  // Language auto-detection\n  if (conf.locale === 'auto') conf.locale = navigator.language\n\n  // Flat mode auto-detection\n  if (conf.flatMode === 'auto') conf.flatMode = window.matchMedia('(max-width: 768px)').matches\n\n  // Change flatMode by nestMax\n  if (typeof conf.nestMax === 'number' && Number(conf.nestMax) <= 1) conf.flatMode = true\n\n  return conf\n}\n\n/**\n * Handle the config which is provided by the server\n *\n * @param conf - The Server response config for control the frontend of Artalk remotely\n * @returns The config for Artalk instance creation\n */\nexport function handleConfFormServer(conf: ConfigPartial): ConfigPartial {\n  const ExcludedKeys: (keyof Config)[] = [\n    'el',\n    'pageKey',\n    'pageTitle',\n    'server',\n    'site',\n    'pvEl',\n    'countEl',\n    'statPageKeyAttr',\n    'pageVote',\n  ]\n  Object.keys(conf).forEach((k) => {\n    if (ExcludedKeys.includes(k as any)) delete conf[k]\n    if (k === 'darkMode' && conf[k] !== 'auto') delete conf[k]\n  })\n\n  // Patch: `emoticons` config string to json\n  if (conf.emoticons && typeof conf.emoticons === 'string') {\n    conf.emoticons = conf.emoticons.trim()\n    if (conf.emoticons.startsWith('[') || conf.emoticons.startsWith('{')) {\n      conf.emoticons = JSON.parse(conf.emoticons) // parse json\n    } else if (conf.emoticons === 'false') {\n      conf.emoticons = false\n    }\n  }\n\n  return conf\n}\n\n/**\n * Get the root element of Artalk\n *\n * @param conf - Artalk config\n * @returns The root element of Artalk\n */\nexport function getRootEl(conf: ConfigPartial): HTMLElement {\n  let $root: HTMLElement\n  if (typeof conf.el === 'string') {\n    const el = document.querySelector<HTMLElement>(conf.el)\n    if (!el) throw new Error(`Element \"${conf.el}\" not found.`)\n    $root = el\n  } else if (conf.el instanceof HTMLElement) {\n    $root = conf.el\n  } else {\n    throw new Error('Please provide a valid `el` config for Artalk.')\n  }\n  return $root\n}\n\n/**\n * Convert Artalk Config to ApiOptions for Api client\n *\n * @param conf - Artalk config\n * @param ctx - If `ctx` not provided, `checkAdmin` and `checkCaptcha` will be disabled\n * @returns ApiOptions for Api client instance creation\n */\nexport function convertApiOptions(\n  conf: ConfigPartial,\n  user?: UserManager,\n  handlers?: ApiHandlers,\n): ApiOptions {\n  return {\n    baseURL: `${conf.server}/api/v2`,\n    siteName: conf.site || '',\n    pageKey: conf.pageKey || '',\n    pageTitle: conf.pageTitle || '',\n    timeout: conf.reqTimeout,\n    getApiToken: () => user?.getData().token,\n    userInfo: user?.checkHasBasicUserInfo()\n      ? {\n          name: user?.getData().name,\n          email: user?.getData().email,\n        }\n      : undefined,\n    handlers,\n  }\n}\n","import type { Context, ArtalkPlugin } from '@/types'\nimport { Api } from '@/api'\n\ntype CountCache = { [pageKey: string]: number }\n\nexport interface CountOptions {\n  getApi(): Api\n\n  siteName: string\n  pageKey?: string\n  pageTitle?: string\n  countEl: string\n  pvEl: string\n  pageKeyAttr: string\n\n  /** Whether to add PV count when initializing */\n  pvAdd?: boolean\n}\n\nexport const PvCountWidget: ArtalkPlugin = (ctx: Context) => {\n  ctx.watchConf(\n    ['site', 'pageKey', 'pageTitle', 'countEl', 'pvEl', 'statPageKeyAttr', 'pvAdd'],\n    (conf) => {\n      initCountWidget({\n        getApi: () => ctx.getApi(),\n        siteName: conf.site,\n        pageKey: conf.pageKey,\n        pageTitle: conf.pageTitle,\n        countEl: conf.countEl,\n        pvEl: conf.pvEl,\n        pageKeyAttr: conf.statPageKeyAttr,\n        pvAdd: conf.pvAdd,\n      })\n    },\n  )\n}\n\n/** Initialize count widgets */\nexport async function initCountWidget(opt: CountOptions) {\n  // Load comment count\n  await loadCommentCount(opt)\n\n  // Increment PV count\n  const cacheData = await incrementPvCount(opt)\n\n  // Load PV count\n  await loadPvCount(opt, cacheData)\n}\n\n/** Increment PV count and get cache data that contains PV count */\nasync function incrementPvCount(opt: CountOptions) {\n  if (!opt.pvAdd || !opt.pageKey) return undefined\n\n  const pvCount = (\n    await opt.getApi().pages.logPv({\n      page_key: opt.pageKey,\n      page_title: opt.pageTitle,\n      site_name: opt.siteName,\n    })\n  ).data.pv // pv+1 and get pv count\n\n  return {\n    [opt.pageKey]: pvCount,\n  }\n}\n\n/** Load comment count */\nasync function loadCommentCount(opt: CountOptions) {\n  await loadStatCount({ opt, query: 'page_comment', containers: [opt.countEl, '#ArtalkCount'] })\n}\n\n/** Load PV count */\nasync function loadPvCount(opt: CountOptions, cache?: CountCache) {\n  await loadStatCount({ opt, query: 'page_pv', containers: [opt.pvEl, '#ArtalkPV'], cache })\n}\n\nasync function loadStatCount(args: {\n  opt: CountOptions\n  query: 'page_pv' | 'page_comment'\n  containers: string[]\n  cache?: CountCache\n}) {\n  const { opt } = args\n  let cache: CountCache = args.cache || {}\n\n  // Retrieve elements\n  const els = retrieveElements(args.containers)\n\n  // Get page keys which will be queried\n  const pageKeys = getPageKeys(els, opt.pageKeyAttr, opt.pageKey, cache)\n\n  // Fetch count data from server\n  if (pageKeys.length > 0) {\n    const res = (\n      await opt.getApi().stats.getStats(args.query, {\n        page_keys: pageKeys.join(','),\n        site_name: opt.siteName,\n      })\n    ).data.data as CountCache\n    cache = { ...cache, ...res }\n  }\n\n  updateElementsText(els, cache, opt.pageKey)\n}\n\n/** Retrieve elements based on selectors */\nfunction retrieveElements(containers: string[]): Set<HTMLElement> {\n  const els = new Set<HTMLElement>()\n  new Set(containers).forEach((selector) => {\n    document.querySelectorAll<HTMLElement>(selector).forEach((el) => els.add(el))\n  })\n  return els\n}\n\n/** Get page keys to be queried */\nfunction getPageKeys(\n  els: Set<HTMLElement>,\n  pageKeyAttr: string,\n  pageKey: string | undefined,\n  cache: CountCache,\n): string[] {\n  const pageKeys = Array.from(els)\n    .map((el) => el.getAttribute(pageKeyAttr) || pageKey)\n    .filter((key) => key && typeof cache[key] !== 'number') // filter out keys that already have data\n\n  return [...new Set(pageKeys as string[])] // deduplicate\n}\n\n/** Update elements text content with the count data */\nfunction updateElementsText(els: Set<HTMLElement>, data: CountCache, defaultPageKey?: string) {\n  els.forEach((el) => {\n    const pageKey = el.getAttribute('data-page-key')\n    const count = (pageKey && data[pageKey]) || (defaultPageKey && data[defaultPageKey]) || 0 // if pageKey is not set, use defaultCount\n    el.innerText = `${Number(count)}`\n  })\n}\n\nexport const exportedForTesting = {\n  incrementPvCount,\n  loadCommentCount,\n  loadPvCount,\n  retrieveElements,\n  getPageKeys,\n  updateElementsText,\n}\n","/* eslint-disable */\n/* tslint:disable */\n/*\n * ---------------------------------------------------------------\n * ## THIS FILE WAS GENERATED VIA SWAGGER-TYPESCRIPT-API        ##\n * ##                                                           ##\n * ## AUTHOR: acacode                                           ##\n * ## SOURCE: https://github.com/acacode/swagger-typescript-api ##\n * ---------------------------------------------------------------\n */\n\nexport interface AuthAuthProviderInfo {\n  icon: string\n  label: string\n  name: string\n  path?: string\n}\n\nexport interface CommonApiVersionData {\n  app: string\n  commit_hash: string\n  version: string\n}\n\nexport interface CommonConfData {\n  frontend_conf: CommonMap\n  version: CommonApiVersionData\n}\n\nexport interface CommonJSONResult {\n  /** Data */\n  data: any\n  /** Message */\n  msg: string\n}\n\nexport type CommonMap = Record<string, any>\n\nexport interface EntityCookedComment {\n  badge_color: string\n  badge_name: string\n  content: string\n  content_marked: string\n  date: string\n  email_encrypted: string\n  id: number\n  ip_region: string\n  is_allow_reply: boolean\n  is_collapsed: boolean\n  is_pending: boolean\n  is_pinned: boolean\n  is_verified: boolean\n  link: string\n  nick: string\n  page_key: string\n  page_url: string\n  rid: number\n  site_name: string\n  ua: string\n  user_id: number\n  visible: boolean\n  vote_down: number\n  vote_up: number\n}\n\nexport interface EntityCookedNotify {\n  comment_id: number\n  id: number\n  is_emailed: boolean\n  is_read: boolean\n  read_link: string\n  user_id: number\n}\n\nexport interface EntityCookedPage {\n  admin_only: boolean\n  date: string\n  id: number\n  key: string\n  pv: number\n  site_name: string\n  title: string\n  url: string\n  vote_down: number\n  vote_up: number\n}\n\nexport interface EntityCookedSite {\n  first_url: string\n  id: number\n  name: string\n  urls: string[]\n  urls_raw: string\n}\n\nexport interface EntityCookedUser {\n  badge_color: string\n  badge_name: string\n  email: string\n  id: number\n  is_admin: boolean\n  link: string\n  name: string\n  receive_email: boolean\n}\n\nexport interface EntityCookedUserForAdmin {\n  badge_color: string\n  badge_name: string\n  comment_count: number\n  email: string\n  id: number\n  is_admin: boolean\n  is_in_conf: boolean\n  last_ip: string\n  last_ua: string\n  link: string\n  name: string\n  receive_email: boolean\n}\n\nexport type HandlerMap = Record<string, any>\n\nexport interface HandlerParamsCaptchaVerify {\n  /** The captcha value to check */\n  value: string\n}\n\nexport interface HandlerParamsCommentCreate {\n  /** The comment content */\n  content: string\n  /** The comment email */\n  email: string\n  /** The comment link */\n  link?: string\n  /** The comment name */\n  name: string\n  /** The comment page_key */\n  page_key: string\n  /** The comment page_title */\n  page_title?: string\n  /** The comment rid */\n  rid?: number\n  /** The site name of your content scope */\n  site_name: string\n  /** The comment ua */\n  ua?: string\n}\n\nexport interface HandlerParamsCommentUpdate {\n  /** The comment content */\n  content: string\n  /** The comment email */\n  email?: string\n  /** The comment ip */\n  ip?: string\n  /** The comment is_collapsed */\n  is_collapsed: boolean\n  /** The comment is_pending */\n  is_pending: boolean\n  /** The comment is_pinned */\n  is_pinned: boolean\n  /** The comment link */\n  link?: string\n  /** The comment nick */\n  nick?: string\n  /** The comment page_key */\n  page_key: string\n  /** The comment rid */\n  rid: number\n  /** The site name of your content scope */\n  site_name: string\n  /** The comment ua */\n  ua?: string\n}\n\nexport interface HandlerParamsEmailSend {\n  /** The body of email */\n  body: string\n  /** The subject of email */\n  subject: string\n  /** The email address of the receiver */\n  to_addr: string\n}\n\nexport interface HandlerParamsNotifyReadAll {\n  /** The user email */\n  email: string\n  /** The username */\n  name: string\n}\n\nexport interface HandlerParamsPageFetchAll {\n  /** If not empty, only fetch pages of this site */\n  site_name?: string\n}\n\nexport interface HandlerParamsPagePV {\n  /** The page key */\n  page_key: string\n  /** The page title */\n  page_title?: string\n  /** The site name of your content scope */\n  site_name?: string\n}\n\nexport interface HandlerParamsPageUpdate {\n  /** Updated page admin_only option */\n  admin_only: boolean\n  /** Updated page key */\n  key: string\n  /** The site name of your content scope */\n  site_name: string\n  /** Updated page title */\n  title: string\n}\n\nexport interface HandlerParamsSettingApply {\n  /** The content of the config file in YAML format */\n  yaml: string\n}\n\nexport interface HandlerParamsSiteCreate {\n  /** The site name */\n  name: string\n  /** The site urls */\n  urls: string[]\n}\n\nexport interface HandlerParamsSiteUpdate {\n  /** Updated site name */\n  name: string\n  /** Updated site urls */\n  urls: string[]\n}\n\nexport interface HandlerParamsTransferImport {\n  /** Automatically answer yes for all questions */\n  assumeyes?: boolean\n  /** The JSON data */\n  json_data?: string\n  /** The JSON file path */\n  json_file?: string\n  /** The target site name */\n  target_site_name?: string\n  /** The target site url */\n  target_site_url?: string\n  /** Keep domain */\n  url_keep_domain?: boolean\n  /** Enable URL resolver */\n  url_resolver?: boolean\n}\n\nexport interface HandlerParamsUserCreate {\n  /** The user badge color (hex format) */\n  badge_color?: string\n  /** The user badge name */\n  badge_name?: string\n  /** The user email */\n  email: string\n  /** The user is an admin */\n  is_admin: boolean\n  /** The user link */\n  link?: string\n  /** The user name */\n  name: string\n  /** The user password */\n  password?: string\n  /** The user receive email */\n  receive_email: boolean\n}\n\nexport interface HandlerParamsUserLogin {\n  /** The user email */\n  email: string\n  /** The username */\n  name?: string\n  /** The user password */\n  password: string\n}\n\nexport interface HandlerParamsUserUpdate {\n  /** The user badge color (hex format) */\n  badge_color?: string\n  /** The user badge name */\n  badge_name?: string\n  /** The user email */\n  email: string\n  /** The user is an admin */\n  is_admin: boolean\n  /** The user link */\n  link?: string\n  /** The user name */\n  name: string\n  /** The user password */\n  password?: string\n  /** The user receive email */\n  receive_email: boolean\n}\n\nexport interface HandlerParamsVoteCreate {\n  /** The user email */\n  email?: string\n  /** The username */\n  name?: string\n}\n\nexport interface HandlerRequestAuthDataMergeApply {\n  user_name: string\n}\n\nexport interface HandlerRequestAuthEmailLogin {\n  code?: string\n  email: string\n  password?: string\n}\n\nexport interface HandlerRequestAuthEmailRegister {\n  code: string\n  email: string\n  link?: string\n  name?: string\n  password: string\n}\n\nexport interface HandlerRequestAuthEmailSend {\n  email: string\n}\n\nexport interface HandlerRequestUserInfoUpdate {\n  code?: string\n  email: string\n  link?: string\n  name: string\n}\n\nexport interface HandlerResponseAdminUserList {\n  count: number\n  users: EntityCookedUserForAdmin[]\n}\n\nexport interface HandlerResponseAuthDataMergeApply {\n  deleted_user_count: number\n  update_comments_count: number\n  update_notifies_count: number\n  update_votes_count: number\n  /** Empty if login user is target user no need to re-login */\n  user_token: string\n}\n\nexport interface HandlerResponseAuthDataMergeCheck {\n  need_merge: boolean\n  user_names: string[]\n}\n\nexport interface HandlerResponseCaptchaGet {\n  img_data: string\n}\n\nexport interface HandlerResponseCaptchaStatus {\n  is_pass: boolean\n}\n\nexport interface HandlerResponseCommentCreate {\n  badge_color: string\n  badge_name: string\n  content: string\n  content_marked: string\n  date: string\n  email_encrypted: string\n  id: number\n  ip_region: string\n  is_allow_reply: boolean\n  is_collapsed: boolean\n  is_pending: boolean\n  is_pinned: boolean\n  is_verified: boolean\n  link: string\n  nick: string\n  page_key: string\n  page_url: string\n  rid: number\n  site_name: string\n  ua: string\n  user_id: number\n  visible: boolean\n  vote_down: number\n  vote_up: number\n}\n\nexport interface HandlerResponseCommentGet {\n  /** The comment detail */\n  comment: EntityCookedComment\n  /** The reply comment if exists (like reply) */\n  reply_comment: EntityCookedComment\n}\n\nexport interface HandlerResponseCommentList {\n  comments: EntityCookedComment[]\n  count: number\n  page: EntityCookedPage\n  roots_count: number\n}\n\nexport interface HandlerResponseCommentUpdate {\n  badge_color: string\n  badge_name: string\n  content: string\n  content_marked: string\n  date: string\n  email_encrypted: string\n  id: number\n  ip_region: string\n  is_allow_reply: boolean\n  is_collapsed: boolean\n  is_pending: boolean\n  is_pinned: boolean\n  is_verified: boolean\n  link: string\n  nick: string\n  page_key: string\n  page_url: string\n  rid: number\n  site_name: string\n  ua: string\n  user_id: number\n  visible: boolean\n  vote_down: number\n  vote_up: number\n}\n\nexport interface HandlerResponseConfAuthProviders {\n  anonymous: boolean\n  providers: AuthAuthProviderInfo[]\n}\n\nexport interface HandlerResponseConfDomain {\n  /** Is the domain trusted */\n  is_trusted: boolean\n  /** The origin of the domain */\n  origin: string\n}\n\nexport interface HandlerResponseNotifyList {\n  count: number\n  notifies: EntityCookedNotify[]\n}\n\nexport interface HandlerResponsePageFetch {\n  admin_only: boolean\n  date: string\n  id: number\n  key: string\n  pv: number\n  site_name: string\n  title: string\n  url: string\n  vote_down: number\n  vote_up: number\n}\n\nexport interface HandlerResponsePageFetchStatus {\n  /** The number of pages that have been fetched */\n  done: number\n  /** If the task is in progress */\n  is_progress: boolean\n  /** The message of the task status */\n  msg: string\n  /** The total number of pages */\n  total: number\n}\n\nexport interface HandlerResponsePageList {\n  count: number\n  pages: EntityCookedPage[]\n}\n\nexport interface HandlerResponsePagePV {\n  pv: number\n}\n\nexport interface HandlerResponsePageUpdate {\n  admin_only: boolean\n  date: string\n  id: number\n  key: string\n  pv: number\n  site_name: string\n  title: string\n  url: string\n  vote_down: number\n  vote_up: number\n}\n\nexport interface HandlerResponseSettingGet {\n  envs: string[]\n  yaml: string\n}\n\nexport interface HandlerResponseSettingTemplate {\n  yaml: string\n}\n\nexport interface HandlerResponseSiteCreate {\n  first_url: string\n  id: number\n  name: string\n  urls: string[]\n  urls_raw: string\n}\n\nexport interface HandlerResponseSiteList {\n  count: number\n  sites: EntityCookedSite[]\n}\n\nexport interface HandlerResponseSiteUpdate {\n  first_url: string\n  id: number\n  name: string\n  urls: string[]\n  urls_raw: string\n}\n\nexport interface HandlerResponseTransferExport {\n  /** The exported data which is a JSON string */\n  artrans: string\n}\n\nexport interface HandlerResponseTransferUpload {\n  /** The uploaded file name which can be used to import */\n  filename: string\n}\n\nexport interface HandlerResponseUpload {\n  file_name: string\n  file_type: string\n  public_url: string\n}\n\nexport interface HandlerResponseUserCreate {\n  badge_color: string\n  badge_name: string\n  comment_count: number\n  email: string\n  id: number\n  is_admin: boolean\n  is_in_conf: boolean\n  last_ip: string\n  last_ua: string\n  link: string\n  name: string\n  receive_email: boolean\n}\n\nexport interface HandlerResponseUserInfo {\n  is_login: boolean\n  notifies: EntityCookedNotify[]\n  notifies_count: number\n  user: EntityCookedUser\n}\n\nexport interface HandlerResponseUserInfoUpdate {\n  user: EntityCookedUser\n}\n\nexport interface HandlerResponseUserLogin {\n  token: string\n  user: EntityCookedUser\n}\n\nexport interface HandlerResponseUserStatus {\n  is_admin: boolean\n  is_login: boolean\n}\n\nexport interface HandlerResponseUserUpdate {\n  badge_color: string\n  badge_name: string\n  comment_count: number\n  email: string\n  id: number\n  is_admin: boolean\n  is_in_conf: boolean\n  last_ip: string\n  last_ua: string\n  link: string\n  name: string\n  receive_email: boolean\n}\n\nexport interface HandlerResponseVote {\n  down: number\n  is_down: boolean\n  is_up: boolean\n  up: number\n}\n\nexport type QueryParamsType = Record<string | number, any>\nexport type ResponseFormat = keyof Omit<Body, 'body' | 'bodyUsed'>\n\nexport interface FullRequestParams extends Omit<RequestInit, 'body'> {\n  /** set parameter to `true` for call `securityWorker` for this request */\n  secure?: boolean\n  /** request path */\n  path: string\n  /** content type of request body */\n  type?: ContentType\n  /** query params */\n  query?: QueryParamsType\n  /** format of response (i.e. response.json() -> format: \"json\") */\n  format?: ResponseFormat\n  /** request body */\n  body?: unknown\n  /** base url */\n  baseUrl?: string\n  /** request cancellation token */\n  cancelToken?: CancelToken\n}\n\nexport type RequestParams = Omit<FullRequestParams, 'body' | 'method' | 'query' | 'path'>\n\nexport interface ApiConfig<SecurityDataType = unknown> {\n  baseUrl?: string\n  baseApiParams?: Omit<RequestParams, 'baseUrl' | 'cancelToken' | 'signal'>\n  securityWorker?: (\n    securityData: SecurityDataType | null,\n  ) => Promise<RequestParams | void> | RequestParams | void\n  customFetch?: typeof fetch\n}\n\nexport interface HttpResponse<D extends unknown, E extends unknown = unknown> extends Response {\n  data: D\n  error: E\n}\n\ntype CancelToken = Symbol | string | number\n\nexport enum ContentType {\n  Json = 'application/json',\n  FormData = 'multipart/form-data',\n  UrlEncoded = 'application/x-www-form-urlencoded',\n  Text = 'text/plain',\n}\n\nexport class HttpClient<SecurityDataType = unknown> {\n  public baseUrl: string = '/api/v2'\n  private securityData: SecurityDataType | null = null\n  private securityWorker?: ApiConfig<SecurityDataType>['securityWorker']\n  private abortControllers = new Map<CancelToken, AbortController>()\n  private customFetch = (...fetchParams: Parameters<typeof fetch>) => fetch(...fetchParams)\n\n  private baseApiParams: RequestParams = {\n    credentials: 'same-origin',\n    headers: {},\n    redirect: 'follow',\n    referrerPolicy: 'no-referrer',\n  }\n\n  constructor(apiConfig: ApiConfig<SecurityDataType> = {}) {\n    Object.assign(this, apiConfig)\n  }\n\n  public setSecurityData = (data: SecurityDataType | null) => {\n    this.securityData = data\n  }\n\n  protected encodeQueryParam(key: string, value: any) {\n    const encodedKey = encodeURIComponent(key)\n    return `${encodedKey}=${encodeURIComponent(typeof value === 'number' ? value : `${value}`)}`\n  }\n\n  protected addQueryParam(query: QueryParamsType, key: string) {\n    return this.encodeQueryParam(key, query[key])\n  }\n\n  protected addArrayQueryParam(query: QueryParamsType, key: string) {\n    const value = query[key]\n    return value.map((v: any) => this.encodeQueryParam(key, v)).join('&')\n  }\n\n  protected toQueryString(rawQuery?: QueryParamsType): string {\n    const query = rawQuery || {}\n    const keys = Object.keys(query).filter((key) => 'undefined' !== typeof query[key])\n    return keys\n      .map((key) =>\n        Array.isArray(query[key])\n          ? this.addArrayQueryParam(query, key)\n          : this.addQueryParam(query, key),\n      )\n      .join('&')\n  }\n\n  protected addQueryParams(rawQuery?: QueryParamsType): string {\n    const queryString = this.toQueryString(rawQuery)\n    return queryString ? `?${queryString}` : ''\n  }\n\n  private contentFormatters: Record<ContentType, (input: any) => any> = {\n    [ContentType.Json]: (input: any) =>\n      input !== null && (typeof input === 'object' || typeof input === 'string')\n        ? JSON.stringify(input)\n        : input,\n    [ContentType.Text]: (input: any) =>\n      input !== null && typeof input !== 'string' ? JSON.stringify(input) : input,\n    [ContentType.FormData]: (input: any) =>\n      Object.keys(input || {}).reduce((formData, key) => {\n        const property = input[key]\n        formData.append(\n          key,\n          property instanceof Blob\n            ? property\n            : typeof property === 'object' && property !== null\n              ? JSON.stringify(property)\n              : `${property}`,\n        )\n        return formData\n      }, new FormData()),\n    [ContentType.UrlEncoded]: (input: any) => this.toQueryString(input),\n  }\n\n  protected mergeRequestParams(params1: RequestParams, params2?: RequestParams): RequestParams {\n    return {\n      ...this.baseApiParams,\n      ...params1,\n      ...(params2 || {}),\n      headers: {\n        ...(this.baseApiParams.headers || {}),\n        ...(params1.headers || {}),\n        ...((params2 && params2.headers) || {}),\n      },\n    }\n  }\n\n  protected createAbortSignal = (cancelToken: CancelToken): AbortSignal | undefined => {\n    if (this.abortControllers.has(cancelToken)) {\n      const abortController = this.abortControllers.get(cancelToken)\n      if (abortController) {\n        return abortController.signal\n      }\n      return void 0\n    }\n\n    const abortController = new AbortController()\n    this.abortControllers.set(cancelToken, abortController)\n    return abortController.signal\n  }\n\n  public abortRequest = (cancelToken: CancelToken) => {\n    const abortController = this.abortControllers.get(cancelToken)\n\n    if (abortController) {\n      abortController.abort()\n      this.abortControllers.delete(cancelToken)\n    }\n  }\n\n  public request = async <T = any, E = any>({\n    body,\n    secure,\n    path,\n    type,\n    query,\n    format,\n    baseUrl,\n    cancelToken,\n    ...params\n  }: FullRequestParams): Promise<HttpResponse<T, E>> => {\n    const secureParams =\n      ((typeof secure === 'boolean' ? secure : this.baseApiParams.secure) &&\n        this.securityWorker &&\n        (await this.securityWorker(this.securityData))) ||\n      {}\n    const requestParams = this.mergeRequestParams(params, secureParams)\n    const queryString = query && this.toQueryString(query)\n    const payloadFormatter = this.contentFormatters[type || ContentType.Json]\n    const responseFormat = format || requestParams.format\n\n    return this.customFetch(\n      `${baseUrl || this.baseUrl || ''}${path}${queryString ? `?${queryString}` : ''}`,\n      {\n        ...requestParams,\n        headers: {\n          ...(requestParams.headers || {}),\n          ...(type && type !== ContentType.FormData ? { 'Content-Type': type } : {}),\n        },\n        signal: (cancelToken ? this.createAbortSignal(cancelToken) : requestParams.signal) || null,\n        body: typeof body === 'undefined' || body === null ? null : payloadFormatter(body),\n      },\n    ).then(async (response) => {\n      const r = response.clone() as HttpResponse<T, E>\n      r.data = null as unknown as T\n      r.error = null as unknown as E\n\n      const data = !responseFormat\n        ? r\n        : await response[responseFormat]()\n            .then((data) => {\n              if (r.ok) {\n                r.data = data\n              } else {\n                r.error = data\n              }\n              return r\n            })\n            .catch((e) => {\n              r.error = e\n              return r\n            })\n\n      if (cancelToken) {\n        this.abortControllers.delete(cancelToken)\n      }\n\n      if (!response.ok) throw data\n      return data\n    })\n  }\n}\n\n/**\n * @title Artalk API\n * @version 2.0\n * @license MIT (https://github.com/ArtalkJS/Artalk/blob/master/LICENSE)\n * @baseUrl /api/v2\n * @contact API Support <artalkjs@gmail.com> (https://artalk.js.org)\n *\n * Artalk is a modern comment system based on Golang.\n */\nexport class Api<SecurityDataType extends unknown> extends HttpClient<SecurityDataType> {\n  auth = {\n    /**\n * @description Login by email with verify code (Need send email verify code first) or password\n *\n * @tags Auth\n * @name LoginByEmail\n * @summary Login by email\n * @request POST:/auth/email/login\n * @response `200` `HandlerResponseUserLogin` OK\n * @response `400` `(HandlerMap & {\n    msg?: string,\n\n})` Bad Request\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    loginByEmail: (data: HandlerRequestAuthEmailLogin, params: RequestParams = {}) =>\n      this.request<\n        HandlerResponseUserLogin,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/auth/email/login`,\n        method: 'POST',\n        body: data,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Register by email and verify code (if user exists, will update user, like forget or change password. Need send email verify code first)\n *\n * @tags Auth\n * @name RegisterByEmail\n * @summary Register by email\n * @request POST:/auth/email/register\n * @response `200` `HandlerResponseUserLogin` OK\n * @response `400` `(HandlerMap & {\n    msg?: string,\n\n})` Bad Request\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    registerByEmail: (data: HandlerRequestAuthEmailRegister, params: RequestParams = {}) =>\n      this.request<\n        HandlerResponseUserLogin,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/auth/email/register`,\n        method: 'POST',\n        body: data,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Send email including verify code to user\n *\n * @tags Auth\n * @name SendVerifyEmail\n * @summary Send verify email\n * @request POST:/auth/email/send\n * @response `200` `(HandlerMap & {\n    msg?: string,\n\n})` OK\n * @response `400` `(HandlerMap & {\n    msg?: string,\n\n})` Bad Request\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    sendVerifyEmail: (data: HandlerRequestAuthEmailSend, params: RequestParams = {}) =>\n      this.request<\n        HandlerMap & {\n          msg?: string\n        },\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/auth/email/send`,\n        method: 'POST',\n        body: data,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Get all users with same email, if there are more than one user with same email, need merge\n *\n * @tags Auth\n * @name CheckDataMerge\n * @summary Check data merge\n * @request GET:/auth/merge\n * @secure\n * @response `200` `HandlerResponseAuthDataMergeCheck` OK\n * @response `400` `(HandlerMap & {\n    msg?: string,\n\n})` Bad Request\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    checkDataMerge: (params: RequestParams = {}) =>\n      this.request<\n        HandlerResponseAuthDataMergeCheck,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/auth/merge`,\n        method: 'GET',\n        secure: true,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description This function is to solve the problem of multiple users with the same email address, should be called after user login and then check, and perform data merge.\n *\n * @tags Auth\n * @name ApplyDataMerge\n * @summary Apply data merge\n * @request POST:/auth/merge\n * @secure\n * @response `200` `HandlerResponseAuthDataMergeApply` OK\n * @response `400` `(HandlerMap & {\n    msg?: string,\n\n})` Bad Request\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    applyDataMerge: (data: HandlerRequestAuthDataMergeApply, params: RequestParams = {}) =>\n      this.request<\n        HandlerResponseAuthDataMergeApply,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/auth/merge`,\n        method: 'POST',\n        body: data,\n        secure: true,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n  }\n  cache = {\n    /**\n * @description Flush all cache on the server\n *\n * @tags Cache\n * @name FlushCache\n * @summary Flush Cache\n * @request POST:/cache/flush\n * @secure\n * @response `200` `(HandlerMap & {\n    msg?: string,\n\n})` OK\n * @response `400` `(HandlerMap & {\n    msg?: string,\n\n})` Bad Request\n * @response `403` `(HandlerMap & {\n    msg?: string,\n\n})` Forbidden\n */\n    flushCache: (params: RequestParams = {}) =>\n      this.request<\n        HandlerMap & {\n          msg?: string\n        },\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/cache/flush`,\n        method: 'POST',\n        secure: true,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Cache warming helps you to pre-load the cache to improve the performance of the first request\n *\n * @tags Cache\n * @name WarmUpCache\n * @summary Warm-Up Cache\n * @request POST:/cache/warm_up\n * @secure\n * @response `200` `(HandlerMap & {\n    msg?: string,\n\n})` OK\n * @response `400` `(HandlerMap & {\n    msg?: string,\n\n})` Bad Request\n * @response `403` `(HandlerMap & {\n    msg?: string,\n\n})` Forbidden\n */\n    warmUpCache: (params: RequestParams = {}) =>\n      this.request<\n        HandlerMap & {\n          msg?: string\n        },\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/cache/warm_up`,\n        method: 'POST',\n        secure: true,\n        format: 'json',\n        ...params,\n      }),\n  }\n  captcha = {\n    /**\n * @description Get a base64 encoded captcha image or a HTML page to verify for user\n *\n * @tags Captcha\n * @name GetCaptcha\n * @summary Get Captcha\n * @request GET:/captcha\n * @response `200` `HandlerResponseCaptchaGet` OK\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    getCaptcha: (params: RequestParams = {}) =>\n      this.request<\n        HandlerResponseCaptchaGet,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/captcha`,\n        method: 'GET',\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n     * @description Get the status of the user's captcha verification\n     *\n     * @tags Captcha\n     * @name GetCaptchaStatus\n     * @summary Get Captcha Status\n     * @request GET:/captcha/status\n     * @response `200` `HandlerResponseCaptchaStatus` OK\n     */\n    getCaptchaStatus: (params: RequestParams = {}) =>\n      this.request<HandlerResponseCaptchaStatus, any>({\n        path: `/captcha/status`,\n        method: 'GET',\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Verify user enters correct captcha code\n *\n * @tags Captcha\n * @name VerifyCaptcha\n * @summary Verify Captcha\n * @request POST:/captcha/verify\n * @response `200` `HandlerMap` OK\n * @response `403` `(HandlerMap & {\n    img_data?: string,\n\n})` Forbidden\n */\n    verifyCaptcha: (data: HandlerParamsCaptchaVerify, params: RequestParams = {}) =>\n      this.request<\n        HandlerMap,\n        HandlerMap & {\n          img_data?: string\n        }\n      >({\n        path: `/captcha/verify`,\n        method: 'POST',\n        body: data,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n  }\n  comments = {\n    /**\n * @description Get a list of comments by some conditions\n *\n * @tags Comment\n * @name GetComments\n * @summary Get Comment List\n * @request GET:/comments\n * @secure\n * @response `200` `HandlerResponseCommentList` OK\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    getComments: (\n      query: {\n        /** The user email */\n        email?: string\n        /** Enable flat_mode */\n        flat_mode?: boolean\n        /** The limit for pagination */\n        limit?: number\n        /** The username */\n        name?: string\n        /** The offset for pagination */\n        offset?: number\n        /** The comment page_key */\n        page_key: string\n        /** The scope of comments */\n        scope?: 'page' | 'user' | 'site'\n        /** Search keywords */\n        search?: string\n        /** The site name of your content scope */\n        site_name?: string\n        /** Sort by condition */\n        sort_by?: 'date_asc' | 'date_desc' | 'vote'\n        /** Message center show type */\n        type?: 'all' | 'mentions' | 'mine' | 'pending'\n        /** Only show comments by admin */\n        view_only_admin?: boolean\n      },\n      params: RequestParams = {},\n    ) =>\n      this.request<\n        HandlerResponseCommentList,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/comments`,\n        method: 'GET',\n        query: query,\n        secure: true,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Create a new comment\n *\n * @tags Comment\n * @name CreateComment\n * @summary Create Comment\n * @request POST:/comments\n * @secure\n * @response `200` `HandlerResponseCommentCreate` OK\n * @response `400` `(HandlerMap & {\n    msg?: string,\n\n})` Bad Request\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    createComment: (comment: HandlerParamsCommentCreate, params: RequestParams = {}) =>\n      this.request<\n        HandlerResponseCommentCreate,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/comments`,\n        method: 'POST',\n        body: comment,\n        secure: true,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Get the detail of a comment by comment id\n *\n * @tags Comment\n * @name GetComment\n * @summary Get a comment\n * @request GET:/comments/{id}\n * @response `200` `HandlerResponseCommentGet` OK\n * @response `404` `(HandlerMap & {\n    msg?: string,\n\n})` Not Found\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    getComment: (id: number, params: RequestParams = {}) =>\n      this.request<\n        HandlerResponseCommentGet,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/comments/${id}`,\n        method: 'GET',\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Update a specific comment\n *\n * @tags Comment\n * @name UpdateComment\n * @summary Update Comment\n * @request PUT:/comments/{id}\n * @secure\n * @response `200` `HandlerResponseCommentUpdate` OK\n * @response `400` `(HandlerMap & {\n    msg?: string,\n\n})` Bad Request\n * @response `403` `(HandlerMap & {\n    msg?: string,\n\n})` Forbidden\n * @response `404` `(HandlerMap & {\n    msg?: string,\n\n})` Not Found\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    updateComment: (id: number, comment: HandlerParamsCommentUpdate, params: RequestParams = {}) =>\n      this.request<\n        HandlerResponseCommentUpdate,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/comments/${id}`,\n        method: 'PUT',\n        body: comment,\n        secure: true,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Delete a specific comment\n *\n * @tags Comment\n * @name DeleteComment\n * @summary Delete Comment\n * @request DELETE:/comments/{id}\n * @secure\n * @response `200` `HandlerMap` OK\n * @response `403` `(HandlerMap & {\n    msg?: string,\n\n})` Forbidden\n * @response `404` `(HandlerMap & {\n    msg?: string,\n\n})` Not Found\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    deleteComment: (id: number, params: RequestParams = {}) =>\n      this.request<\n        HandlerMap,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/comments/${id}`,\n        method: 'DELETE',\n        secure: true,\n        format: 'json',\n        ...params,\n      }),\n  }\n  conf = {\n    /**\n     * @description Get System Configs for UI\n     *\n     * @tags System\n     * @name Conf\n     * @summary Get System Configs\n     * @request GET:/conf\n     * @response `200` `CommonConfData` OK\n     */\n    conf: (params: RequestParams = {}) =>\n      this.request<CommonConfData, any>({\n        path: `/conf`,\n        method: 'GET',\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Get social login providers\n *\n * @tags System\n * @name GetSocialLoginProviders\n * @summary Get Social Login Providers\n * @request GET:/conf/auth/providers\n * @response `200` `HandlerResponseConfAuthProviders` OK\n * @response `404` `(HandlerMap & {\n    msg?: string,\n\n})` Not Found\n */\n    getSocialLoginProviders: (params: RequestParams = {}) =>\n      this.request<\n        HandlerResponseConfAuthProviders,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/conf/auth/providers`,\n        method: 'GET',\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n     * @description Get Domain Info\n     *\n     * @tags System\n     * @name GetDomain\n     * @summary Get Domain Info\n     * @request GET:/conf/domain\n     * @response `200` `HandlerResponseConfDomain` OK\n     */\n    getDomain: (\n      query?: {\n        /** Domain URL */\n        url?: string\n      },\n      params: RequestParams = {},\n    ) =>\n      this.request<HandlerResponseConfDomain, any>({\n        path: `/conf/domain`,\n        method: 'GET',\n        query: query,\n        format: 'json',\n        ...params,\n      }),\n  }\n  notifies = {\n    /**\n * @description Get a list of notifies for user\n *\n * @tags Notify\n * @name GetNotifies\n * @summary Get Notifies\n * @request GET:/notifies\n * @response `200` `HandlerResponseNotifyList` OK\n * @response `400` `(HandlerMap & {\n    msg?: string,\n\n})` Bad Request\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    getNotifies: (\n      query: {\n        /** The user email */\n        email: string\n        /** The user name */\n        name: string\n      },\n      params: RequestParams = {},\n    ) =>\n      this.request<\n        HandlerResponseNotifyList,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/notifies`,\n        method: 'GET',\n        query: query,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Mark all notifies as read for user\n *\n * @tags Notify\n * @name MarkAllNotifyRead\n * @summary Mark All Notifies as Read\n * @request POST:/notifies/read\n * @response `200` `HandlerMap` OK\n * @response `400` `(HandlerMap & {\n    msg?: string,\n\n})` Bad Request\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    markAllNotifyRead: (options: HandlerParamsNotifyReadAll, params: RequestParams = {}) =>\n      this.request<\n        HandlerMap,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/notifies/read`,\n        method: 'POST',\n        body: options,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Mark specific notification as read for user\n *\n * @tags Notify\n * @name MarkNotifyRead\n * @summary Mark Notify as Read\n * @request POST:/notifies/{comment_id}/{notify_key}\n * @response `200` `HandlerMap` OK\n * @response `400` `(HandlerMap & {\n    msg?: string,\n\n})` Bad Request\n * @response `404` `(HandlerMap & {\n    msg?: string,\n\n})` Not Found\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    markNotifyRead: (commentId: number, notifyKey: string, params: RequestParams = {}) =>\n      this.request<\n        HandlerMap,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/notifies/${commentId}/${notifyKey}`,\n        method: 'POST',\n        format: 'json',\n        ...params,\n      }),\n  }\n  pages = {\n    /**\n * @description Get a list of pages by some conditions\n *\n * @tags Page\n * @name GetPages\n * @summary Get Page List\n * @request GET:/pages\n * @secure\n * @response `200` `HandlerResponsePageList` OK\n * @response `403` `(HandlerMap & {\n    msg?: string,\n\n})` Forbidden\n */\n    getPages: (\n      query?: {\n        /** The limit for pagination */\n        limit?: number\n        /** The offset for pagination */\n        offset?: number\n        /** Search keywords */\n        search?: string\n        /** The site name of your content scope */\n        site_name?: string\n      },\n      params: RequestParams = {},\n    ) =>\n      this.request<\n        HandlerResponsePageList,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/pages`,\n        method: 'GET',\n        query: query,\n        secure: true,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Fetch the data of all pages\n *\n * @tags Page\n * @name FetchAllPages\n * @summary Fetch All Pages Data\n * @request POST:/pages/fetch\n * @secure\n * @response `200` `HandlerMap` OK\n * @response `400` `(HandlerMap & {\n    msg?: string,\n\n})` Bad Request\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    fetchAllPages: (options: HandlerParamsPageFetchAll, params: RequestParams = {}) =>\n      this.request<\n        HandlerMap,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/pages/fetch`,\n        method: 'POST',\n        body: options,\n        secure: true,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n     * @description Get the status of the task of fetching all pages\n     *\n     * @tags Page\n     * @name GetPageFetchStatus\n     * @summary Get Pages Fetch Status\n     * @request GET:/pages/fetch/status\n     * @secure\n     * @response `200` `HandlerResponsePageFetchStatus` OK\n     */\n    getPageFetchStatus: (params: RequestParams = {}) =>\n      this.request<HandlerResponsePageFetchStatus, any>({\n        path: `/pages/fetch/status`,\n        method: 'GET',\n        secure: true,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n     * @description Increase and get the number of page views\n     *\n     * @tags Page\n     * @name LogPv\n     * @summary Increase Page Views (PV)\n     * @request POST:/pages/pv\n     * @response `200` `HandlerResponsePagePV` OK\n     */\n    logPv: (page: HandlerParamsPagePV, params: RequestParams = {}) =>\n      this.request<HandlerResponsePagePV, any>({\n        path: `/pages/pv`,\n        method: 'POST',\n        body: page,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Update a specific page\n *\n * @tags Page\n * @name UpdatePage\n * @summary Update Page\n * @request PUT:/pages/{id}\n * @secure\n * @response `200` `HandlerResponsePageUpdate` OK\n * @response `400` `(HandlerMap & {\n    msg?: string,\n\n})` Bad Request\n * @response `403` `(HandlerMap & {\n    msg?: string,\n\n})` Forbidden\n * @response `404` `(HandlerMap & {\n    msg?: string,\n\n})` Not Found\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    updatePage: (id: number, page: HandlerParamsPageUpdate, params: RequestParams = {}) =>\n      this.request<\n        HandlerResponsePageUpdate,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/pages/${id}`,\n        method: 'PUT',\n        body: page,\n        secure: true,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Delete a specific page\n *\n * @tags Page\n * @name DeletePage\n * @summary Delete Page\n * @request DELETE:/pages/{id}\n * @secure\n * @response `200` `HandlerMap` OK\n * @response `403` `(HandlerMap & {\n    msg?: string,\n\n})` Forbidden\n * @response `404` `(HandlerMap & {\n    msg?: string,\n\n})` Not Found\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    deletePage: (id: number, params: RequestParams = {}) =>\n      this.request<\n        HandlerMap,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/pages/${id}`,\n        method: 'DELETE',\n        secure: true,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Fetch the data of a specific page\n *\n * @tags Page\n * @name FetchPage\n * @summary Fetch Page Data\n * @request POST:/pages/{id}/fetch\n * @secure\n * @response `200` `HandlerResponsePageFetch` OK\n * @response `404` `(HandlerMap & {\n    msg?: string,\n\n})` Not Found\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    fetchPage: (id: number, params: RequestParams = {}) =>\n      this.request<\n        HandlerResponsePageFetch,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/pages/${id}/fetch`,\n        method: 'POST',\n        secure: true,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n  }\n  sendEmail = {\n    /**\n * @description Send an email to test the email sender\n *\n * @tags System\n * @name SendEmail\n * @summary Send Email\n * @request POST:/send_email\n * @secure\n * @response `200` `HandlerMap` OK\n * @response `403` `(HandlerMap & {\n    msg?: string,\n\n})` Forbidden\n * @response `500` `HandlerMap` Internal Server Error\n */\n    sendEmail: (email: HandlerParamsEmailSend, params: RequestParams = {}) =>\n      this.request<\n        HandlerMap,\n        | (HandlerMap & {\n            msg?: string\n          })\n        | HandlerMap\n      >({\n        path: `/send_email`,\n        method: 'POST',\n        body: email,\n        secure: true,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n  }\n  settings = {\n    /**\n * @description Get settings from app config file\n *\n * @tags System\n * @name GetSettings\n * @summary Get Settings\n * @request GET:/settings\n * @secure\n * @response `200` `HandlerResponseSettingGet` OK\n * @response `403` `(HandlerMap & {\n    msg?: string,\n\n})` Forbidden\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    getSettings: (params: RequestParams = {}) =>\n      this.request<\n        HandlerResponseSettingGet,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/settings`,\n        method: 'GET',\n        secure: true,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Apply settings and restart the server\n *\n * @tags System\n * @name ApplySettings\n * @summary Save and apply Settings\n * @request PUT:/settings\n * @secure\n * @response `200` `HandlerMap` OK\n * @response `403` `(HandlerMap & {\n    msg?: string,\n\n})` Forbidden\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    applySettings: (settings: HandlerParamsSettingApply, params: RequestParams = {}) =>\n      this.request<\n        HandlerMap,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/settings`,\n        method: 'PUT',\n        body: settings,\n        secure: true,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n     * @description Get config templates in different languages for rendering the settings page in the frontend\n     *\n     * @tags System\n     * @name GetSettingsTemplate\n     * @summary Get Settings Template\n     * @request GET:/settings/template/{locale}\n     * @secure\n     * @response `200` `HandlerResponseSettingTemplate` OK\n     */\n    getSettingsTemplate: (locale: string, params: RequestParams = {}) =>\n      this.request<HandlerResponseSettingTemplate, any>({\n        path: `/settings/template/${locale}`,\n        method: 'GET',\n        secure: true,\n        format: 'json',\n        ...params,\n      }),\n  }\n  sites = {\n    /**\n     * @description Get a list of sites by some conditions\n     *\n     * @tags Site\n     * @name GetSites\n     * @summary Get Site List\n     * @request GET:/sites\n     * @secure\n     * @response `200` `HandlerResponseSiteList` OK\n     */\n    getSites: (params: RequestParams = {}) =>\n      this.request<HandlerResponseSiteList, any>({\n        path: `/sites`,\n        method: 'GET',\n        secure: true,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Create a new site\n *\n * @tags Site\n * @name CreateSite\n * @summary Create Site\n * @request POST:/sites\n * @secure\n * @response `200` `HandlerResponseSiteCreate` OK\n * @response `400` `(HandlerMap & {\n    msg?: string,\n\n})` Bad Request\n * @response `403` `(HandlerMap & {\n    msg?: string,\n\n})` Forbidden\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    createSite: (site: HandlerParamsSiteCreate, params: RequestParams = {}) =>\n      this.request<\n        HandlerResponseSiteCreate,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/sites`,\n        method: 'POST',\n        body: site,\n        secure: true,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n     * @description Update a specific site\n     *\n     * @tags Site\n     * @name UpdateSite\n     * @summary Update Site\n     * @request PUT:/sites/{id}\n     * @secure\n     * @response `200` `HandlerResponseSiteUpdate` OK\n     */\n    updateSite: (id: number, site: HandlerParamsSiteUpdate, params: RequestParams = {}) =>\n      this.request<HandlerResponseSiteUpdate, any>({\n        path: `/sites/${id}`,\n        method: 'PUT',\n        body: site,\n        secure: true,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Delete a specific site\n *\n * @tags Site\n * @name DeleteSite\n * @summary Site Delete\n * @request DELETE:/sites/{id}\n * @secure\n * @response `200` `HandlerMap` OK\n * @response `403` `(HandlerMap & {\n    msg?: string,\n\n})` Forbidden\n * @response `404` `(HandlerMap & {\n    msg?: string,\n\n})` Not Found\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    deleteSite: (id: number, params: RequestParams = {}) =>\n      this.request<\n        HandlerMap,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/sites/${id}`,\n        method: 'DELETE',\n        secure: true,\n        format: 'json',\n        ...params,\n      }),\n  }\n  stats = {\n    /**\n * @description Get the statistics of various data analysis\n *\n * @tags Statistic\n * @name GetStats\n * @summary Statistic\n * @request GET:/stats/{type}\n * @response `200` `CommonJSONResult` OK\n * @response `400` `(HandlerMap & {\n    msg?: string,\n\n})` Bad Request\n * @response `403` `(HandlerMap & {\n    msg?: string,\n\n})` Forbidden\n * @response `404` `(HandlerMap & {\n    msg?: string,\n\n})` Not Found\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    getStats: (\n      type:\n        | 'latest_comments'\n        | 'latest_pages'\n        | 'pv_most_pages'\n        | 'comment_most_pages'\n        | 'page_pv'\n        | 'site_pv'\n        | 'page_comment'\n        | 'site_comment'\n        | 'rand_comments'\n        | 'rand_pages',\n      query?: {\n        /** The limit for pagination */\n        limit?: number\n        /** multiple page keys separated by commas */\n        page_keys?: string\n        /** The site name of your content scope */\n        site_name?: string\n      },\n      params: RequestParams = {},\n    ) =>\n      this.request<\n        CommonJSONResult,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/stats/${type}`,\n        method: 'GET',\n        query: query,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n  }\n  transfer = {\n    /**\n * @description Export data from Artalk\n *\n * @tags Transfer\n * @name ExportArtrans\n * @summary Export Artrans\n * @request GET:/transfer/export\n * @secure\n * @response `200` `HandlerResponseTransferExport` OK\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    exportArtrans: (params: RequestParams = {}) =>\n      this.request<\n        HandlerResponseTransferExport,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/transfer/export`,\n        method: 'GET',\n        secure: true,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n     * @description Import data to Artalk\n     *\n     * @tags Transfer\n     * @name ImportArtrans\n     * @summary Import Artrans\n     * @request POST:/transfer/import\n     * @secure\n     * @response `200` `string` OK\n     */\n    importArtrans: (data: HandlerParamsTransferImport, params: RequestParams = {}) =>\n      this.request<string, any>({\n        path: `/transfer/import`,\n        method: 'POST',\n        body: data,\n        secure: true,\n        type: ContentType.Json,\n        ...params,\n      }),\n\n    /**\n * @description Upload a file to prepare to import\n *\n * @tags Transfer\n * @name UploadArtrans\n * @summary Upload Artrans\n * @request POST:/transfer/upload\n * @secure\n * @response `200` `(HandlerResponseTransferUpload & {\n    filename?: string,\n\n})` OK\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    uploadArtrans: (\n      data: {\n        /**\n         * Upload file in preparation for import task\n         * @format binary\n         */\n        file: File\n      },\n      params: RequestParams = {},\n    ) =>\n      this.request<\n        HandlerResponseTransferUpload & {\n          filename?: string\n        },\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/transfer/upload`,\n        method: 'POST',\n        body: data,\n        secure: true,\n        type: ContentType.FormData,\n        format: 'json',\n        ...params,\n      }),\n  }\n  upload = {\n    /**\n * @description Upload file from this endpoint\n *\n * @tags Upload\n * @name Upload\n * @summary Upload\n * @request POST:/upload\n * @secure\n * @response `200` `HandlerResponseUpload` OK\n * @response `400` `(HandlerMap & {\n    msg?: string,\n\n})` Bad Request\n * @response `403` `(HandlerMap & {\n    msg?: string,\n\n})` Forbidden\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    upload: (\n      data: {\n        /**\n         * Upload file\n         * @format binary\n         */\n        file: File\n      },\n      params: RequestParams = {},\n    ) =>\n      this.request<\n        HandlerResponseUpload,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/upload`,\n        method: 'POST',\n        body: data,\n        secure: true,\n        type: ContentType.FormData,\n        format: 'json',\n        ...params,\n      }),\n  }\n  user = {\n    /**\n * @description Get user info to prepare for login or check current user status\n *\n * @tags Auth\n * @name GetUser\n * @summary Get User Info\n * @request GET:/user\n * @secure\n * @response `200` `HandlerResponseUserInfo` OK\n * @response `400` `(HandlerMap & {\n    msg?: string,\n\n})` Bad Request\n */\n    getUser: (\n      query?: {\n        /** The user email */\n        email?: string\n        /** The username */\n        name?: string\n      },\n      params: RequestParams = {},\n    ) =>\n      this.request<\n        HandlerResponseUserInfo,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/user`,\n        method: 'GET',\n        query: query,\n        secure: true,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Update user profile when user is logged in\n *\n * @tags Auth\n * @name UpdateProfile\n * @summary Update user profile\n * @request POST:/user\n * @secure\n * @response `200` `HandlerResponseUserInfoUpdate` OK\n * @response `400` `(HandlerMap & {\n    msg?: string,\n\n})` Bad Request\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    updateProfile: (data: HandlerRequestUserInfoUpdate, params: RequestParams = {}) =>\n      this.request<\n        HandlerResponseUserInfoUpdate,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/user`,\n        method: 'POST',\n        body: data,\n        secure: true,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Login user by name or email\n *\n * @tags Auth\n * @name Login\n * @summary Get Access Token\n * @request POST:/user/access_token\n * @response `200` `HandlerResponseUserLogin` OK\n * @response `400` `(HandlerMap & {\n    data?: {\n    need_name_select?: (string)[],\n\n},\n    msg?: string,\n\n})` Multiple users with the same email address are matched\n * @response `401` `(HandlerMap & {\n    msg?: string,\n\n})` Unauthorized\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    login: (user: HandlerParamsUserLogin, params: RequestParams = {}) =>\n      this.request<\n        HandlerResponseUserLogin,\n        | (HandlerMap & {\n            data?: {\n              need_name_select?: string[]\n            }\n            msg?: string\n          })\n        | (HandlerMap & {\n            msg?: string\n          })\n      >({\n        path: `/user/access_token`,\n        method: 'POST',\n        body: user,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n     * @description Get user login status by header Authorization\n     *\n     * @tags Auth\n     * @name GetUserStatus\n     * @summary Get Login Status\n     * @request GET:/user/status\n     * @secure\n     * @response `200` `HandlerResponseUserStatus` OK\n     */\n    getUserStatus: (\n      query?: {\n        /** The user email */\n        email?: string\n        /** The username */\n        name?: string\n      },\n      params: RequestParams = {},\n    ) =>\n      this.request<HandlerResponseUserStatus, any>({\n        path: `/user/status`,\n        method: 'GET',\n        query: query,\n        secure: true,\n        format: 'json',\n        ...params,\n      }),\n  }\n  users = {\n    /**\n * @description Create a new user\n *\n * @tags User\n * @name CreateUser\n * @summary Create User\n * @request POST:/users\n * @secure\n * @response `200` `HandlerResponseUserCreate` OK\n * @response `400` `(HandlerMap & {\n    msg?: string,\n\n})` Bad Request\n * @response `403` `(HandlerMap & {\n    msg?: string,\n\n})` Forbidden\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    createUser: (user: HandlerParamsUserCreate, params: RequestParams = {}) =>\n      this.request<\n        HandlerResponseUserCreate,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/users`,\n        method: 'POST',\n        body: user,\n        secure: true,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Update a specific user\n *\n * @tags User\n * @name UpdateUser\n * @summary Update User\n * @request PUT:/users/{id}\n * @secure\n * @response `200` `HandlerResponseUserUpdate` OK\n * @response `400` `(HandlerMap & {\n    msg?: string,\n\n})` Bad Request\n * @response `403` `(HandlerMap & {\n    msg?: string,\n\n})` Forbidden\n * @response `404` `(HandlerMap & {\n    msg?: string,\n\n})` Not Found\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    updateUser: (id: number, user: HandlerParamsUserUpdate, params: RequestParams = {}) =>\n      this.request<\n        HandlerResponseUserUpdate,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/users/${id}`,\n        method: 'PUT',\n        body: user,\n        secure: true,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Delete a specific user\n *\n * @tags User\n * @name DeleteUser\n * @summary Delete User\n * @request DELETE:/users/{id}\n * @secure\n * @response `200` `HandlerMap` OK\n * @response `403` `(HandlerMap & {\n    msg?: string,\n\n})` Forbidden\n * @response `404` `(HandlerMap & {\n    msg?: string,\n\n})` Not Found\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    deleteUser: (id: number, params: RequestParams = {}) =>\n      this.request<\n        HandlerMap,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/users/${id}`,\n        method: 'DELETE',\n        secure: true,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Get a list of users by some conditions\n *\n * @tags User\n * @name GetUsers\n * @summary Get User List\n * @request GET:/users/{type}\n * @secure\n * @response `200` `HandlerResponseAdminUserList` OK\n * @response `403` `(HandlerMap & {\n    msg?: string,\n\n})` Forbidden\n */\n    getUsers: (\n      type?: 'all' | 'admin' | 'in_conf',\n      query?: {\n        /** The limit for pagination */\n        limit?: number\n        /** The offset for pagination */\n        offset?: number\n        /** Search keywords */\n        search?: string\n      },\n      params: RequestParams = {},\n    ) =>\n      this.request<\n        HandlerResponseAdminUserList,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/users/${type}`,\n        method: 'GET',\n        query: query,\n        secure: true,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n  }\n  version = {\n    /**\n     * @description Get the version of Artalk\n     *\n     * @tags System\n     * @name GetVersion\n     * @summary Get Version Info\n     * @request GET:/version\n     * @response `200` `CommonApiVersionData` OK\n     */\n    getVersion: (params: RequestParams = {}) =>\n      this.request<CommonApiVersionData, any>({\n        path: `/version`,\n        method: 'GET',\n        format: 'json',\n        ...params,\n      }),\n  }\n  votes = {\n    /**\n * @description Sync the number of votes in the `comments` or `pages` data tables to keep them the same as the `votes` table\n *\n * @tags Vote\n * @name SyncVotes\n * @summary Sync Vote Data\n * @request POST:/votes/sync\n * @secure\n * @response `200` `HandlerMap` OK\n * @response `403` `(HandlerMap & {\n    msg?: string,\n\n})` Forbidden\n */\n    syncVotes: (params: RequestParams = {}) =>\n      this.request<\n        HandlerMap,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/votes/sync`,\n        method: 'POST',\n        secure: true,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Get vote status for a specific comment or page\n *\n * @tags Vote\n * @name GetVote\n * @summary Get Vote Status\n * @request GET:/votes/{target_name}/{target_id}\n * @response `200` `HandlerResponseVote` OK\n * @response `403` `(HandlerMap & {\n    msg?: string,\n\n})` Forbidden\n * @response `404` `(HandlerMap & {\n    msg?: string,\n\n})` Not Found\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    getVote: (targetName: 'comment' | 'page', targetId: number, params: RequestParams = {}) =>\n      this.request<\n        HandlerResponseVote,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/votes/${targetName}/${targetId}`,\n        method: 'GET',\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Create a new vote for a specific comment or page\n *\n * @tags Vote\n * @name CreateVote\n * @summary Create Vote\n * @request POST:/votes/{target_name}/{target_id}/{choice}\n * @response `200` `HandlerResponseVote` OK\n * @response `403` `(HandlerMap & {\n    msg?: string,\n\n})` Forbidden\n * @response `404` `(HandlerMap & {\n    msg?: string,\n\n})` Not Found\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    createVote: (\n      targetName: 'comment' | 'page',\n      targetId: number,\n      choice: 'up' | 'down',\n      vote: HandlerParamsVoteCreate,\n      params: RequestParams = {},\n    ) =>\n      this.request<\n        HandlerResponseVote,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/votes/${targetName}/${targetId}/${choice}`,\n        method: 'POST',\n        body: vote,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n  }\n}\n","import { ApiOptions } from './options'\nimport { FetchError } from '@/types'\n\nexport const Fetch = async (\n  opts: ApiOptions,\n  input: string | URL | Request,\n  init?: RequestInit,\n) => {\n  const apiToken = opts.getApiToken && opts.getApiToken()\n\n  const headers = new Headers({\n    Authorization: apiToken ? `Bearer ${apiToken}` : '',\n    ...init?.headers,\n  })\n\n  if (!headers.get('Authorization')) headers.delete('Authorization')\n\n  // 请求操作\n  const resp = await fetch(input, {\n    ...init,\n    headers,\n  })\n\n  if (!resp.ok) {\n    // Deserialize response body (if it is JSON, otherwise returns `{}`)\n    const json: any = (await resp.json().catch(() => {})) || {}\n\n    let retry = false\n    opts.handlers &&\n      (await opts.handlers.get().reduce(async (promise, item) => {\n        await promise\n        if (json[item.action] === true) {\n          await item.handler(json)\n          retry = true\n        }\n      }, Promise.resolve()))\n\n    if (retry) return Fetch(opts, input, init)\n    throw createError(resp.status, json)\n  }\n\n  return resp\n}\n\nexport class FetchException extends Error implements FetchError {\n  code: number = 0\n  message: string = 'fetch error'\n  data?: any\n}\n\nfunction createError(code: number, data: any): FetchException {\n  const err = new FetchException()\n  err.message = data.msg || data.message || 'fetch error'\n  err.code = code\n  err.data = data\n  console.error(err)\n  return err\n}\n","import { ApiOptions } from './options'\nimport { Api as ApiV2 } from './v2'\nimport { Fetch } from './fetch'\n\nexport * from './options'\nexport * from './handler'\n\nexport class Api extends ApiV2<void> {\n  private _opts: ApiOptions\n\n  constructor(opts: ApiOptions) {\n    super({\n      baseUrl: opts.baseURL,\n      customFetch: (input, init) => Fetch(opts, input, init),\n    })\n\n    this._opts = opts\n  }\n\n  /**\n   * Get user info as params for request\n   *\n   * @returns Request params with user info\n   */\n  getUserFields() {\n    const user = this._opts.userInfo\n    if (!user?.name || !user?.email) return undefined\n    return { name: user.name, email: user.email }\n  }\n}\n","import type PlugKit from './_kit'\nimport type { CommentData, EditorState } from '@/types'\nimport * as Utils from '@/lib/utils'\n\n/**\n * Editor 插件\n */\nexport class EditorPlugin {\n  $btn?: HTMLElement\n  $panel?: HTMLElement\n  contentTransformer?(rawContent: string): string\n  editorStateEffectWhen?: EditorState\n  editorStateEffect?(comment: CommentData): () => void\n\n  constructor(protected kit: PlugKit) {}\n\n  /** Use plug btn will add a btn on the bottom of editor */\n  useBtn(html: string = '<div></div>') {\n    this.$btn = Utils.createElement(`<span class=\"atk-plug-btn\">${html}</span>`)\n    return this.$btn\n  }\n\n  /** Use plug panel will show the panel when btn is clicked */\n  usePanel(html: string = '<div></div>') {\n    this.$panel = Utils.createElement(html)\n    return this.$panel\n  }\n\n  /** Use the content transformer to handle the content of the last submit by the editor */\n  useContentTransformer(func: (raw: string) => string) {\n    this.contentTransformer = func\n  }\n\n  /** Listen the event of panel show */\n  usePanelShow(func: () => void) {\n    this.kit.useEvents().on('panel-show', (aPlug) => {\n      if (aPlug === this) func()\n    })\n  }\n\n  /** Listen the event of panel hide */\n  usePanelHide(func: () => void) {\n    this.kit.useEvents().on('panel-hide', (aPlug) => {\n      if (aPlug === this) func()\n    })\n  }\n\n  /** Use editor state modifier */\n  useEditorStateEffect(stateName: EditorState, effectFn: (comment: CommentData) => () => void) {\n    this.editorStateEffectWhen = stateName\n    this.editorStateEffect = effectFn\n  }\n}\n\nexport default EditorPlugin\n","import type PlugKit from './_kit'\nimport EditorPlugin from './_plug'\nimport $t from '@/i18n'\n\nconst LocalStorageKey = 'ArtalkContent'\n\nexport default class LocalStorage extends EditorPlugin {\n  constructor(kit: PlugKit) {\n    super(kit)\n\n    const onContentUpdated = () => {\n      this.save()\n    }\n\n    this.kit.useMounted(() => {\n      // load editor content from localStorage when init\n      const localContent = window.localStorage.getItem(LocalStorageKey) || ''\n      if (localContent.trim() !== '') {\n        this.kit.useEditor().showNotify($t('restoredMsg'), 'i')\n        this.kit.useEditor().setContent(localContent)\n      }\n\n      // bind event\n      this.kit.useEvents().on('content-updated', onContentUpdated)\n    })\n\n    this.kit.useUnmounted(() => {\n      this.kit.useEvents().off('content-updated', onContentUpdated)\n    })\n  }\n\n  // Save editor content to localStorage\n  public save() {\n    window.localStorage.setItem(LocalStorageKey, this.kit.useEditor().getContentRaw().trim())\n  }\n}\n","import type PlugKit from './_kit'\nimport type { CommentData } from '@/types'\nimport * as Utils from '@/lib/utils'\n\nexport default class SubmitAddPreset {\n  constructor(private kit: PlugKit) {}\n\n  async reqAdd() {\n    const nComment = (\n      await this.kit.useApi().comments.createComment({\n        ...(await this.getSubmitAddParams()),\n      })\n    ).data\n    return nComment\n  }\n\n  async getSubmitAddParams() {\n    const { name, email, link } = this.kit.useUser().getData()\n    const conf = this.kit.useConf()\n\n    return {\n      content: this.kit.useEditor().getContentFinal(),\n      name,\n      email,\n      link,\n      rid: 0,\n      page_key: conf.pageKey,\n      page_title: conf.pageTitle,\n      site_name: conf.site,\n      ua: await Utils.getCorrectUserAgent(), // Get the corrected UA\n    }\n  }\n\n  postSubmitAdd(commentNew: CommentData) {\n    // insert the new comment to list\n    this.kit.useData().insertComment(commentNew)\n  }\n}\n","import EditorPlugin from './_plug'\nimport type PlugKit from './_kit'\nimport SubmitAddPreset from './submit-add'\nimport $t from '@/i18n'\nimport type { CommentData } from '@/types'\n\ninterface CustomSubmit {\n  activeCond: () => void\n  pre?: () => void\n  req?: () => Promise<CommentData>\n  /** The `post` method is called after the comment is successfully submitted */\n  post?: (nComment: CommentData) => void\n}\n\nexport default class Submit extends EditorPlugin {\n  private customs: CustomSubmit[] = []\n  private defaultPreset: SubmitAddPreset\n\n  constructor(kit: PlugKit) {\n    super(kit)\n\n    this.defaultPreset = new SubmitAddPreset(this.kit)\n\n    const onEditorSubmit = () => this.do()\n\n    this.kit.useMounted(() => {\n      // invoke `do()` when event `editor-submit` is triggered\n      this.kit.useEvents().on('editor-submit', onEditorSubmit)\n    })\n    this.kit.useUnmounted(() => {\n      this.kit.useEvents().off('editor-submit', onEditorSubmit)\n    })\n  }\n\n  registerCustom(c: CustomSubmit) {\n    this.customs.push(c)\n  }\n\n  private async do() {\n    if (this.kit.useEditor().getContentFinal().trim() === '') {\n      this.kit.useEditor().focus()\n      return\n    }\n\n    const custom = this.customs.find((o) => o.activeCond())\n\n    this.kit.useEditor().showLoading()\n\n    try {\n      // pre submit\n      if (custom?.pre) custom.pre()\n\n      let nComment: CommentData\n\n      // submit request\n      if (custom?.req) nComment = await custom.req()\n      else nComment = await this.defaultPreset.reqAdd()\n\n      // post submit\n      if (custom?.post) custom.post(nComment)\n      else this.defaultPreset.postSubmitAdd(nComment)\n    } catch (err: any) {\n      // submit error\n      console.error(err)\n      this.kit.useEditor().showNotify(`${$t('commentFail')}: ${err.message || String(err)}`, 'e')\n      return\n    } finally {\n      this.kit.useEditor().hideLoading()\n    }\n\n    this.kit.useEditor().reset() // 复原编辑器\n    this.kit.useEvents().trigger('editor-submitted')\n  }\n}\n","import EditorPlugin from './_plug'\nimport * as Utils from '@/lib/utils'\n\nexport default class Mover extends EditorPlugin {\n  private isMoved = false\n\n  move(afterEl: HTMLElement) {\n    if (this.isMoved) return\n    this.isMoved = true\n\n    const editorEl = this.kit.useUI().$el\n\n    editorEl.after(Utils.createElement('<div class=\"atk-editor-travel-placeholder\"></div>'))\n\n    const $travelPlace = Utils.createElement('<div></div>')\n    afterEl.after($travelPlace)\n    $travelPlace.replaceWith(editorEl)\n\n    editorEl.classList.add('atk-fade-in') // 添加渐入动画\n    editorEl.classList.add('editor-traveling')\n  }\n\n  back() {\n    if (!this.isMoved) return\n    this.isMoved = false\n    this.kit\n      .useArtalkRootEl()\n      .querySelector('.atk-editor-travel-placeholder')\n      ?.replaceWith(this.kit.useUI().$el)\n    this.kit.useUI().$el.classList.remove('editor-traveling')\n  }\n}\n","import * as Utils from './utils'\nimport type { NotifyLevel } from '@/types'\n\n/** 显示加载 */\nexport function showLoading(parentElem: HTMLElement, conf?: { transparentBg?: boolean }) {\n  // Use :scope https://developer.mozilla.org/en-US/docs/Web/CSS/:scope\n  let $loading = parentElem.querySelector<HTMLElement>(':scope > .atk-loading')\n  if (!$loading) {\n    $loading = Utils.createElement(\n      `<div class=\"atk-loading\" style=\"display: none;\">\n      <div class=\"atk-loading-spinner\">\n        <svg viewBox=\"25 25 50 50\"><circle cx=\"50\" cy=\"50\" r=\"20\" fill=\"none\" stroke-width=\"2\" stroke-miterlimit=\"10\"></circle></svg>\n      </div>\n    </div>`,\n    )\n    if (conf?.transparentBg) $loading.style.background = 'transparent'\n    parentElem.appendChild($loading)\n  }\n  $loading.style.display = ''\n\n  // spinner 延迟显示，若加载等待时间太短，没必要显示（闪一下即可）\n  const $spinner = $loading.querySelector<HTMLElement>('.atk-loading-spinner')\n  if ($spinner) {\n    $spinner.style.display = 'none'\n    window.setTimeout(() => {\n      if ($spinner.isConnected) $spinner.style.display = ''\n    }, 500)\n  }\n}\n\n/** 隐藏加载 */\nexport function hideLoading(parentElem: HTMLElement) {\n  const $loading = parentElem.querySelector<HTMLElement>(':scope > .atk-loading')\n  if ($loading) $loading.style.display = 'none'\n}\n\n/** 元素加载动画 */\nexport function setLoading(val: boolean, parentElem: HTMLElement) {\n  if (val) showLoading(parentElem)\n  else hideLoading(parentElem)\n}\n\n/** 元素是否用户可见 */\nexport function isVisible(el: HTMLElement, viewport: HTMLElement = document.documentElement) {\n  const viewportHeight = viewport.clientHeight\n\n  const docViewTop = viewport.scrollTop\n  const docViewBottom = docViewTop + viewportHeight\n\n  const rect = el.getBoundingClientRect()\n  const elemTop = rect.top + docViewTop\n  const elemBottom = elemTop + rect.height\n\n  return elemBottom <= docViewBottom //&& (elemTop >= docViewTop) 注释因为假如 el 比 viewport 还高就会失效\n}\n\n/** 滚动到元素中心 */\nexport function scrollIntoView(\n  elem: HTMLElement,\n  enableAnim: boolean = true,\n  relativeTo?: HTMLElement,\n) {\n  let top: number\n\n  if (relativeTo) {\n    const containerRect = relativeTo.getBoundingClientRect()\n    const elementRect = elem.getBoundingClientRect()\n    top =\n      elementRect.top -\n      containerRect.top +\n      relativeTo.scrollTop -\n      relativeTo.clientHeight / 2 +\n      elem.clientHeight / 2\n  } else {\n    const rect = elem.getBoundingClientRect()\n    const elemTop = rect.top + window.scrollY\n    top = elemTop - (window.innerHeight / 2 - rect.height / 2)\n  }\n\n  const scrollOptions: ScrollToOptions = {\n    top,\n    left: 0,\n    // behavior: enableAnim ? 'smooth' : 'instant',\n    behavior: 'instant',\n  }\n\n  if (relativeTo) relativeTo.scroll(scrollOptions)\n  else window.scroll(scrollOptions)\n}\n\n/** 显示消息 */\nexport function showNotify(wrapElem: HTMLElement, msg: string, type: NotifyLevel) {\n  const colors = { s: '#57d59f', e: '#ff6f6c', w: '#ffc721', i: '#2ebcfc' }\n  const timeout = 3000 // 持续显示时间 ms\n\n  const notifyElem = Utils.createElement(\n    `<div class=\"atk-notify atk-fade-in\" style=\"background-color: ${colors[type]}\"><span class=\"atk-notify-content\"></span></div>`,\n  )\n  const notifyContentEl = notifyElem.querySelector<HTMLElement>('.atk-notify-content')!\n  notifyContentEl.innerHTML = Utils.htmlEncode(msg).replace('\\n', '<br/>')\n\n  wrapElem.appendChild(notifyElem)\n\n  const notifyRemove = () => {\n    notifyElem.classList.add('atk-fade-out')\n    setTimeout(() => {\n      notifyElem.remove()\n    }, 200)\n  }\n\n  let timeoutFn: number\n  if (timeout > 0) {\n    timeoutFn = window.setTimeout(() => {\n      notifyRemove()\n    }, timeout)\n  }\n\n  notifyElem.addEventListener('click', () => {\n    notifyRemove()\n    window.clearTimeout(timeoutFn)\n  })\n}\n\n/** fade 动画 */\nexport function playFadeAnim(elem: HTMLElement, after?: () => void, type: 'in' | 'out' = 'in') {\n  elem.classList.add(`atk-fade-${type}`)\n  // 动画结束清除 class\n  const onAnimEnded = () => {\n    elem.classList.remove(`atk-fade-${type}`)\n    elem.removeEventListener('animationend', onAnimEnded)\n    if (after) after()\n  }\n  elem.addEventListener('animationend', onAnimEnded)\n}\n\n/** 渐入动画 */\nexport function playFadeInAnim(elem: HTMLElement, after?: () => void) {\n  playFadeAnim(elem, after, 'in')\n}\n\n/** 渐出动画 */\nexport function playFadeOutAnim(elem: HTMLElement, after?: () => void) {\n  playFadeAnim(elem, after, 'out')\n}\n\n/** 设置全局错误 */\nexport function setError(\n  parentElem: HTMLElement,\n  html: string | HTMLElement | null,\n  title: string = '<span class=\"atk-error-title\">Artalk Error</span>',\n) {\n  let elem = parentElem.querySelector<HTMLElement>('.atk-error-layer')\n  if (html === null) {\n    if (elem !== null) elem.remove()\n    return\n  }\n  if (!elem) {\n    elem = Utils.createElement(\n      `<div class=\"atk-error-layer\">${title}<span class=\"atk-error-text\"></span></div>`,\n    )\n    parentElem.appendChild(elem)\n  }\n\n  const errorTextEl = elem.querySelector<HTMLElement>('.atk-error-text')!\n  errorTextEl.innerHTML = ''\n  if (html === null) return\n\n  if (html instanceof HTMLElement) {\n    errorTextEl.appendChild(html)\n  } else {\n    errorTextEl.innerText = html\n  }\n}\n\nexport function getScrollBarWidth() {\n  const inner = document.createElement('p')\n  inner.style.width = '100%'\n  inner.style.height = '200px'\n\n  const outer = document.createElement('div')\n  outer.style.position = 'absolute'\n  outer.style.top = '0px'\n  outer.style.left = '0px'\n  outer.style.visibility = 'hidden'\n  outer.style.width = '200px'\n  outer.style.height = '150px'\n  outer.style.overflow = 'hidden'\n  outer.appendChild(inner)\n\n  document.body.appendChild(outer)\n  const w1 = inner.offsetWidth\n  outer.style.overflow = 'scroll'\n  let w2 = inner.offsetWidth\n  if (w1 === w2) w2 = outer.clientWidth\n\n  document.body.removeChild(outer)\n\n  return w1 - w2\n}\n","import './emoticons.scss'\n\nimport EditorPlugin from './_plug'\nimport type PlugKit from './_kit'\nimport type { EmoticonListData, EmoticonGrpData } from '@/types'\nimport * as Utils from '@/lib/utils'\nimport * as Ui from '@/lib/ui'\nimport $t from '@/i18n'\n\ntype OwOFormatType = {\n  [key: string]: {\n    type: 'emoticon' | 'emoji' | 'image'\n    container: { icon: string; text: string }[]\n  }\n}\n\nexport default class Emoticons extends EditorPlugin {\n  private emoticons: EmoticonListData = []\n  private loadingTask: Promise<void> | null = null\n\n  private $grpWrap!: HTMLElement\n  private $grpSwitcher!: HTMLElement\n\n  constructor(kit: PlugKit) {\n    super(kit)\n\n    this.kit.useMounted(() => {\n      this.usePanel(`<div class=\"atk-editor-plug-emoticons\"></div>`)\n      this.useBtn(\n        `<i aria-label=\"${$t('emoticon')}\"><svg fill=\"currentColor\" aria-hidden=\"true\" height=\"14\" viewBox=\"0 0 14 14\" width=\"14\"><path d=\"m4.26829 5.29294c0-.94317.45893-1.7074 1.02439-1.7074.56547 0 1.02439.76423 1.02439 1.7074s-.45892 1.7074-1.02439 1.7074c-.56546 0-1.02439-.76423-1.02439-1.7074zm4.43903 1.7074c.56546 0 1.02439-.76423 1.02439-1.7074s-.45893-1.7074-1.02439-1.7074c-.56547 0-1.02439.76423-1.02439 1.7074s.45892 1.7074 1.02439 1.7074zm-1.70732 2.73184c-1.51883 0-2.06312-1.52095-2.08361-1.58173l-1.29551.43231c.03414.10244.868 2.51604 3.3798 2.51604 2.51181 0 3.34502-2.41291 3.37982-2.51604l-1.29484-.43573c-.02254.06488-.56683 1.58583-2.08498 1.58583zm7-2.73252c0 3.86004-3.1401 7.00034-7 7.00034s-7-3.1396-7-6.99966c0-3.86009 3.1401-7.00034 7-7.00034s7 3.14025 7 7.00034zm-1.3659 0c0-3.10679-2.5275-5.63442-5.6341-5.63442-3.10663 0-5.63415 2.52832-5.63415 5.6351 0 3.10676 2.52752 5.63446 5.63415 5.63446 3.1066 0 5.6341-2.5277 5.6341-5.63446z\"/></svg></i>`,\n      )\n    })\n    this.kit.useUnmounted(() => {})\n\n    this.useContentTransformer((raw) => this.transEmoticonImageText(raw))\n    this.usePanelShow(() => {\n      ;(async () => {\n        await this.loadEmoticonsData()\n\n        // 初始化元素\n        if (!this.isImgLoaded) {\n          this.initEmoticonsList()\n          this.isImgLoaded = true\n        }\n\n        // 延迟执行，防止无法读取高度\n        setTimeout(() => {\n          this.changeListHeight()\n        }, 30)\n      })()\n    })\n    this.usePanelHide(() => {\n      this.$panel!.parentElement!.style.height = ''\n    })\n\n    // 表情包预加载\n    window.setTimeout(() => {\n      this.loadEmoticonsData()\n    }, 1000) // 延迟 1s 加载\n  }\n\n  private isListLoaded = false\n  private isImgLoaded = false\n\n  public async loadEmoticonsData() {\n    if (this.isListLoaded) return\n    if (this.loadingTask !== null) {\n      await this.loadingTask\n      return\n    }\n\n    // 数据处理\n    this.loadingTask = (async () => {\n      Ui.showLoading(this.$panel!)\n      this.emoticons = await this.handleData(this.kit.useConf().emoticons)\n      Ui.hideLoading(this.$panel!)\n      this.loadingTask = null\n      this.isListLoaded = true\n    })()\n    await this.loadingTask\n  }\n\n  private async handleData(data: any): Promise<any[]> {\n    if (!Array.isArray(data) && ['object', 'string'].includes(typeof data)) {\n      data = [data]\n    }\n\n    if (!Array.isArray(data)) {\n      Ui.setError(this.$panel!, `[${$t('emoticon')}] Data must be of Array/Object/String type`)\n      Ui.hideLoading(this.$panel!)\n      return []\n    }\n\n    const pushGrp = (grp: EmoticonGrpData) => {\n      if (typeof grp !== 'object') return\n      if (grp.name && data.find((o) => o.name === grp.name)) return\n      data.push(grp)\n    }\n\n    // 加载子内容\n    const remoteLoad = async (d: any[]) => {\n      await Promise.all(\n        d.map(async (grp, index) => {\n          if (typeof grp === 'object' && !Array.isArray(grp)) {\n            pushGrp(grp)\n          } else if (Array.isArray(grp)) {\n            await remoteLoad(grp)\n          } else if (typeof grp === 'string') {\n            const grpData = await this.remoteLoad(grp)\n\n            if (Array.isArray(grpData)) await remoteLoad(grpData)\n            else if (typeof grpData === 'object') pushGrp(grpData)\n          }\n        }),\n      )\n    }\n    await remoteLoad(data)\n\n    // 处理数组数据\n    data.forEach((item: any) => {\n      if (this.isOwOFormat(item)) {\n        const c = this.convertOwO(item)\n        c.forEach((grp) => {\n          pushGrp(grp)\n        })\n      } else if (Array.isArray(item)) {\n        item.forEach((grp) => {\n          pushGrp(grp)\n        })\n      }\n    })\n\n    // 剔除非法数据\n    data = data.filter(\n      (item: any) => typeof item === 'object' && !Array.isArray(item) && !!item && !!item.name,\n    )\n\n    // console.log(data)\n\n    this.solveNullKey(data)\n    this.solveSameKey(data)\n\n    return data\n  }\n\n  /** 远程加载 */\n  private async remoteLoad(url: string): Promise<any> {\n    if (!url) return []\n\n    try {\n      const resp = await fetch(url)\n      const json = await resp.json()\n      return json\n    } catch (err) {\n      Ui.hideLoading(this.$panel!)\n      console.error('[Emoticons] Load Failed:', err)\n      Ui.setError(this.$panel!, `[${$t('emoticon')}] ${$t('loadFail')}: ${String(err)}`)\n      return []\n    }\n  }\n\n  /** 避免表情 item.key 为 null 的情况 */\n  private solveNullKey(data: EmoticonGrpData[]) {\n    data.forEach((grp) => {\n      grp.items.forEach((item, index) => {\n        if (!item.key) item.key = `${grp.name} ${index + 1}`\n      })\n    })\n  }\n\n  /** 避免相同 item.key */\n  private solveSameKey(data: EmoticonGrpData[]) {\n    const tmp: { [key: string]: number } = {}\n    data.forEach((grp) => {\n      grp.items.forEach((item) => {\n        if (!item.key || String(item.key).trim() === '') return\n        if (!tmp[item.key]) tmp[item.key] = 1\n        else tmp[item.key]++\n\n        if (tmp[item.key] > 1) item.key = `${item.key} ${tmp[item.key]}`\n      })\n    })\n  }\n\n  /** 判断是否为 OwO 格式 */\n  private isOwOFormat(data: any) {\n    try {\n      return (\n        typeof data === 'object' &&\n        !!Object.values(data).length &&\n        Array.isArray(Object.keys(Object.values<any>(data)[0].container)) &&\n        Object.keys(Object.values<any>(data)[0].container[0]).includes('icon')\n      )\n    } catch {\n      return false\n    }\n  }\n\n  /** 转换 OwO 格式数据 */\n  private convertOwO(owoData: OwOFormatType): EmoticonListData {\n    const dest: EmoticonListData = []\n    Object.entries(owoData).forEach(([grpName, grp]) => {\n      const nGrp: EmoticonGrpData = { name: grpName, type: grp.type, items: [] }\n      grp.container.forEach((item, index) => {\n        // 图片标签提取 src 属性值\n        const iconStr = item.icon\n        if (/<(img|IMG)/.test(iconStr)) {\n          const find = /src=[\"'](.*?)[\"']/.exec(iconStr)\n          if (find && find.length > 1) item.icon = find[1]\n        }\n        nGrp.items.push({\n          key: item.text || `${grpName} ${index + 1}`,\n          val: item.icon,\n        })\n      })\n      dest.push(nGrp)\n    })\n    return dest\n  }\n\n  /** 初始化表情列表界面 */\n  private initEmoticonsList() {\n    // 表情列表\n    this.$grpWrap = Utils.createElement(`<div class=\"atk-grp-wrap\"></div>`)\n    this.$panel!.append(this.$grpWrap)\n\n    this.emoticons.forEach((grp, index) => {\n      const $grp = Utils.createElement(`<div class=\"atk-grp\" style=\"display: none;\"></div>`)\n      this.$grpWrap.append($grp)\n      $grp.setAttribute('data-index', String(index))\n      $grp.setAttribute('data-grp-name', grp.name)\n      $grp.setAttribute('data-type', grp.type)\n      grp.items.forEach((item) => {\n        const $item = Utils.createElement(`<span class=\"atk-item\"></span>`)\n        $grp.append($item)\n\n        if (!!item.key && !new RegExp(`^(${grp.name})?\\\\s?[0-9]+$`).test(item.key))\n          $item.setAttribute('title', item.key)\n\n        if (grp.type === 'image') {\n          const imgEl = document.createElement('img')\n          imgEl.src = item.val\n          imgEl.alt = item.key\n          $item.append(imgEl)\n        } else {\n          $item.innerText = item.val\n        }\n\n        $item.onclick = () => {\n          if (grp.type === 'image') {\n            this.kit.useEditor().insertContent(`:[${item.key}]`)\n          } else {\n            this.kit.useEditor().insertContent(item.val || '')\n          }\n        }\n      })\n    })\n\n    // 表情分类切换 bar\n    if (this.emoticons.length > 1) {\n      this.$grpSwitcher = Utils.createElement(`<div class=\"atk-grp-switcher\"></div>`)\n      this.$panel!.append(this.$grpSwitcher)\n      this.emoticons.forEach((grp, index) => {\n        const $item = Utils.createElement('<span />')\n        $item.innerText = grp.name\n        $item.setAttribute('data-index', String(index))\n        $item.onclick = () => this.openGrp(index)\n        this.$grpSwitcher.append($item)\n      })\n    }\n\n    // 默认打开第一个分类\n    if (this.emoticons.length > 0) this.openGrp(0)\n  }\n\n  /** 打开一个表情组 */\n  public openGrp(index: number) {\n    Array.from(this.$grpWrap.children).forEach((item) => {\n      const el = item as HTMLElement\n      if (el.getAttribute('data-index') !== String(index)) {\n        el.style.display = 'none'\n      } else {\n        el.style.display = ''\n      }\n    })\n\n    this.$grpSwitcher\n      ?.querySelectorAll('span.active')\n      .forEach((item) => item.classList.remove('active'))\n    this.$grpSwitcher?.querySelector(`span[data-index=\"${index}\"]`)?.classList.add('active')\n\n    this.changeListHeight()\n  }\n\n  private changeListHeight() {\n    /* const listWrapHeight = Utils.getHeight(this.$grpWrapem)\n    this.editor.plugWrapEl.style.height = `${listWrapHeight > 150 ? listWrapHeight : 150}px` */\n  }\n\n  /** 处理评论 content 中的表情内容 */\n  public transEmoticonImageText(text: string) {\n    if (!this.emoticons || !Array.isArray(this.emoticons)) return text\n\n    this.emoticons.forEach((grp) => {\n      if (grp.type !== 'image') return\n      Object.entries(grp.items).forEach(([index, item]) => {\n        text = text\n          .split(`:[${item.key}]`)\n          .join(`<img src=\"${item.val}\" atk-emoticon=\"${item.key}\">`) // replaceAll(...)\n      })\n    })\n\n    return text\n  }\n}\n","import type PlugKit from './_kit'\nimport EditorPlugin from './_plug'\nimport * as Utils from '@/lib/utils'\nimport $t from '@/i18n'\n\n/** 允许的图片格式 */\nconst AllowImgExts = ['png', 'jpg', 'jpeg', 'gif', 'bmp', 'svg', 'webp']\n\nexport default class Upload extends EditorPlugin {\n  private $imgUploadInput?: HTMLInputElement\n\n  constructor(kit: PlugKit) {\n    super(kit)\n\n    this.kit.useMounted(() => this.init())\n\n    this.initDragImg()\n  }\n\n  private init() {\n    this.$imgUploadInput = document.createElement('input')\n    this.$imgUploadInput.type = 'file'\n    this.$imgUploadInput.style.display = 'none'\n    this.$imgUploadInput.accept = AllowImgExts.map((o) => `.${o}`).join(',')\n\n    // TODO: Use btn cannot refresh when mounted event is triggered\n    const $btn = this.useBtn(\n      `<i aria-label=\"${$t('uploadImage')}\"><svg fill=\"currentColor\" aria-hidden=\"true\" height=\"14\" viewBox=\"0 0 14 14\" width=\"14\"><path d=\"m0 1.94444c0-1.074107.870333-1.94444 1.94444-1.94444h10.11116c1.0741 0 1.9444.870333 1.9444 1.94444v10.11116c0 1.0741-.8703 1.9444-1.9444 1.9444h-10.11116c-1.074107 0-1.94444-.8703-1.94444-1.9444zm1.94444-.38888c-.21466 0-.38888.17422-.38888.38888v7.06689l2.33333-2.33333 2.33333 2.33333 3.88888-3.88889 2.3333 2.33334v-5.51134c0-.21466-.1742-.38888-.3888-.38888zm10.49996 8.09977-2.3333-2.33333-3.88888 3.8889-2.33333-2.33334-2.33333 2.33334v.8447c0 .2146.17422.3888.38888.3888h10.11116c.2146 0 .3888-.1742.3888-.3888zm-7.1944-6.54422c-.75133 0-1.36111.60978-1.36111 1.36111 0 .75134.60978 1.36111 1.36111 1.36111s1.36111-.60977 1.36111-1.36111c0-.75133-.60978-1.36111-1.36111-1.36111z\"/></svg></i>`,\n    )\n    $btn.after(this.$imgUploadInput)\n    $btn.onclick = () => {\n      // 选择图片\n      const $input = this.$imgUploadInput!\n      $input.onchange = () => {\n        ;(async () => {\n          // 解决阻塞 UI 问题\n          if (!$input.files || $input.files.length === 0) return\n          const file = $input.files[0]\n          this.uploadImg(file)\n        })()\n      }\n      $input.click() // 显示选择图片对话框\n    }\n\n    if (!this.kit.useConf().imgUpload) {\n      this.$btn!.setAttribute('atk-only-admin-show', '')\n    }\n  }\n\n  private initDragImg() {\n    // 统一从 FileList 获取文件并上传图片方法\n    const uploadFromFileList = (files?: FileList) => {\n      if (!files) return\n\n      for (let i = 0; i < files.length; i++) {\n        const file = files[i]\n        this.uploadImg(file)\n      }\n    }\n\n    // 拖拽图片\n    // @link https://developer.mozilla.org/zh-CN/docs/Web/API/HTML_Drag_and_Drop_API/File_drag_and_drop\n    // 阻止浏览器的默认释放行为\n    const onDragover = (evt: Event) => {\n      evt.stopPropagation()\n      evt.preventDefault()\n    }\n\n    const onDrop = (evt: DragEvent) => {\n      const files = evt.dataTransfer?.files\n      if (files?.length) {\n        evt.preventDefault()\n        uploadFromFileList(files)\n      }\n    }\n\n    // 粘贴图片\n    const onPaste = (evt: ClipboardEvent) => {\n      const files = evt.clipboardData?.files\n      if (files?.length) {\n        evt.preventDefault()\n        uploadFromFileList(files)\n      }\n    }\n\n    this.kit.useMounted(() => {\n      this.kit.useUI().$textarea.addEventListener('dragover', onDragover)\n      this.kit.useUI().$textarea.addEventListener('drop', onDrop)\n      this.kit.useUI().$textarea.addEventListener('paste', onPaste)\n    })\n    this.kit.useUnmounted(() => {\n      this.kit.useUI().$textarea.removeEventListener('dragover', onDragover)\n      this.kit.useUI().$textarea.removeEventListener('drop', onDrop)\n      this.kit.useUI().$textarea.removeEventListener('paste', onPaste)\n    })\n  }\n\n  async uploadImg(file: File) {\n    const fileExt = /[^.]+$/.exec(file.name)\n    if (!fileExt || !AllowImgExts.includes(String(fileExt[0]).toLowerCase())) return\n\n    // 未登录提示\n    if (!this.kit.useUser().checkHasBasicUserInfo()) {\n      this.kit.useEditor().showNotify($t('uploadLoginMsg'), 'w')\n      return\n    }\n\n    // 插入图片前换一行\n    let insertPrefix = '\\n'\n    if (this.kit.useUI().$textarea.value.trim() === '') insertPrefix = ''\n\n    // 插入占位加载文字\n    const uploadPlaceholderTxt = `${insertPrefix}![](Uploading ${file.name}...)`\n    this.kit.useEditor().insertContent(uploadPlaceholderTxt)\n\n    // 上传图片\n    let resp: { public_url: string } | undefined\n    try {\n      const customUploaderFn = this.kit.useConf().imgUploader\n      if (!customUploaderFn) {\n        // 使用 Artalk 进行图片上传\n        resp = (await this.kit.useApi().upload.upload({ file })).data\n      } else {\n        // 使用自定义的图片上传器\n        resp = { public_url: await customUploaderFn(file) }\n      }\n    } catch (err: any) {\n      console.error(err)\n      this.kit.useEditor().showNotify(`${$t('uploadFail')}: ${err.message}`, 'e')\n    }\n    if (!!resp && resp.public_url) {\n      let imgURL = resp.public_url as string\n\n      // 若为相对路径，加上 artalk server\n      if (!Utils.isValidURL(imgURL))\n        imgURL = Utils.getURLBasedOnApi({\n          base: this.kit.useConf().server,\n          path: imgURL,\n        })\n\n      // 上传成功插入图片\n      this.kit\n        .useEditor()\n        .setContent(\n          this.kit\n            .useUI()\n            .$textarea.value.replace(uploadPlaceholderTxt, `${insertPrefix}![](${imgURL})`),\n        )\n    } else {\n      // 上传失败删除加载文字\n      this.kit\n        .useEditor()\n        .setContent(this.kit.useUI().$textarea.value.replace(uploadPlaceholderTxt, ''))\n    }\n  }\n}\n","import './preview.scss'\n\nimport EditorPlugin from './_plug'\nimport type PlugKit from './_kit'\nimport $t from '@/i18n'\n\nexport default class Preview extends EditorPlugin {\n  private isPlugPanelShow = false\n\n  constructor(kit: PlugKit) {\n    super(kit)\n\n    this.kit.useMounted(() => {\n      this.usePanel(`<div class=\"atk-editor-plug-preview\"></div>`)\n\n      // initialize plug button\n      this.useBtn(\n        `<i aria-label=\"${$t('preview')}\"><svg fill=\"currentColor\" aria-hidden=\"true\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\"><path fill-rule=\"evenodd\" d=\"M14.85 3H1.15C.52 3 0 3.52 0 4.15v7.69C0 12.48.52 13 1.15 13h13.69c.64 0 1.15-.52 1.15-1.15v-7.7C16 3.52 15.48 3 14.85 3zM9 11H7V8L5.5 9.92 4 8v3H2V5h2l1.5 2L7 5h2v6zm2.99.5L9.5 8H11V5h2v3h1.5l-2.51 3.5z\"></path></svg></i>`,\n      )\n    })\n    this.kit.useUnmounted(() => {})\n\n    // function to update content\n    this.kit.useEvents().on('content-updated', (content) => {\n      this.isPlugPanelShow && this.updateContent()\n    })\n\n    this.usePanelShow(() => {\n      this.isPlugPanelShow = true\n      this.updateContent()\n    })\n    this.usePanelHide(() => {\n      this.isPlugPanelShow = false\n    })\n  }\n\n  updateContent() {\n    this.$panel!.innerHTML = this.kit.useEditor().getContentMarked()\n  }\n}\n","import type EditorPlugin from './_plug'\nimport LocalStorage from './local-storage'\nimport Textarea from './textarea'\nimport SubmitBtn from './submit-btn'\nimport Submit from './submit'\nimport StateReply from './state-reply'\nimport StateEdit from './state-edit'\nimport Closable from './closable'\nimport HeaderEvent from './header-event'\nimport HeaderUser from './header-user'\nimport HeaderLink from './header-link'\nimport Mover from './mover'\nimport Emoticons from './emoticons'\nimport Upload from './upload'\nimport Preview from './preview'\nimport type { Config } from '@/types'\n\n/** The default enabled plugs */\nconst EDITOR_PLUGS: (typeof EditorPlugin)[] = [\n  // Core\n  LocalStorage,\n  HeaderEvent,\n  HeaderUser,\n  HeaderLink,\n  Textarea,\n  Submit,\n  SubmitBtn,\n  Mover,\n  StateReply,\n  StateEdit,\n  Closable,\n\n  // Extensions\n  Emoticons,\n  Upload,\n  Preview,\n]\n\n/**\n * Get the enabled plugs by config\n */\nexport function getEnabledPlugs(\n  conf: Pick<Config, 'imgUpload' | 'emoticons' | 'preview' | 'editorTravel'>,\n): (typeof EditorPlugin)[] {\n  // The reference map of config and plugs\n  // (for check if the plug is enabled)\n  const confRefs = new Map<typeof EditorPlugin, any>()\n  confRefs.set(Upload, conf.imgUpload)\n  confRefs.set(Emoticons, conf.emoticons)\n  confRefs.set(Preview, conf.preview)\n  confRefs.set(Mover, conf.editorTravel)\n\n  return EDITOR_PLUGS.filter((p) => !confRefs.has(p) || !!confRefs.get(p))\n}\n","import EditorPlugin from './_plug'\nimport type PlugKit from './_kit'\n\nexport default class HeaderEvent extends EditorPlugin {\n  private get $inputs() {\n    return this.kit.useEditor().getHeaderInputEls()\n  }\n\n  constructor(kit: PlugKit) {\n    super(kit)\n\n    const inputEventFns: { [name: string]: () => void } = {}\n    const changeEventFns: { [name: string]: () => void } = {}\n\n    const trigger =\n      (evt: 'header-input' | 'header-change', $input: HTMLInputElement, field: string) => () => {\n        this.kit.useEvents().trigger(evt, { field, $input })\n      }\n\n    this.kit.useMounted(() => {\n      // batch bind the events\n      Object.entries(this.$inputs).forEach(([key, $input]) => {\n        $input.addEventListener(\n          'input',\n          (inputEventFns[key] = trigger('header-input', $input, key)),\n        )\n        $input.addEventListener(\n          'change',\n          (changeEventFns[key] = trigger('header-change', $input, key)),\n        )\n      })\n    })\n\n    this.kit.useUnmounted(() => {\n      // unmount the event\n      Object.entries(this.$inputs).forEach(([key, $input]) => {\n        $input.removeEventListener('input', inputEventFns[key])\n        $input.removeEventListener('change', changeEventFns[key])\n      })\n    })\n  }\n}\n","import EditorPlugin from './_plug'\nimport type PlugKit from './_kit'\nimport $t from '@/i18n'\nimport type { UserInfoApiResponseData } from '@/types'\n\nexport default class HeaderUser extends EditorPlugin {\n  constructor(kit: PlugKit) {\n    super(kit)\n\n    const onInput = ({ $input, field }: { $input: HTMLInputElement; field: string }) => {\n      if (this.kit.useEditor().getState() === 'edit') return // TODO: prevent execute when editing, since update comment.user not support\n\n      // update user data\n      this.kit.useUser().update({ [field]: $input.value.trim() })\n\n      // remote fetch user info\n      if (field === 'name' || field === 'email') this.fetchUserInfo() // must after update user data, since fetchUserInfo() will use User.data\n    }\n\n    const placeholders = {\n      name: $t('nick'),\n      email: $t('email'),\n      link: $t('link'),\n    }\n\n    this.kit.useMounted(() => {\n      Object.entries(this.kit.useEditor().getHeaderInputEls()).forEach(([key, $input]) => {\n        // set placeholder\n        $input.placeholder = placeholders[key]\n\n        // sync header values from User.data\n        $input.value = this.kit.useUser().getData()[key] || ''\n      })\n\n      // bind events\n      this.kit.useEvents().on('header-input', onInput)\n    })\n\n    this.kit.useUnmounted(() => {\n      this.kit.useEvents().off('header-input', onInput)\n    })\n  }\n\n  private query = {\n    timer: <number | null>null,\n    abortFn: <(() => void) | null>null,\n  }\n\n  /**\n   * Fetch user info from server\n   */\n  private fetchUserInfo() {\n    this.kit.useUser().logout() // clear login status\n\n    if (this.query.timer) window.clearTimeout(this.query.timer) // clear the not executed timeout task\n    if (this.query.abortFn) this.query.abortFn() // abort the last request (if request is pending not finished)\n\n    this.query.timer = window.setTimeout(() => {\n      this.query.timer = null // clear the timer (clarify the timer is executing)\n\n      const api = this.kit.useApi()\n      const CANCEL_TOKEN = 'getUserCancelToken'\n      this.query.abortFn = () => api.abortRequest(CANCEL_TOKEN)\n\n      api.user\n        .getUser(\n          { ...api.getUserFields() },\n          {\n            cancelToken: CANCEL_TOKEN,\n          },\n        )\n        .then((res) => this.onUserInfoFetched(res.data))\n        .catch((err) => {})\n        .finally(() => {\n          this.query.abortFn = null // clear the abort function (clarify the request is finished)\n        })\n    }, 400) // delay to reduce request\n  }\n\n  /**\n   * Function called when user info fetched\n   *\n   * @param data The response data from server\n   */\n  private onUserInfoFetched(data: UserInfoApiResponseData) {\n    // If api response is not login, logout\n    if (!data.is_login) this.kit.useUser().logout()\n\n    // Update unread notifies\n    this.kit.useData().updateNotifies(data.notifies)\n\n    // If user is admin and not login,\n    if (this.kit.useUser().checkHasBasicUserInfo() && !data.is_login && data.user?.is_admin) {\n      // then show login window\n      this.kit.useCheckers().checkAdmin({\n        onSuccess: () => {},\n      })\n    }\n\n    // Auto fill user link from server\n    if (data.user && data.user.link) {\n      this.kit.useUI().$link.value = data.user.link\n      this.kit.useUser().update({ link: data.user.link })\n    }\n  }\n}\n","import EditorPlugin from './_plug'\nimport type PlugKit from './_kit'\n\nexport default class HeaderLink extends EditorPlugin {\n  constructor(kit: PlugKit) {\n    super(kit)\n\n    const onLinkChange = ({ field }: { field: string }) => {\n      if (field === 'link') this.onLinkInputChange()\n    }\n\n    // bind events\n    this.kit.useMounted(() => {\n      this.kit.useEvents().on('header-change', onLinkChange)\n    })\n\n    this.kit.useUnmounted(() => {\n      this.kit.useEvents().off('header-change', onLinkChange)\n    })\n  }\n\n  private onLinkInputChange() {\n    // auto and force add protocol prefix for user input link\n    const link = this.kit.useUI().$link.value.trim()\n    if (!!link && !/^(http|https):\\/\\//.test(link)) {\n      this.kit.useUI().$link.value = `https://${link}`\n      this.kit.useUser().update({ link: this.kit.useUI().$link.value })\n    }\n  }\n}\n","import EditorPlugin from './_plug'\nimport type PlugKit from './_kit'\nimport $t from '@/i18n'\n\nexport default class Textarea extends EditorPlugin {\n  constructor(kit: PlugKit) {\n    super(kit)\n\n    const onKeydown = (e: KeyboardEvent) => this.onKeydown(e)\n    const onInput = () => this.onInput()\n\n    this.kit.useMounted(() => {\n      // 占位符\n      this.kit.useUI().$textarea.placeholder = this.kit.useConf().placeholder || $t('placeholder')\n\n      // bind the event\n      this.kit.useUI().$textarea.addEventListener('keydown', onKeydown)\n      this.kit.useUI().$textarea.addEventListener('input', onInput)\n    })\n\n    this.kit.useUnmounted(() => {\n      // unmount the event\n      this.kit.useUI().$textarea.removeEventListener('keydown', onKeydown)\n      this.kit.useUI().$textarea.removeEventListener('input', onInput)\n    })\n\n    this.kit.useEvents().on('content-updated', () => {\n      // delay 80ms to prevent invalid execution\n      window.setTimeout(() => {\n        this.adaptiveHeightByContent()\n      }, 80)\n    })\n  }\n\n  // 按下 Tab 输入内容，而不是失去焦距\n  private onKeydown(e: KeyboardEvent) {\n    const keyCode = e.keyCode || e.which\n\n    if (keyCode === 9) {\n      e.preventDefault()\n      this.kit.useEditor().insertContent('\\t')\n    }\n  }\n\n  private onInput() {\n    this.kit.useEvents().trigger('content-updated', this.kit.useEditor().getContentRaw())\n  }\n\n  // Resize the textarea height by content\n  public adaptiveHeightByContent() {\n    const diff = this.kit.useUI().$textarea.offsetHeight - this.kit.useUI().$textarea.clientHeight\n    this.kit.useUI().$textarea.style.height = '0px' // it's a magic. 若不加此行，内容减少，高度回不去\n    this.kit.useUI().$textarea.style.height = `${this.kit.useUI().$textarea.scrollHeight + diff}px`\n  }\n}\n","import EditorPlugin from './_plug'\nimport type PlugKit from './_kit'\nimport $t from '@/i18n'\n\nexport default class SubmitBtn extends EditorPlugin {\n  constructor(kit: PlugKit) {\n    super(kit)\n\n    const onClick = () => {\n      this.kit.useEditor().submit()\n    }\n\n    this.kit.useMounted(() => {\n      // apply the submit button text from user custom config\n      this.kit.useUI().$submitBtn.innerText = this.kit.useConf().sendBtn || $t('send')\n\n      // bind the event when click the submit button\n      this.kit.useUI().$submitBtn.addEventListener('click', onClick)\n    })\n\n    this.kit.useUnmounted(() => {\n      this.kit.useUI().$submitBtn.removeEventListener('click', onClick)\n    })\n  }\n}\n","import EditorPlugin from './_plug'\nimport type PlugKit from './_kit'\nimport Submit from './submit'\nimport SubmitAddPreset from './submit-add'\nimport type { CommentData } from '@/types'\nimport * as Utils from '@/lib/utils'\nimport $t from '@/i18n'\n\nexport default class StateReply extends EditorPlugin {\n  private comment?: CommentData\n\n  constructor(kit: PlugKit) {\n    super(kit)\n\n    // add effect when state switch to `reply`\n    this.useEditorStateEffect('reply', (commentData) => {\n      this.setReply(commentData)\n\n      return () => {\n        this.cancelReply()\n      }\n    })\n\n    // register submit preset\n    this.kit.useEvents().on('mounted', () => {\n      const submitPlug = this.kit.useDeps(Submit)\n      if (!submitPlug) throw Error('SubmitPlug not initialized')\n\n      const defaultPreset = new SubmitAddPreset(this.kit)\n\n      submitPlug.registerCustom({\n        activeCond: () => !!this.comment, // active this custom submit when reply mode\n        req: async () => {\n          if (!this.comment) throw new Error('reply comment cannot be empty')\n\n          const nComment = (\n            await this.kit.useApi().comments.createComment({\n              ...(await defaultPreset.getSubmitAddParams()),\n              rid: this.comment.id,\n              page_key: this.comment.page_key,\n              page_title: undefined,\n              site_name: this.comment.site_name,\n            })\n          ).data\n\n          return nComment\n        },\n        post: (nComment: CommentData) => {\n          // open another page when reply comment is not the same pageKey\n          const conf = this.kit.useConf()\n          if (nComment.page_key !== conf.pageKey) {\n            window.open(`${nComment.page_url}#atk-comment-${nComment.id}`)\n          }\n\n          defaultPreset.postSubmitAdd(nComment)\n        },\n      })\n    })\n  }\n\n  private setReply(commentData: CommentData) {\n    const ui = this.kit.useUI()\n    if (!ui.$sendReplyBtn) {\n      const $btn = Utils.createElement(\n        `<span class=\"atk-state-btn\">` +\n          `<span class=\"atk-text-wrap\">` +\n          `${$t('reply')} <span class=\"atk-text\"></span>` +\n          `</span>` +\n          `<span class=\"atk-cancel atk-icon-close atk-icon\"></span>` +\n          `</span>`,\n      )\n      $btn.querySelector<HTMLElement>('.atk-text')!.innerText = `@${commentData.nick}`\n      $btn.addEventListener('click', () => {\n        this.kit.useEditor().resetState()\n      })\n      ui.$stateWrap.append($btn)\n      ui.$sendReplyBtn = $btn\n    }\n\n    this.comment = commentData\n\n    ui.$textarea.focus()\n  }\n\n  private cancelReply() {\n    if (!this.comment) return\n\n    const ui = this.kit.useUI()\n    if (ui.$sendReplyBtn) {\n      ui.$sendReplyBtn.remove()\n      ui.$sendReplyBtn = undefined\n    }\n    this.comment = undefined\n  }\n}\n","import type PlugKit from './_kit'\nimport EditorPlugin from './_plug'\nimport Submit from './submit'\nimport type { CommentData } from '@/types'\nimport $t from '@/i18n'\nimport * as Utils from '@/lib/utils'\n\nexport default class StateEdit extends EditorPlugin {\n  private comment?: CommentData\n\n  constructor(kit: PlugKit) {\n    super(kit)\n\n    // add effect when state switch to `edit`\n    this.useEditorStateEffect('edit', (comment) => {\n      this.edit(comment)\n\n      return () => {\n        this.cancelEdit()\n      }\n    })\n\n    // register submit preset\n    this.kit.useMounted(() => {\n      const submitPlug = this.kit.useDeps(Submit)\n      if (!submitPlug) throw Error('SubmitPlug not initialized')\n\n      submitPlug.registerCustom({\n        activeCond: () => !!this.comment, // active this custom submit when edit mode\n        req: async () => {\n          const saveData = {\n            content: this.kit.useEditor().getContentFinal(),\n            nick: this.kit.useUI().$name.value,\n            email: this.kit.useUI().$email.value,\n            link: this.kit.useUI().$link.value,\n          }\n          const comment = this.comment!\n          const nComment = await this.kit.useApi().comments.updateComment(comment.id, {\n            ...comment,\n            ...saveData,\n          })\n          return nComment.data\n        },\n        post: (nComment: CommentData) => {\n          this.kit.useData().updateComment(nComment)\n        },\n      })\n    })\n  }\n\n  private edit(comment: CommentData) {\n    const ui = this.kit.useUI()\n    if (!ui.$editCancelBtn) {\n      const $btn = Utils.createElement(\n        `<span class=\"atk-state-btn\">` +\n          `<span class=\"atk-text-wrap\">` +\n          `${$t('editCancel')}` +\n          `</span>` +\n          `<span class=\"atk-cancel atk-icon-close atk-icon\"></span>` +\n          `</span>`,\n      )\n      $btn.onclick = () => {\n        this.kit.useEditor().resetState()\n      }\n      ui.$stateWrap.append($btn)\n      ui.$editCancelBtn = $btn\n    }\n    this.comment = comment\n\n    ui.$header.style.display = 'none' // TODO: support modify header information\n\n    ui.$name.value = comment.nick || ''\n    ui.$email.value = comment.email || ''\n    ui.$link.value = comment.link || ''\n\n    this.kit.useEditor().setContent(comment.content)\n    ui.$textarea.focus()\n\n    this.updateSubmitBtnText($t('save'))\n  }\n\n  private cancelEdit() {\n    if (!this.comment) return\n\n    const ui = this.kit.useUI()\n\n    if (ui.$editCancelBtn) {\n      ui.$editCancelBtn.remove()\n      ui.$editCancelBtn = undefined\n    }\n\n    this.comment = undefined\n\n    const { name, email, link } = this.kit.useUser().getData()\n    ui.$name.value = name\n    ui.$email.value = email\n    ui.$link.value = link\n\n    this.kit.useEditor().setContent('')\n    this.restoreSubmitBtnText()\n\n    ui.$header.style.display = '' // TODO: support modify header information\n  }\n\n  // -------------------------------------------------------------------\n  //  Submit Btn Text Modifier\n  // -------------------------------------------------------------------\n\n  private originalSubmitBtnText = 'Send'\n\n  private updateSubmitBtnText(text: string) {\n    this.originalSubmitBtnText = this.kit.useUI().$submitBtn.innerText\n    this.kit.useUI().$submitBtn.innerText = text\n  }\n\n  private restoreSubmitBtnText() {\n    this.kit.useUI().$submitBtn.innerText = this.originalSubmitBtnText\n  }\n}\n","import EditorPlugin from './_plug'\nimport type PlugKit from './_kit'\nimport * as Utils from '@/lib/utils'\nimport $t from '@/i18n'\n\nexport default class Closable extends EditorPlugin {\n  constructor(kit: PlugKit) {\n    super(kit)\n\n    const onOpen = () => this.open()\n    const onClose = () => this.close()\n\n    this.kit.useMounted(() => {\n      this.kit.useEvents().on('editor-open', onOpen)\n      this.kit.useEvents().on('editor-close', onClose)\n    })\n    this.kit.useUnmounted(() => {\n      this.kit.useEvents().off('editor-open', onOpen)\n      this.kit.useEvents().off('editor-close', onClose)\n    })\n  }\n\n  private open() {\n    this.kit.useUI().$textareaWrap.querySelector('.atk-comment-closed')?.remove()\n    this.kit.useUI().$textarea.style.display = ''\n    this.kit.useUI().$bottom.style.display = ''\n  }\n\n  private close() {\n    if (!this.kit.useUI().$textareaWrap.querySelector('.atk-comment-closed'))\n      this.kit\n        .useUI()\n        .$textareaWrap.prepend(\n          Utils.createElement(`<div class=\"atk-comment-closed\">${$t('onlyAdminCanReply')}</div>`),\n        )\n\n    if (!this.kit.useUser().getData().is_admin) {\n      this.kit.useUI().$textarea.style.display = 'none'\n      this.kit.useEvents().trigger('panel-close')\n      this.kit.useUI().$bottom.style.display = 'none'\n    } else {\n      // 管理员一直打开评论\n      this.kit.useUI().$textarea.style.display = ''\n      this.kit.useUI().$bottom.style.display = ''\n    }\n  }\n}\n","import type { PluginManager } from '../editor-kit'\nimport type EditorPlugin from './_plug'\n\n/**\n * PlugKit provides a set of methods to help you develop editor plug\n */\nexport default class PlugKit {\n  constructor(private plugins: PluginManager) {}\n\n  /** Use the editor */\n  useEditor() {\n    return this.plugins.getEditor()\n  }\n\n  /** Use the config of Artalk */\n  useConf() {\n    return this.plugins.getOptions().getConf().get()\n  }\n\n  /** Use the http api client */\n  useApi() {\n    return this.plugins.getOptions().getApi()\n  }\n\n  /** Use the data manager */\n  useData() {\n    return this.plugins.getOptions().getData()\n  }\n\n  /** Use the user manager */\n  useUser() {\n    return this.plugins.getOptions().getUser()\n  }\n\n  /** Use the checkers */\n  useCheckers() {\n    return this.plugins.getOptions().getCheckers()\n  }\n\n  /** Use the ui of editor */\n  useUI() {\n    return this.plugins.getEditor().getUI()\n  }\n\n  /** Use the events in editor scope */\n  useEvents() {\n    return this.plugins.getEvents()\n  }\n\n  /** Listen the event when plug is mounted */\n  useMounted(func: () => void) {\n    this.useEvents().on('mounted', func)\n  }\n\n  /** Listen the event when plug is unmounted */\n  useUnmounted(func: () => void) {\n    this.useEvents().on('unmounted', func)\n  }\n\n  /** Use the deps of other plug */\n  useDeps<T extends typeof EditorPlugin>(plug: T) {\n    return this.plugins.get(plug)\n  }\n\n  /** Use the root element of artalk */\n  useArtalkRootEl() {\n    return this.plugins.getOptions().getArtalkRootEl()\n  }\n}\n","import type { EventManager as IEventManager, Event, EventHandler, EventOptions } from '@/types'\n\nexport class EventManager<T> implements IEventManager<T> {\n  private events: Event<T>[] = []\n\n  /**\n   * Add an event listener for a specific event name\n   */\n  public on<K extends keyof T>(name: K, handler: EventHandler<T[K]>, opts: EventOptions = {}) {\n    this.events.push({\n      name,\n      handler: handler as EventHandler<T[keyof T]>,\n      ...opts,\n    })\n  }\n\n  /**\n   * Remove an event listener for a specific event name and handler\n   */\n  public off<K extends keyof T>(name: K, handler: EventHandler<T[K]>) {\n    if (!handler) return // not allow remove all events with same name\n    this.events = this.events.filter((evt) => !(evt.name === name && evt.handler === handler))\n  }\n\n  /**\n   * Trigger an event with an optional payload\n   */\n  public trigger<K extends keyof T>(name: K, payload?: T[K]) {\n    this.events\n      .slice(0) // make a copy, in case listeners are removed while iterating\n      .filter((evt) => evt.name === name && typeof evt.handler === 'function')\n      .forEach((evt) => {\n        if (evt.once) this.off(name, evt.handler)\n        evt.handler(payload!)\n      })\n  }\n}\n","import { getEnabledPlugs } from './editor'\nimport EditorPlugin from './editor/_plug'\nimport PlugKit from './editor/_kit'\nimport { EventManager } from '@/lib/event-manager'\nimport type {\n  Editor,\n  ArtalkPlugin,\n  DataManager,\n  ConfigManager,\n  UserManager,\n  EditorPluginManager as IEditorPluginManager,\n  CheckerManager,\n} from '@/types'\nimport type { Api } from '@/api'\n\nexport interface EditorEventPayloadMap {\n  mounted: undefined\n  unmounted: undefined\n  'header-input': { field: string; $input: HTMLInputElement }\n  'header-change': { field: string; $input: HTMLInputElement }\n  'content-updated': string\n  'panel-show': EditorPlugin\n  'panel-hide': EditorPlugin\n  'panel-close': undefined\n\n  'editor-close': undefined\n  'editor-open': undefined\n  'editor-submit': undefined\n  'editor-submitted': undefined\n}\n\nexport const EditorKit: ArtalkPlugin = (ctx) => {\n  ctx.provide(\n    'editorPlugs',\n    (editor, config, user, data, checkers, api) => {\n      const pluginManager = new PluginManager({\n        getArtalkRootEl: () => ctx.getEl(),\n        getEditor: () => editor,\n        getConf: () => config,\n        getUser: () => user,\n        getApi: () => api,\n        getData: () => data,\n        getCheckers: () => checkers,\n        onSubmitted: () => ctx.trigger('editor-submitted'),\n      })\n      editor.setPlugins(pluginManager)\n      return pluginManager\n    },\n    ['editor', 'config', 'user', 'data', 'checkers', 'api'] as const,\n  )\n}\n\nexport interface PluginManagerOptions {\n  getArtalkRootEl: () => HTMLElement\n  getEditor: () => Editor\n  getConf: () => ConfigManager\n  getUser: () => UserManager\n  getApi: () => Api\n  getData: () => DataManager\n  getCheckers: () => CheckerManager\n  onSubmitted: () => void\n}\n\nexport class PluginManager implements IEditorPluginManager {\n  private plugins: EditorPlugin[] = []\n  private openedPlug: EditorPlugin | null = null\n  private events = new EventManager<EditorEventPayloadMap>()\n\n  constructor(public opts: PluginManagerOptions) {\n    let confLoaded = false // config not loaded at first time\n    this.opts\n      .getConf()\n      .watchConf(['imgUpload', 'emoticons', 'preview', 'editorTravel', 'locale'], (conf) => {\n        // trigger unmount event will call all plugs' unmount function\n        // (this will only be called while conf reloaded, not be called at first time)\n        confLoaded && this.getEvents().trigger('unmounted')\n\n        // reset the plugs\n        this.clear()\n\n        // init the all enabled plugs\n        getEnabledPlugs(conf).forEach((Plug) => {\n          // create the plug instance\n          const kit = new PlugKit(this)\n          this.plugins.push(new Plug(kit))\n        })\n\n        // trigger event for plug initialization\n        this.getEvents().trigger('mounted')\n        confLoaded = true\n\n        // refresh the plug UI\n        this.loadPluginUI()\n      })\n\n    this.events.on('panel-close', () => this.closePluginPanel())\n    this.events.on('editor-submitted', () => opts.onSubmitted())\n  }\n\n  getPlugins() {\n    return this.plugins\n  }\n\n  getEvents() {\n    return this.events\n  }\n\n  getEditor() {\n    return this.opts.getEditor()\n  }\n\n  getOptions() {\n    return this.opts\n  }\n\n  private clear() {\n    this.plugins = []\n    this.events = new EventManager()\n    if (this.openedPlug) this.closePluginPanel()\n  }\n\n  private loadPluginUI() {\n    // handle ui, clear and reset the plug btns and plug panels\n    this.getEditor().getUI().$plugPanelWrap.innerHTML = ''\n    this.getEditor().getUI().$plugPanelWrap.style.display = 'none'\n    this.getEditor().getUI().$plugBtnWrap.innerHTML = ''\n\n    // load the plug UI\n    this.plugins.forEach((plug) => this.loadPluginItem(plug))\n  }\n\n  /** Load the plug btn and plug panel on editor ui */\n  private loadPluginItem(plug: EditorPlugin) {\n    const $btn = plug.$btn\n    if (!$btn) return\n    this.getEditor().getUI().$plugBtnWrap.appendChild($btn)\n\n    // bind the event when click plug btn\n    !$btn.onclick &&\n      ($btn.onclick = () => {\n        // removing the active class from all the buttons\n        this.opts\n          .getEditor()\n          .getUI()\n          .$plugBtnWrap.querySelectorAll('.active')\n          .forEach((item) => item.classList.remove('active'))\n\n        // if the plug is not the same as the openedPlug,\n        if (plug !== this.openedPlug) {\n          // then open the plug current clicked plug panel\n          this.openPluginPanel(plug)\n\n          // add active class for current plug panel\n          $btn.classList.add('active')\n        } else {\n          // then close the plug\n          this.closePluginPanel()\n        }\n      })\n\n    // initialization of plug panel\n    const $panel = plug.$panel\n    if ($panel) {\n      $panel.style.display = 'none'\n      this.getEditor().getUI().$plugPanelWrap.appendChild($panel)\n    }\n  }\n\n  get<T extends typeof EditorPlugin>(plug: T) {\n    return this.plugins.find((p) => p instanceof plug) as InstanceType<T> | undefined\n  }\n\n  /** Open the editor plug panel */\n  openPluginPanel(plug: EditorPlugin) {\n    this.plugins.forEach((aPlug) => {\n      const plugPanel = aPlug.$panel\n      if (!plugPanel) return\n\n      if (aPlug === plug) {\n        plugPanel.style.display = ''\n        this.events.trigger('panel-show', plug)\n      } else {\n        plugPanel.style.display = 'none'\n        this.events.trigger('panel-hide', plug)\n      }\n    })\n\n    this.getEditor().getUI().$plugPanelWrap.style.display = ''\n    this.openedPlug = plug\n  }\n\n  /** Close the editor plugin panel */\n  closePluginPanel() {\n    if (!this.openedPlug) return\n\n    this.getEditor().getUI().$plugPanelWrap.style.display = 'none'\n    this.events.trigger('panel-hide', this.openedPlug)\n    this.openedPlug = null\n  }\n\n  /** Get the content which is transformed by plugs */\n  getTransformedContent(rawContent: string) {\n    let result = rawContent\n    this.plugins.forEach((aPlug) => {\n      if (!aPlug.contentTransformer) return\n      result = aPlug.contentTransformer(result)\n    })\n    return result\n  }\n}\n","import type { ArtalkPlugin } from '@/types'\n\nexport const GotoFocus: ArtalkPlugin = (ctx) => {\n  const list = ctx.inject('list')\n\n  ctx.on('list-goto', async (commentID) => {\n    // find the comment node\n    let comment = ctx.getCommentNodes().find((c) => c.getID() === commentID)\n    if (!comment) {\n      // fetch and insert the comment from the server\n      const data = (await ctx.getApi().comments.getComment(commentID)).data\n      list.getLayout({ forceFlatMode: true }).insert(data.comment, data.reply_comment)\n      comment = ctx.getCommentNodes().find((c) => c.getID() === commentID)\n    }\n    if (!comment) return\n    comment.focus()\n  })\n}\n","import * as Utils from '@/lib/utils'\nimport * as Ui from '@/lib/ui'\nimport $t from '@/i18n'\n\nexport interface ErrorDialogOptions {\n  $err: HTMLElement\n\n  errMsg: string\n  errData?: any\n  retryFn?: () => void\n\n  onOpenSidebar?: () => void\n}\n\nexport function showErrorDialog(opts: ErrorDialogOptions) {\n  const errEl = Utils.createElement(`<span><span class=\"error-message\"></span><br/><br/></span>`)\n  errEl.querySelector<HTMLElement>('.error-message')!.innerText =\n    `${$t('listLoadFailMsg')}\\n${opts.errMsg}`\n\n  if (opts.retryFn) {\n    const $retryBtn = Utils.createElement(`<span style=\"cursor:pointer;\">${$t('listRetry')}</span>`)\n    $retryBtn.onclick = () => opts.retryFn && opts.retryFn()\n    errEl.appendChild($retryBtn)\n  }\n\n  if (opts.onOpenSidebar) {\n    const $openSidebar = Utils.createElement(\n      `<span atk-only-admin-show> | <span style=\"cursor:pointer;\">${$t('openName', { name: $t('ctrlCenter') })}</span></span>`,\n    )\n    errEl.appendChild($openSidebar)\n    $openSidebar.onclick = () => opts.onOpenSidebar && opts.onOpenSidebar()\n  }\n\n  Ui.setError(opts.$err, errEl)\n}\n","import * as Ui from '../../lib/ui'\nimport type { ArtalkPlugin } from '@/types'\nimport { showErrorDialog } from '@/components/error-dialog'\n\nexport const ErrorDialog: ArtalkPlugin = (ctx) => {\n  const list = ctx.inject('list')\n\n  ctx.on('list-fetch', () => {\n    // clear the original error when a new fetch is triggered\n    Ui.setError(list.getEl(), null)\n  })\n\n  ctx.on('list-failed', (err) => {\n    showErrorDialog({\n      $err: list.getEl(),\n      errMsg: err.msg,\n      errData: err.data,\n      retryFn: () => ctx.fetch({ offset: 0 }),\n    })\n  })\n}\n","import { WithEditor } from './with-editor'\nimport { Unread } from './unread'\nimport { Count } from './count'\nimport { SidebarBtn } from './sidebar-btn'\nimport { UnreadBadge } from './unread-badge'\nimport { GotoDispatcher } from './goto-dispatcher'\nimport { GotoFocus } from './goto-focus'\nimport { Copyright } from './copyright'\nimport { NoComment } from './no-comment'\nimport { Dropdown } from './dropdown'\nimport { TimeTicking } from './time-ticking'\nimport { ErrorDialog } from './error-dialog'\nimport { Loading } from './loading'\nimport { Fetch } from './fetch'\nimport { ReachBottom } from './reach-bottom'\nimport { GotoFirst } from './goto-first'\nimport type { ArtalkPlugin } from '@/types'\n\nconst ListPlugins: ArtalkPlugin[] = [\n  Fetch,\n  Loading,\n  Unread,\n  WithEditor,\n  Count,\n  SidebarBtn,\n  UnreadBadge,\n  Dropdown,\n  GotoDispatcher,\n  GotoFocus,\n  NoComment,\n  Copyright,\n  TimeTicking,\n  ErrorDialog,\n  ReachBottom,\n  GotoFirst,\n]\n\nexport { ListPlugins }\n","import type { ListFetchParams, ArtalkPlugin } from '@/types'\n\nexport const Fetch: ArtalkPlugin = (ctx) => {\n  const conf = ctx.inject('config')\n\n  ctx.on('list-fetch', (_params) => {\n    if (ctx.getData().getLoading()) return\n    ctx.getData().setLoading(true)\n\n    const params: ListFetchParams = {\n      // default params\n      offset: 0,\n      limit: conf.get().pagination.pageSize,\n      flatMode: conf.get().flatMode as boolean, // always be boolean because had been handled in Artalk.init\n      paramsModifier: conf.get().listFetchParamsModifier,\n      ..._params,\n    }\n\n    // must before other function call\n    ctx.getData().setListLastFetch({\n      params,\n    })\n\n    // prepare params for request\n    const reqParams = {\n      limit: params.limit,\n      offset: params.offset,\n      flat_mode: params.flatMode,\n      page_key: conf.get().pageKey,\n      site_name: conf.get().site,\n    }\n\n    // call the modifier function\n    if (params.paramsModifier) params.paramsModifier(reqParams)\n\n    // start request\n    ctx\n      .getApi()\n      .comments.getComments({\n        ...reqParams,\n        ...ctx.getApi().getUserFields(),\n      })\n      .then(({ data }) => {\n        // Must before all other function call and event trigger,\n        // because it will depend on the lastData\n        // TODO: this is global variable, easy to use, but not good, consider to refactor.\n        // refactor work is hard, because it is used in many places.\n        ctx.getData().setListLastFetch({ params, data })\n\n        // 装置评论\n        ctx.getData().loadComments(data.comments)\n\n        // 更新页面数据\n        ctx.getData().updatePage(data.page)\n\n        // trigger events when success\n        params.onSuccess && params.onSuccess(data)\n\n        ctx.trigger('list-fetched', { params, data })\n      })\n      .catch((e) => {\n        // 显示错误对话框\n        const error = {\n          msg: e.msg || String(e),\n          data: e.data,\n        }\n\n        params.onError && params.onError(error)\n\n        // trigger events when error\n        ctx.trigger('list-failed', error)\n        ctx.trigger('list-fetched', { params, error })\n\n        throw e\n      })\n      .finally(() => {\n        ctx.getData().setLoading(false)\n      })\n  })\n}\n","import type { ArtalkPlugin } from '@/types'\nimport * as Ui from '@/lib/ui'\n\nexport const Loading: ArtalkPlugin = (ctx) => {\n  const list = ctx.inject('list')\n\n  ctx.on('list-fetch', (p) => {\n    if (p.offset === 0)\n      // only show loading when fetch first page\n      Ui.setLoading(true, list.getEl())\n    // else if not first page, show loading in paginator (code not there)\n  })\n\n  ctx.on('list-fetched', () => {\n    Ui.setLoading(false, list.getEl())\n  })\n}\n","import type { ArtalkPlugin } from '@/types'\nimport * as Utils from '@/lib/utils'\n\nexport const Unread: ArtalkPlugin = (ctx) => {\n  const conf = ctx.inject('config')\n\n  ctx.on('comment-rendered', (comment) => {\n    // comment unread highlight\n    if (conf.get().listUnreadHighlight) {\n      const notifies = ctx.getData().getNotifies()\n      const notify = notifies.find((o) => o.comment_id === comment.getID())\n\n      if (notify) {\n        // if comment contains in unread list\n        comment.getRender().setUnread(true)\n        comment.getRender().setOpenAction(() => {\n          window.open(notify.read_link)\n\n          // remove notify which has been read\n          ctx.getData().updateNotifies(notifies.filter((o) => o.comment_id !== comment.getID()))\n        })\n      } else {\n        // comment not in unread list\n        comment.getRender().setUnread(false)\n      }\n    }\n  })\n\n  ctx.on('list-goto', (commentID) => {\n    const notifyKey = Utils.getQueryParam('atk_notify_key')\n    if (notifyKey) {\n      // mark as read\n      ctx\n        .getApi()\n        .notifies.markNotifyRead(commentID, notifyKey)\n        .then(() => {\n          // remove from unread list\n          ctx.getData().updateNotifies(\n            ctx\n              .getData()\n              .getNotifies()\n              .filter((o) => o.comment_id !== commentID),\n          )\n        })\n    }\n  })\n}\n","import type { Context as IContext, ArtalkPlugin, PageData } from '@/types'\nimport $t from '@/i18n'\n\nexport const WithEditor: ArtalkPlugin = (ctx) => {\n  const list = ctx.inject('list')\n  const editorPlugs = ctx.inject('editorPlugs')\n  let $closeCommentBtn: HTMLElement | undefined\n\n  // on Artalk mounted\n  // (after all components had mounted)\n  ctx.on('mounted', () => {\n    $closeCommentBtn = list\n      .getEl()\n      .querySelector<HTMLElement>('[data-action=\"admin-close-comment\"]')!\n\n    // bind editor close button click event\n    $closeCommentBtn.addEventListener('click', () => {\n      const page = ctx.getData().getPage()\n      if (!page) throw new Error('Page data not found')\n\n      page.admin_only = !page.admin_only\n      adminPageEditSave(ctx, page)\n    })\n  })\n\n  // on comment list loaded (it will include page data update)\n  ctx.on('page-loaded', (page) => {\n    // if page comment is closed\n    if (page?.admin_only === true) {\n      // then close editor\n      editorPlugs?.getEvents().trigger('editor-close')\n      $closeCommentBtn && ($closeCommentBtn.innerText = $t('openComment'))\n    } else {\n      // the open editor\n      editorPlugs?.getEvents().trigger('editor-open')\n      $closeCommentBtn && ($closeCommentBtn.innerText = $t('closeComment'))\n    }\n  })\n\n  ctx.on('list-loaded', (comments) => {\n    // 防止评论框被吞\n    ctx.editorResetState()\n  })\n}\n\n/** 管理员设置页面信息 */\nfunction adminPageEditSave(ctx: IContext, page: PageData) {\n  ctx.editorShowLoading()\n  ctx\n    .getApi()\n    .pages.updatePage(page.id, page)\n    .then(({ data }) => {\n      ctx.getData().updatePage(data)\n    })\n    .catch((err) => {\n      ctx.editorShowNotify(`${$t('editFail')}: ${err.message || String(err)}`, 'e')\n    })\n    .finally(() => {\n      ctx.editorHideLoading()\n    })\n}\n","import type { ArtalkPlugin } from '@/types'\nimport * as Utils from '@/lib/utils'\nimport $t from '@/i18n'\n\nexport const Count: ArtalkPlugin = (ctx) => {\n  const list = ctx.inject('list')\n\n  const refreshCountNumEl = () => {\n    const $count = list.getEl().querySelector('.atk-comment-count .atk-text')\n    if (!$count) return\n\n    const text = Utils.htmlEncode(\n      $t('counter', {\n        count: `${Number(ctx.getData().getListLastFetch()?.data?.count) || 0}`,\n      }),\n    )\n    $count.innerHTML = text.replace(/(\\d+)/, '<span class=\"atk-comment-count-num\">$1</span>')\n  }\n\n  ctx.on('list-loaded', () => {\n    refreshCountNumEl()\n  })\n\n  ctx.on('comment-inserted', () => {\n    // 评论数增加 1\n    const last = ctx.getData().getListLastFetch()\n    if (last?.data) last.data.count += 1\n  })\n\n  ctx.on('comment-deleted', () => {\n    // 评论数减 1\n    const last = ctx.getData().getListLastFetch()\n    if (last?.data) last.data.count -= 1\n  })\n}\n","import type { ArtalkPlugin } from '@/types'\nimport $t from '@/i18n'\n\nexport const SidebarBtn: ArtalkPlugin = (ctx) => {\n  const list = ctx.inject('list')\n  let $openSidebarBtn: HTMLElement | null = null\n\n  const syncByUser = () => {\n    if (!$openSidebarBtn) return\n    const user = ctx.inject('user').getData()\n\n    // 已输入个人信息\n    if (!!user.name && !!user.email) {\n      $openSidebarBtn.classList.remove('atk-hide')\n\n      // update button text (normal user or admin)\n      const $btnText = $openSidebarBtn.querySelector<HTMLElement>('.atk-text')\n      if ($btnText) $btnText.innerText = !user.is_admin ? $t('msgCenter') : $t('ctrlCenter')\n    } else {\n      $openSidebarBtn.classList.add('atk-hide')\n    }\n  }\n\n  ctx.watchConf(['locale'], (conf) => {\n    $openSidebarBtn = list.getEl().querySelector<HTMLElement>('[data-action=\"open-sidebar\"]')\n    if (!$openSidebarBtn) return\n\n    $openSidebarBtn.onclick = () => {\n      // use onclick rather than addEventListener to prevent duplicate event\n      ctx.showSidebar()\n    }\n\n    syncByUser()\n  })\n\n  ctx.on('user-changed', (user) => {\n    syncByUser()\n  })\n}\n","import type { ArtalkPlugin } from '@/types'\n\nexport const UnreadBadge: ArtalkPlugin = (ctx) => {\n  const list = ctx.inject('list')\n  let $unreadBadge: HTMLElement | null = null\n\n  const showUnreadBadge = (count: number) => {\n    if (!$unreadBadge) return\n\n    if (count > 0) {\n      $unreadBadge.innerText = `${Number(count || 0)}`\n      $unreadBadge.style.display = 'block'\n    } else {\n      $unreadBadge.style.display = 'none'\n    }\n  }\n\n  ctx.on('mounted', () => {\n    $unreadBadge = list.getEl().querySelector<HTMLElement>('.atk-unread-badge')\n  })\n\n  ctx.on('notifies-updated', (notifies) => {\n    showUnreadBadge(notifies.length || 0)\n  })\n}\n","import type { ArtalkPlugin } from '@/types'\nimport * as Utils from '@/lib/utils'\nimport $t from '@/i18n'\n\nexport const Dropdown: ArtalkPlugin = (ctx) => {\n  const list = ctx.inject('list')\n  const conf = ctx.inject('config')\n\n  const reloadUseParamsEditor = (func: (p: any) => void) => {\n    conf.update({\n      listFetchParamsModifier: func,\n    })\n    ctx.reload()\n  }\n\n  const initDropdown = ($dropdownOn: HTMLElement) => {\n    renderDropdown({\n      $dropdownWrap: $dropdownOn,\n      dropdownList: [\n        [\n          $t('sortLatest'),\n          () => {\n            reloadUseParamsEditor((p) => {\n              p.sort_by = 'date_desc'\n            })\n          },\n        ],\n        [\n          $t('sortBest'),\n          () => {\n            reloadUseParamsEditor((p) => {\n              p.sort_by = 'vote'\n            })\n          },\n        ],\n        [\n          $t('sortOldest'),\n          () => {\n            reloadUseParamsEditor((p) => {\n              p.sort_by = 'date_asc'\n            })\n          },\n        ],\n        [\n          $t('sortAuthor'),\n          () => {\n            reloadUseParamsEditor((p) => {\n              p.view_only_admin = true\n            })\n          },\n        ],\n      ],\n    })\n  }\n\n  ctx.watchConf(['listSort', 'locale'], (conf) => {\n    const $count = list.getEl().querySelector<HTMLElement>('.atk-comment-count')\n    if (!$count) return\n\n    // 评论列表排序 Dropdown 下拉选择层\n    if (conf.listSort) {\n      initDropdown($count)\n    } else {\n      removeDropdown({\n        $dropdownWrap: $count,\n      })\n    }\n  })\n}\n\n/** 评论排序方式选择下拉菜单 */\nfunction renderDropdown(conf: {\n  $dropdownWrap: HTMLElement\n  dropdownList: [string, () => void][]\n}) {\n  const { $dropdownWrap, dropdownList } = conf\n  if ($dropdownWrap.querySelector('.atk-dropdown')) return\n\n  // 修改 class\n  $dropdownWrap.classList.add('atk-dropdown-wrap')\n\n  // 插入图标\n  $dropdownWrap.append(Utils.createElement(`<span class=\"atk-arrow-down-icon\"></span>`))\n\n  // 列表项点击事件\n  let curtActive = 0 // 当前选中\n  const onItemClick = (i: number, $item: HTMLElement, name: string, action: () => void) => {\n    action()\n\n    // set active\n    curtActive = i\n    $dropdown.querySelectorAll('.active').forEach((e) => {\n      e.classList.remove('active')\n    })\n    $item.classList.add('active')\n\n    // 关闭层 (临时消失，取消 :hover)\n    $dropdown.style.display = 'none'\n    setTimeout(() => {\n      $dropdown.style.display = ''\n    }, 80)\n  }\n\n  // 生成列表元素\n  const $dropdown = Utils.createElement(`<ul class=\"atk-dropdown atk-fade-in\"></ul>`)\n  dropdownList.forEach((item, i) => {\n    const [name, action] = item\n\n    const $item = Utils.createElement(`<li class=\"atk-dropdown-item\"><span></span></li>`)\n    const $link = $item.querySelector<HTMLElement>('span')!\n    $link.innerText = name\n    $link.onclick = () => {\n      onItemClick(i, $item, name, action)\n    }\n    $dropdown.append($item)\n\n    if (i === curtActive) $item.classList.add('active') // 默认选中项\n  })\n\n  $dropdownWrap.append($dropdown)\n}\n\n/** 删除评论排序方式选择下拉菜单 */\nfunction removeDropdown(conf: { $dropdownWrap: HTMLElement }) {\n  const { $dropdownWrap } = conf\n  $dropdownWrap.classList.remove('atk-dropdown-wrap')\n  $dropdownWrap.querySelector('.atk-arrow-down-icon')?.remove()\n  $dropdownWrap.querySelector('.atk-dropdown')?.remove()\n}\n","import type { ArtalkPlugin } from '@/types'\nimport * as Utils from '@/lib/utils'\n\nexport const GotoDispatcher: ArtalkPlugin = (ctx) => {\n  let lastID = 0\n  const check = ({ locker }: { locker: boolean }) => {\n    const commentID = extractCommentID()\n    if (!commentID) return\n\n    if (locker && lastID === commentID) return // if the commentID is the same as the last one, do nothing\n    lastID = commentID // record the last commentID\n\n    ctx.trigger('list-goto', commentID) // trigger event\n  }\n\n  const hashChangeHandler = () => check({ locker: false })\n  const listLoadedHandler = () => check({ locker: true })\n  ctx.on('mounted', () => {\n    window.addEventListener('hashchange', hashChangeHandler)\n    ctx.on('list-loaded', listLoadedHandler)\n  })\n  ctx.on('unmounted', () => {\n    window.removeEventListener('hashchange', hashChangeHandler)\n    ctx.off('list-loaded', listLoadedHandler)\n  })\n}\n\nfunction extractCommentID(): number | null {\n  // Try get from hash\n  // Hash retrieval priority is higher than query,\n  // Because click goto will change hash.\n  const match = window.location.hash.match(/#atk-comment-([0-9]+)/)\n  let commentId =\n    match && match[1] && !Number.isNaN(parseFloat(match[1])) ? parseFloat(match[1]) : null\n\n  // Fail over to get from query\n  if (!commentId) {\n    commentId = Number(Utils.getQueryParam('atk_comment')) // same as backend GetReplyLink()\n  }\n\n  return commentId || null\n}\n","import type { ArtalkPlugin } from '@/types'\nimport * as Utils from '@/lib/utils'\nimport { sanitize } from '@/lib/sanitizer'\n\nexport const NoComment: ArtalkPlugin = (ctx) => {\n  const list = ctx.inject('list')\n  const conf = ctx.inject('config')\n\n  ctx.on('list-loaded', (comments) => {\n    // 无评论\n    const isNoComment = comments.length <= 0\n    let $noComment = list.getCommentsWrapEl().querySelector<HTMLElement>('.atk-list-no-comment')\n\n    if (isNoComment) {\n      if (!$noComment) {\n        $noComment = Utils.createElement('<div class=\"atk-list-no-comment\"></div>')\n\n        // sanitize before set innerHTML\n        $noComment.innerHTML = sanitize(conf.get().noComment || ctx.$t('noComment'))\n        list.getCommentsWrapEl().appendChild($noComment)\n      }\n    } else {\n      $noComment?.remove()\n    }\n  })\n}\n","import type { ArtalkPlugin } from '@/types'\nimport { version as ARTALK_VERSION } from '~/package.json'\n\nexport const Copyright: ArtalkPlugin = (ctx) => {\n  const list = ctx.inject('list')\n\n  ctx.on('mounted', () => {\n    const $copyright = list.getEl().querySelector<HTMLElement>('.atk-copyright')\n    if (!$copyright) return\n\n    $copyright.innerHTML =\n      `Powered By <a href=\"https://artalk.js.org\" ` +\n      `target=\"_blank\" title=\"Artalk v${ARTALK_VERSION}\">` +\n      `Artalk</a>`\n  })\n}\n","import type { ArtalkPlugin } from '@/types'\nimport * as Utils from '@/lib/utils'\n\n/** 评论时间自动更新 */\nexport const TimeTicking: ArtalkPlugin = (ctx) => {\n  const list = ctx.inject('list')\n  const conf = ctx.inject('config')\n  let timer: number | null = null\n\n  ctx.on('mounted', () => {\n    timer = window.setInterval(() => {\n      list\n        .getEl()\n        .querySelectorAll<HTMLElement>('[data-atk-comment-date]')\n        .forEach((el) => {\n          const date = new Date(Number(el.getAttribute('data-atk-comment-date')))\n          el.innerText = conf.get().dateFormatter?.(date) || Utils.timeAgo(date, ctx.$t)\n        })\n    }, 30 * 1000) // 30s 更新一次\n  })\n\n  ctx.on('unmounted', () => {\n    timer && window.clearInterval(timer)\n  })\n}\n","import type { ArtalkPlugin } from '@/types'\n\nexport const ReachBottom: ArtalkPlugin = (ctx) => {\n  const list = ctx.inject('list')\n  const conf = ctx.inject('config')\n  let observer: IntersectionObserver | null = null\n\n  const setupObserver = ($target: HTMLElement) => {\n    const scrollEvtAt = conf.get().scrollRelativeTo?.() || null\n\n    observer = new IntersectionObserver(\n      ([entries]) => {\n        if (entries.isIntersecting) {\n          clearObserver() // clear before trigger event to avoid trigger twice `list-reach-bottom`\n\n          // note that this event will be triggered only once\n          // until the next list is loaded\n          ctx.trigger('list-reach-bottom')\n        }\n      },\n      {\n        threshold: 0.9, // when the target is 90% visible\n\n        // @see https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver/root\n        // If the root is null, then the bounds of the actual document viewport are used.\n        root: scrollEvtAt,\n      },\n    )\n    observer.observe($target)\n  }\n\n  const clearObserver = () => {\n    observer?.disconnect()\n    observer = null\n  }\n\n  ctx.on('list-loaded', () => {\n    clearObserver()\n\n    // get the second last child\n    const children = list.getCommentsWrapEl().childNodes\n    const $target = children.length > 2 ? (children[children.length - 2] as HTMLElement) : null\n    if (!$target) return\n\n    // check IntersectionObserver support\n    if (!('IntersectionObserver' in window)) {\n      console.warn('IntersectionObserver api not supported')\n      return\n    }\n\n    // use IntersectionObserver to detect reach bottom\n    setupObserver($target)\n  })\n\n  ctx.on('unmounted', () => {\n    clearObserver()\n  })\n}\n","import type { ArtalkPlugin } from '@/types'\nimport * as Utils from '@/lib/utils'\n\n/** List scroll to the first comment */\nexport const GotoFirst: ArtalkPlugin = (ctx) => {\n  const list = ctx.inject('list')\n  const conf = ctx.inject('config')\n\n  const handler = () => {\n    const $relative = conf.get().scrollRelativeTo?.()\n    ;($relative || window).scroll({\n      top: Utils.getOffset(list.getEl(), $relative).top,\n      left: 0,\n    })\n  }\n\n  ctx.on('mounted', () => {\n    ctx.on('list-goto-first', handler)\n  })\n\n  ctx.on('unmounted', () => {\n    ctx.off('list-goto-first', handler)\n  })\n}\n","import type { ArtalkPlugin, List } from '@/types'\nimport { version as ARTALK_VERSION } from '~/package.json'\nimport * as Utils from '@/lib/utils'\nimport $t from '@/i18n'\n\nlet IgnoreVersionCheck = false\n\nexport const VersionCheck: ArtalkPlugin = (ctx) => {\n  const list = ctx.inject('list')\n  ctx.watchConf(['apiVersion', 'versionCheck'], (conf) => {\n    if (conf.apiVersion && conf.versionCheck && !IgnoreVersionCheck)\n      versionCheck(list, ARTALK_VERSION, conf.apiVersion)\n  })\n}\n\nfunction versionCheck(list: List, feVer: string, beVer: string) {\n  const comp = Utils.versionCompare(feVer, beVer)\n  const sameVer = comp === 0\n  if (sameVer) return\n\n  const errEl = Utils.createElement(\n    `<div class=\"atk-version-check-notice\">${$t('updateMsg', {\n      name: comp < 0 ? $t('client') : $t('server'),\n    })} <span class=\"atk-info\">` +\n      `${$t('currentVersion')}: ${$t('client')} ${feVer} / ${$t('server')} ${beVer}` +\n      `</span></div>`,\n  )\n  const ignoreBtn = Utils.createElement(`<span class=\"atk-ignore-btn\">${$t('ignore')}</span>`)\n  ignoreBtn.onclick = () => {\n    errEl.remove()\n    IgnoreVersionCheck = true\n  }\n  errEl.append(ignoreBtn)\n  list.getEl().parentElement!.prepend(errEl)\n}\n","import type { ArtalkPlugin } from '@/types'\n\n// Notice: Singleton pattern needs to be loaded as lazy as possible,\n//         because the SSG application does not have a `window` context.\nlet darkModeMedia: MediaQueryList | undefined\n\nfunction updateClassnames($els: HTMLElement[], darkMode: boolean) {\n  const DarkModeClassName = 'atk-dark-mode'\n\n  $els.forEach(($el) => {\n    if (darkMode) $el.classList.add(DarkModeClassName)\n    else $el.classList.remove(DarkModeClassName)\n  })\n}\n\nexport const DarkMode: ArtalkPlugin = (ctx) => {\n  const conf = ctx.inject('config')\n  const layers = ctx.inject('layers')\n\n  // the handler bind to Artalk instance, don't forget to remove it when Artalk instance destroyed\n  let darkModeAutoHandler: ((evt: MediaQueryListEvent) => void) | undefined\n\n  const sync = (darkMode: boolean | 'auto') => {\n    // the elements that classnames need to be updated when darkMode changed\n    const $els = [ctx.getEl(), layers.getEl()]\n\n    // init darkModeMedia if not exists, and only create once\n    if (!darkModeMedia) {\n      darkModeMedia = window.matchMedia('(prefers-color-scheme: dark)')\n    }\n\n    if (darkMode === 'auto') {\n      // if darkMode is 'auto', add handler\n      if (!darkModeAutoHandler) {\n        // the handler that will be called when darkModeMedia changed\n        darkModeAutoHandler = (evt) => updateClassnames($els, evt.matches)\n        darkModeMedia.addEventListener('change', darkModeAutoHandler)\n      }\n\n      // update classnames immediately\n      updateClassnames($els, darkModeMedia.matches)\n    } else {\n      // if darkMode is boolean, remove handler\n      if (darkModeAutoHandler) {\n        darkModeMedia.removeEventListener('change', darkModeAutoHandler)\n        darkModeAutoHandler = undefined\n      }\n\n      // update classnames immediately\n      updateClassnames($els, darkMode)\n    }\n  }\n\n  ctx.watchConf(['darkMode'], (conf) => sync(conf.darkMode))\n  ctx.on('created', () => sync(conf.get().darkMode))\n  ctx.on('unmounted', () => {\n    // if handler exists, don't forget to remove it, or it will cause memory leak\n    darkModeAutoHandler && darkModeMedia?.removeEventListener('change', darkModeAutoHandler)\n    darkModeAutoHandler = undefined\n  })\n}\n","import type { ArtalkPlugin, ListFetchedArgs } from '@/types'\nimport type { Api } from '@/api'\nimport $t from '@/i18n'\n\ninterface PageVoteOptions {\n  /** Up Vote Button Selector */\n  upBtnEl: string\n\n  /** Down Vote Button Selector */\n  downBtnEl: string\n\n  /** Up Vote Count Selector */\n  upCountEl: string\n\n  /** Down Vote Count Selector */\n  downCountEl: string\n\n  /** Active class name if the vote is already cast */\n  activeClass?: string\n}\n\nconst defaults: PageVoteOptions = {\n  upBtnEl: '.artalk-page-vote-up',\n  downBtnEl: '.artalk-page-vote-down',\n  upCountEl: '.artalk-page-vote-up-count',\n  downCountEl: '.artalk-page-vote-down-count',\n  activeClass: 'active',\n}\n\ntype VoteBtnHandler = (evt: MouseEvent) => void\n\ninterface PageVoteState {\n  upBtnEl?: HTMLElement | null\n  downBtnEl?: HTMLElement | null\n  upCountEl?: HTMLElement | null\n  downCountEl?: HTMLElement | null\n  voteUpHandler?: VoteBtnHandler\n  voteDownHandler?: VoteBtnHandler\n  activeClass?: string\n}\n\nexport const PageVoteWidget: ArtalkPlugin = (ctx) => {\n  const conf = ctx.inject('config')\n  let state: PageVoteState = initState()\n  let cleanup: (() => void) | undefined\n\n  ctx.watchConf(['pageVote'], (conf) => {\n    const options = { ...defaults, ...(typeof conf.pageVote === 'object' ? conf.pageVote : {}) }\n\n    cleanup?.()\n    if (conf.pageVote) {\n      state = loadOptions(state, options, voteUpHandler, voteDownHandler)\n      cleanup = () => (state = resetState(state))\n    }\n  })\n\n  ctx.on('unmounted', () => {\n    cleanup?.()\n    ctx.off('list-fetched', listFetchedHandler)\n  })\n\n  ctx.on('list-fetched', listFetchedHandler)\n\n  // List fetched handler\n  let currPageId = 0\n  function listFetchedHandler({ data }: ListFetchedArgs) {\n    if (!conf.get().pageVote || !checkEls(state) || !data) return\n\n    if (currPageId !== data.page.id) {\n      // Initialize vote status in a new page\n      currPageId = data.page.id\n      updateVoteStatus(state, data.page.vote_up, data.page.vote_down, false, false) // reset initial status\n      fetchVoteStatus(state, currPageId, ctx.getApi())\n    } else {\n      // Update vote status in the same page\n      updateVoteStatus(state, data.page.vote_up, data.page.vote_down)\n    }\n  }\n\n  // Vote button click handlers\n  const handlerOptions = () => ({\n    state,\n    pageId: ctx.getData().getPage()?.id || 0,\n    httpApi: ctx.getApi(),\n  })\n  const voteUpHandler = voteBtnHandler('up', handlerOptions)\n  const voteDownHandler = voteBtnHandler('down', handlerOptions)\n}\n\nfunction loadOptions(\n  _state: PageVoteState,\n  opts: PageVoteOptions,\n  voteUpHandler: VoteBtnHandler,\n  voteDownHandler: VoteBtnHandler,\n): PageVoteState {\n  const state: PageVoteState = { ..._state } // clone to keep immutable\n  state.upBtnEl = document.querySelector<HTMLElement>(opts.upBtnEl)\n  state.downBtnEl = document.querySelector<HTMLElement>(opts.downBtnEl)\n  state.upCountEl = document.querySelector<HTMLElement>(opts.upCountEl)\n  state.downCountEl = document.querySelector<HTMLElement>(opts.downCountEl)\n  state.activeClass = opts.activeClass\n  state.voteUpHandler = voteUpHandler\n  state.voteDownHandler = voteDownHandler\n  state.upBtnEl?.addEventListener('click', voteUpHandler)\n  state.downBtnEl?.addEventListener('click', voteDownHandler)\n  return state\n}\n\nfunction checkEls(state: PageVoteState) {\n  return state.upBtnEl || state.downBtnEl || state.upCountEl || state.downCountEl\n}\n\nfunction initState(): PageVoteState {\n  return {}\n}\n\nfunction resetState(state: PageVoteState): PageVoteState {\n  state.voteUpHandler && state.upBtnEl?.removeEventListener('click', state.voteUpHandler)\n  state.voteDownHandler && state.downBtnEl?.removeEventListener('click', state.voteDownHandler)\n  return initState()\n}\n\nfunction updateVoteStatus(\n  state: PageVoteState,\n  up: number | string,\n  down: number | string,\n  isUp?: boolean,\n  isDown?: boolean,\n) {\n  // Up vote count\n  if (state.upCountEl) {\n    state.upCountEl.innerText = String(up)\n  } else if (state.upBtnEl) {\n    state.upBtnEl.innerText = `${$t('voteUp')} (${up})`\n  }\n\n  // Down vote count\n  if (state.downCountEl) {\n    state.downCountEl.innerText = String(down)\n  } else if (state.downBtnEl) {\n    state.downBtnEl.innerText = `${$t('voteDown')} (${down})`\n  }\n\n  if (typeof isUp === 'boolean')\n    state.upBtnEl?.classList.toggle(state.activeClass || 'active', isUp)\n  if (typeof isDown === 'boolean')\n    state.downBtnEl?.classList.toggle(state.activeClass || 'active', isDown)\n}\n\ninterface VoteBtnHandlerOptions {\n  state: PageVoteState\n  pageId: number\n  httpApi: Api\n}\n\nconst voteBtnHandler =\n  (choice: 'up' | 'down', options: () => VoteBtnHandlerOptions) => (evt: MouseEvent) => {\n    evt.preventDefault()\n    const { state, pageId, httpApi } = options()\n    if (!pageId) return\n    httpApi.votes\n      .createVote('page', pageId, choice, {\n        ...httpApi.getUserFields(),\n      })\n      .then(({ data }) => {\n        updateVoteStatus(state, data.up, data.down, data.is_up, data.is_down)\n      })\n      .catch((err) => {\n        window.alert($t('voteFail'))\n        console.error('[ArtalkPageVote]', err)\n      })\n  }\n\nfunction fetchVoteStatus(state: PageVoteState, pageId: number, httpApi: Api) {\n  httpApi.votes\n    .getVote('page', pageId)\n    .then(({ data }) => {\n      updateVoteStatus(state, data.up, data.down, data.is_up, data.is_down)\n    })\n    .catch((err) => {\n      console.error('[ArtalkPageVote]', err)\n    })\n}\n","import type { ArtalkPlugin } from '@/types'\nimport { Api, createApiHandlers } from '@/api'\nimport { convertApiOptions } from '@/config'\n\nexport const ApiService: ArtalkPlugin = (ctx) => {\n  ctx.provide('apiHandlers', () => createApiHandlers(), [] as const)\n  ctx.provide(\n    'api',\n    (user, config, apiHandlers) => new Api(convertApiOptions(config.get(), user, apiHandlers)),\n    ['user', 'config', 'apiHandlers'] as const,\n    {\n      lifecycle: 'transient',\n    },\n  )\n}\n","import type { LocalUser, UserManager as IUserManager } from '@/types'\n\nconst LOCAL_USER_KEY = 'ArtalkUser'\n\ninterface UserOpts {\n  onUserChanged?: (user: LocalUser) => void\n}\n\nexport class UserManager implements IUserManager {\n  private data: LocalUser\n\n  constructor(private opts: UserOpts) {\n    // Import from localStorage\n    const localUser = JSON.parse(window.localStorage.getItem(LOCAL_USER_KEY) || '{}')\n\n    // Initialize\n    this.data = {\n      name: localUser.name || localUser.nick || '', // nick is deprecated (for historical compatibility)\n      email: localUser.email || '',\n      link: localUser.link || '',\n      token: localUser.token || '',\n      is_admin: localUser.is_admin || localUser.isAdmin || false,\n    }\n  }\n\n  getData() {\n    return this.data\n  }\n\n  /** Update user data and save to localStorage */\n  update(obj: Partial<LocalUser> = {}) {\n    Object.entries(obj).forEach(([key, value]) => {\n      this.data[key] = value\n    })\n\n    window.localStorage.setItem(LOCAL_USER_KEY, JSON.stringify(this.data))\n    this.opts.onUserChanged && this.opts.onUserChanged(this.data)\n  }\n\n  /**\n   * Logout\n   *\n   * @description Logout will clear login status, but not clear user data (name, email, link)\n   */\n  logout() {\n    this.update({\n      token: '',\n      is_admin: false,\n    })\n  }\n\n  /** Check if user has filled basic data */\n  checkHasBasicUserInfo() {\n    return !!this.data.name && !!this.data.email\n  }\n}\n\nexport default UserManager\n","import type { CheckerCtx } from '.'\nimport $t from '@/i18n'\nimport * as Utils from '@/lib/utils'\nimport * as Ui from '@/lib/ui'\n\n/** 图片验证码 */\nexport function imgBody(checker: CheckerCtx) {\n  // 图片验证方式\n  const elem = Utils.createElement(\n    `<span><img class=\"atk-captcha-img\" src=\"${checker.get('img_data') || ''}\">${$t('captchaCheck')}</span>`,\n  )\n\n  // 刷新验证码\n  elem.querySelector<HTMLElement>('.atk-captcha-img')!.onclick = () => {\n    const imgEl = elem.querySelector('.atk-captcha-img')\n    checker\n      .getApi()\n      .captcha.getCaptcha()\n      .then((res) => {\n        imgEl!.setAttribute('src', res.data.img_data)\n      })\n      .catch((err) => {\n        console.error('Failed to get captcha image ', err)\n      })\n  }\n  return elem\n}\n\n/** iframe 形式的通用验证服务 */\nexport function iframeBody(checker: CheckerCtx) {\n  const $iframeWrap = Utils.createElement(`<div class=\"atk-checker-iframe-wrap\"></div>`)\n  const $iframe = Utils.createElement<HTMLIFrameElement>(\n    `<iframe class=\"atk-fade-in\" referrerpolicy=\"strict-origin-when-cross-origin\"></iframe>`,\n  )\n  $iframe.style.display = 'none'\n  Ui.showLoading($iframeWrap, { transparentBg: true })\n  $iframe.src = checker.getOpts().getCaptchaIframeURL()\n  $iframe.onload = () => {\n    $iframe.style.display = ''\n    Ui.hideLoading($iframeWrap)\n  }\n  $iframeWrap.append($iframe)\n\n  const $closeBtn = Utils.createElement(\n    `<div class=\"atk-close-btn\"><i class=\"atk-icon atk-icon-close\"></i></div>`,\n  )\n  $iframeWrap.append($closeBtn)\n\n  checker.hideInteractInput()\n\n  // 轮询状态\n  let stop = false // 打断\n  const sleep = (ms: number) =>\n    new Promise((resolve) => {\n      window.setTimeout(() => {\n        resolve(null)\n      }, ms)\n    })\n  ;(async function queryStatus() {\n    await sleep(1000)\n    if (stop) return\n    let isPass = false\n    try {\n      const resp = await checker.getApi().captcha.getCaptchaStatus()\n      isPass = resp.data.is_pass\n    } catch {\n      isPass = false\n    }\n    if (isPass) {\n      checker.triggerSuccess()\n    } else {\n      queryStatus()\n    }\n  })()\n\n  $closeBtn.onclick = () => {\n    stop = true\n    checker.cancel()\n  }\n\n  return $iframeWrap\n}\n","import * as render from './captcha-renders'\nimport type { Checker } from '.'\n\nconst CaptchaChecker: Checker = {\n  request(checker, inputVal) {\n    return checker.getApi().captcha.verifyCaptcha({\n      value: inputVal,\n    })\n  },\n\n  body(checker) {\n    if (checker.get('iframe')) return render.iframeBody(checker)\n    return render.imgBody(checker)\n  },\n\n  onSuccess(checker, data, inputVal, formEl) {\n    checker.set('val', inputVal)\n  },\n\n  onError(checker, err, inputVal, formEl) {\n    formEl.querySelector<HTMLElement>('.atk-captcha-img')!.click() // 刷新验证码\n    formEl.querySelector<HTMLInputElement>('input[type=\"text\"]')!.value = '' // 清空输入框输入\n  },\n}\n\nexport default CaptchaChecker\n","import type { Checker } from '.'\nimport $t from '@/i18n'\nimport * as Utils from '@/lib/utils'\n\nconst AdminChecker: Checker<{ token: string }> = {\n  inputType: 'password',\n\n  async request(checker, inputVal) {\n    return (\n      await checker.getApi().user.login({\n        name: checker.getUser().getData().name,\n        email: checker.getUser().getData().email,\n        password: inputVal,\n      })\n    ).data\n  },\n\n  body(checker) {\n    return Utils.createElement(`<span>${$t('adminCheck')}</span>`)\n  },\n\n  onSuccess(checker, res, inputVal, formEl) {\n    checker.getUser().update({\n      is_admin: true,\n      token: res.token,\n    })\n    checker.getOpts().onReload()\n  },\n\n  onError(checker, err, inputVal, formEl) {},\n}\n\nexport default AdminChecker\n","import * as Utils from '../lib/utils'\nimport $t from '@/i18n'\n\ntype BtnClickHandler = (btnEl: HTMLElement, dialog: Dialog) => boolean | void\n\n/**\n * 对话框\n */\nexport default class Dialog {\n  public $el: HTMLElement\n  public $content: HTMLElement\n  public $actions: HTMLElement\n\n  constructor(contentEl: HTMLElement) {\n    this.$el = Utils.createElement(\n      `<div class=\"atk-layer-dialog-wrap\">\n        <div class=\"atk-layer-dialog\">\n          <div class=\"atk-layer-dialog-content\"></div>\n          <div class=\"atk-layer-dialog-actions\"></div>\n        </div>\n      </div>`,\n    )\n\n    // 按钮\n    this.$actions = this.$el.querySelector<HTMLElement>('.atk-layer-dialog-actions')!\n\n    // 内容\n    this.$content = this.$el.querySelector('.atk-layer-dialog-content')!\n    this.$content.appendChild(contentEl)\n  }\n\n  /** 按钮 · 确定 */\n  public setYes(handler: BtnClickHandler) {\n    const btn = Utils.createElement<HTMLButtonElement>(\n      `<button data-action=\"confirm\">${$t('confirm')}</button>`,\n    )\n    btn.onclick = this.onBtnClick(handler)\n    this.$actions.appendChild(btn)\n\n    return this\n  }\n\n  /** 按钮 · 取消 */\n  public setNo(handler: BtnClickHandler) {\n    const btn = Utils.createElement<HTMLButtonElement>(\n      `<button data-action=\"cancel\">${$t('cancel')}</button>`,\n    )\n    btn.onclick = this.onBtnClick(handler)\n    this.$actions.appendChild(btn)\n\n    return this\n  }\n\n  private onBtnClick(handler: BtnClickHandler) {\n    return (evt: Event) => {\n      const re = handler(evt.currentTarget as HTMLElement, this)\n      if (re === undefined || re === true) {\n        this.$el.remove()\n      }\n    }\n  }\n}\n","import CaptchaChecker from './captcha'\nimport AdminChecker from './admin'\nimport type { Api } from '@/api'\nimport Dialog from '@/components/dialog'\nimport $t from '@/i18n'\nimport * as Utils from '@/lib/utils'\nimport type { UserManager, CheckerManager as ICheckerManager, LayerManager } from '@/types'\n\nexport interface CheckerCaptchaPayload extends CheckerPayload {\n  img_data?: string\n  iframe?: string\n}\n\nexport interface CheckerPayload {\n  onSuccess?: () => void\n  onMount?: (dialogEl: HTMLElement) => void\n  onCancel?: () => void\n}\n\nexport interface CheckerLauncherOptions {\n  getApi: () => Api\n  getLayers: () => LayerManager\n  getUser: () => UserManager\n  getCaptchaIframeURL: () => string\n  onReload: () => void\n}\n\nfunction wrapPromise<P extends CheckerPayload = CheckerPayload>(fn: (p: P) => void) {\n  return (payload: P) =>\n    new Promise<void>((resolve, reject) => {\n      const cancelFn = payload.onCancel\n      payload.onCancel = () => {\n        cancelFn && cancelFn()\n        reject(new Error('user canceled the checker'))\n      }\n      const successFn = payload.onSuccess\n      payload.onSuccess = () => {\n        successFn && successFn()\n        resolve()\n      }\n      fn(payload)\n    })\n}\n\n/**\n * Checker Launcher\n */\nexport class CheckerLauncher implements ICheckerManager {\n  constructor(private opts: CheckerLauncherOptions) {}\n\n  public checkCaptcha: (payload: CheckerCaptchaPayload) => Promise<void> = wrapPromise((p) => {\n    this.check(CaptchaChecker, p, (ctx) => {\n      ctx.set('img_data', p.img_data)\n      ctx.set('iframe', p.iframe)\n    })\n  })\n\n  public checkAdmin: (payload: CheckerPayload) => Promise<void> = wrapPromise((p) => {\n    this.check(AdminChecker, p)\n  })\n\n  public check(checker: Checker, payload: CheckerPayload, beforeCheck?: (c: CheckerCtx) => void) {\n    // 显示层\n    const layer = this.opts.getLayers().create(`checker-${new Date().getTime()}`)\n    layer.show()\n\n    const close = () => {\n      layer.destroy()\n    }\n\n    // 构建 Checker 的上下文\n    const checkerStore: CheckerStore = {}\n    let hideInteractInput = false\n    const checkerCtx: CheckerCtx = {\n      set: (key, val) => {\n        checkerStore[key] = val\n      },\n      get: (key) => checkerStore[key],\n      getOpts: () => this.opts,\n      getUser: () => this.opts.getUser(),\n      getApi: () => this.opts.getApi(),\n      hideInteractInput: () => {\n        hideInteractInput = true\n      },\n      triggerSuccess: () => {\n        close()\n        if (checker.onSuccess) checker.onSuccess(checkerCtx, '', '', formEl)\n        if (payload.onSuccess) payload.onSuccess()\n      },\n      cancel: () => {\n        close()\n        if (payload.onCancel) payload.onCancel()\n      },\n    }\n\n    if (beforeCheck) beforeCheck(checkerCtx)\n\n    // 创建表单\n    const formEl = Utils.createElement()\n    formEl.appendChild(checker.body(checkerCtx))\n\n    // 输入框\n    const $input = Utils.createElement<HTMLInputElement>(\n      `<input id=\"check\" type=\"${checker.inputType || 'text'}\" autocomplete=\"off\" required placeholder=\"\">`,\n    )\n    formEl.appendChild($input)\n    setTimeout(() => $input.focus(), 80) // 延迟 Focus\n\n    // 绑定键盘事件\n    $input.onkeyup = (evt) => {\n      if (evt.key === 'Enter' || evt.keyCode === 13) {\n        // 按下回车键\n        evt.preventDefault()\n        layer.getEl().querySelector<HTMLButtonElement>('button[data-action=\"confirm\"]')!.click()\n      }\n    }\n\n    let btnTextOrg: string | undefined\n    const dialog = new Dialog(formEl)\n\n    // 确认按钮\n    dialog.setYes((btnEl) => {\n      const inputVal = $input.value.trim()\n\n      // 按钮操作\n      if (!btnTextOrg) btnTextOrg = btnEl.innerText\n      const btnTextSet = (btnText: string) => {\n        btnEl.innerText = btnText\n        btnEl.classList.add('error')\n      }\n      const btnTextRestore = () => {\n        btnEl.innerText = btnTextOrg || ''\n        btnEl.classList.remove('error')\n      }\n\n      btnEl.innerText = `${$t('loading')}...`\n\n      // 发送请求\n      checker\n        .request(checkerCtx, inputVal)\n        .then((data) => {\n          // 请求成功\n          close()\n\n          if (checker.onSuccess) checker.onSuccess(checkerCtx, data, inputVal, formEl)\n          if (payload.onSuccess) payload.onSuccess()\n        })\n        .catch((err) => {\n          // 请求失败\n          btnTextSet(String(err.message || String(err)))\n\n          if (checker.onError) checker.onError(checkerCtx, err, inputVal, formEl)\n\n          // 错误显示 3s 后恢复按钮\n          const tf = setTimeout(() => btnTextRestore(), 3000)\n          $input.onfocus = () => {\n            btnTextRestore()\n            clearTimeout(tf)\n          }\n        })\n\n      return false\n    })\n\n    // 取消按钮\n    dialog.setNo(() => {\n      close()\n      if (payload.onCancel) payload.onCancel()\n      return false\n    })\n\n    if (hideInteractInput) {\n      $input.style.display = 'none'\n      dialog.$el.querySelector<HTMLElement>('.atk-layer-dialog-actions')!.style.display = 'none'\n    }\n\n    // 层装载 dialog 元素\n    layer.getEl().append(dialog.$el)\n\n    // onMount 回调\n    if (payload.onMount) payload.onMount(dialog.$el)\n  }\n}\n\nexport interface Checker<T = any> {\n  el?: HTMLElement\n  inputType?: 'password' | 'text'\n  body: (checker: CheckerCtx) => HTMLElement\n  request: (checker: CheckerCtx, inputVal: string) => Promise<T>\n  onSuccess?: (checker: CheckerCtx, respData: T, inputVal: string, formEl: HTMLElement) => void\n  onError?: (checker: CheckerCtx, errData: any, inputVal: string, formEl: HTMLElement) => void\n}\n\ninterface CheckerStore {\n  val?: string\n  img_data?: string\n  iframe?: string\n}\n\nexport interface CheckerCtx {\n  get<K extends keyof CheckerStore>(key: K): CheckerStore[K]\n  set<K extends keyof CheckerStore>(key: K, val: CheckerStore[K]): void\n  getOpts(): CheckerLauncherOptions\n  getApi(): Api\n  getUser(): UserManager\n  hideInteractInput(): void\n  triggerSuccess(): void\n  cancel(): void\n}\n","import type { ArtalkPlugin } from '@/types'\nimport { CheckerLauncher } from '@/components/checker'\n\nexport const CheckersService: ArtalkPlugin = (ctx) => {\n  ctx.provide(\n    'checkers',\n    (api, apiHandlers, layers, user, config) => {\n      const checkers = new CheckerLauncher({\n        getApi: () => api,\n        getLayers: () => layers,\n        getUser: () => user,\n        onReload: () => ctx.reload(),\n\n        // make sure suffix with a slash, because it will be used as a base url when call `fetch`\n        getCaptchaIframeURL: () => `${config.get().server}/api/v2/captcha/?t=${+new Date()}`,\n      })\n\n      apiHandlers.add('need_captcha', (res) => checkers.checkCaptcha(res))\n      apiHandlers.add('need_login', () => checkers.checkAdmin({}))\n\n      return checkers\n    },\n    ['api', 'apiHandlers', 'layers', 'user', 'config'] as const,\n  )\n}\n","import * as Utils from '../lib/utils'\nimport EditorHTML from './editor.html?raw'\n\nconst Sel = {\n  $header: '.atk-header',\n  $name: '.atk-header [name=\"name\"]',\n  $email: '.atk-header [name=\"email\"]',\n  $link: '.atk-header [name=\"link\"]',\n  $textareaWrap: '.atk-textarea-wrap',\n  $textarea: '.atk-textarea',\n  $bottom: '.atk-bottom',\n  $submitBtn: '.atk-send-btn',\n  $notifyWrap: '.atk-notify-wrap',\n  $bottomLeft: '.atk-bottom-left',\n  $stateWrap: '.atk-state-wrap',\n  $plugBtnWrap: '.atk-plug-btn-wrap',\n  $plugPanelWrap: '.atk-plug-panel-wrap',\n}\n\nexport interface EditorUI extends Record<keyof typeof Sel, HTMLElement> {\n  $el: HTMLElement\n  $name: HTMLInputElement\n  $email: HTMLInputElement\n  $link: HTMLInputElement\n  $textarea: HTMLTextAreaElement\n  $submitBtn: HTMLButtonElement\n  $sendReplyBtn?: HTMLElement\n  $editCancelBtn?: HTMLElement\n}\n\nexport function render() {\n  const $el = Utils.createElement(EditorHTML)\n  const ui = { $el }\n  Object.entries(Sel).forEach(([k, sel]) => {\n    ui[k] = $el.querySelector(sel)\n  })\n  return ui as EditorUI\n}\n","import Mover from '../plugins/editor/mover'\nimport type { EditorState, CommentData, Editor } from '@/types'\nimport * as Ui from '@/lib/ui'\n\nexport class EditorStateManager {\n  constructor(private editor: Editor) {}\n\n  private stateCurt: EditorState = 'normal'\n  private stateUnmountFn: (() => void) | null = null\n\n  /** Get current state */\n  get() {\n    return this.stateCurt\n  }\n\n  /**\n   * Switch editor state\n   *\n   * @param state The state to switch\n   * @param payload The cause of state switch\n   */\n  switch(state: EditorState, payload?: { $comment: HTMLElement; comment: CommentData }) {\n    // trigger unmount\n    if (this.stateUnmountFn) {\n      this.stateUnmountFn()\n      this.stateUnmountFn = null\n\n      // move editor back to the initial position\n      this.editor.getPlugins()?.get(Mover)?.back()\n    }\n\n    // invoke effect function and save unmount function\n    if (state !== 'normal' && payload) {\n      // move editor position\n      let moveAfterEl = payload.$comment\n      if (!this.editor.getOptions().getConf().get().flatMode)\n        moveAfterEl = moveAfterEl.querySelector<HTMLElement>('.atk-footer')!\n      this.editor.getPlugins()?.get(Mover)?.move(moveAfterEl)\n\n      const $relative = this.editor.getOptions().getConf().get().scrollRelativeTo?.()\n      Ui.scrollIntoView(this.editor.getUI().$el, true, $relative)\n\n      const plugin = this.editor\n        .getPlugins()\n        ?.getPlugins()\n        .find((p) => p.editorStateEffectWhen === state)\n      if (plugin && plugin.editorStateEffect) {\n        this.stateUnmountFn = plugin.editorStateEffect(payload.comment)\n      }\n    }\n\n    // change current state\n    this.stateCurt = state\n  }\n}\n","import * as Ui from '../lib/ui'\nimport marked from '../lib/marked'\nimport { render, type EditorUI } from './ui'\nimport { EditorStateManager } from './state'\nimport type { ConfigManager, CommentData, Editor as IEditor, EventManager } from '@/types'\nimport type { PluginManager } from '@/plugins/editor-kit'\n\nexport interface EditorOptions {\n  getEvents: () => EventManager\n  getConf: () => ConfigManager\n}\n\nexport class Editor implements IEditor {\n  private opts: EditorOptions\n  private $el: HTMLElement\n  private ui: EditorUI\n  private state: EditorStateManager\n  private plugins?: PluginManager\n\n  constructor(opts: EditorOptions) {\n    this.opts = opts\n\n    // init editor ui\n    this.ui = render()\n    this.$el = this.ui.$el\n\n    // init state manager\n    this.state = new EditorStateManager(this)\n  }\n\n  getOptions() {\n    return this.opts\n  }\n\n  getEl() {\n    return this.$el\n  }\n\n  getUI() {\n    return this.ui\n  }\n\n  getPlugins() {\n    return this.plugins\n  }\n\n  setPlugins(plugins: PluginManager) {\n    this.plugins = plugins\n  }\n\n  getState() {\n    return this.state.get()\n  }\n\n  getHeaderInputEls() {\n    return { name: this.ui.$name, email: this.ui.$email, link: this.ui.$link }\n  }\n\n  getContentFinal() {\n    let content = this.getContentRaw()\n\n    // plugin hook: final content transformer\n    const plugins = this.getPlugins()\n    if (plugins) content = plugins.getTransformedContent(content)\n\n    return content\n  }\n\n  getContentRaw() {\n    return this.ui.$textarea.value || ''\n  }\n\n  getContentMarked() {\n    return marked(this.getContentFinal())\n  }\n\n  setContent(val: string) {\n    this.ui.$textarea.value = val\n\n    // plug hook: content updated\n    this.getPlugins()?.getEvents().trigger('content-updated', val)\n  }\n\n  insertContent(val: string) {\n    if ((document as any).selection) {\n      this.ui.$textarea.focus()\n      ;(document as any).selection.createRange().text = val\n      this.ui.$textarea.focus()\n    } else if (this.ui.$textarea.selectionStart || this.ui.$textarea.selectionStart === 0) {\n      const sStart = this.ui.$textarea.selectionStart\n      const sEnd = this.ui.$textarea.selectionEnd\n      const sT = this.ui.$textarea.scrollTop\n      this.setContent(\n        this.ui.$textarea.value.substring(0, sStart) +\n          val +\n          this.ui.$textarea.value.substring(sEnd, this.ui.$textarea.value.length),\n      )\n      this.ui.$textarea.focus()\n      this.ui.$textarea.selectionStart = sStart + val.length\n      this.ui.$textarea.selectionEnd = sStart + val.length\n      this.ui.$textarea.scrollTop = sT\n    } else {\n      this.ui.$textarea.focus()\n      this.ui.$textarea.value += val\n    }\n  }\n\n  focus() {\n    this.ui.$textarea.focus()\n  }\n\n  reset() {\n    this.setContent('')\n    this.resetState()\n  }\n\n  resetState() {\n    this.state.switch('normal')\n  }\n\n  setReplyComment(comment: CommentData, $comment: HTMLElement) {\n    this.state.switch('reply', { comment, $comment })\n  }\n\n  setEditComment(comment: CommentData, $comment: HTMLElement) {\n    this.state.switch('edit', { comment, $comment })\n  }\n\n  showNotify(msg: string, type: any) {\n    Ui.showNotify(this.ui.$notifyWrap, msg, type)\n  }\n\n  showLoading() {\n    Ui.showLoading(this.ui.$el)\n  }\n\n  hideLoading() {\n    Ui.hideLoading(this.ui.$el)\n  }\n\n  submit() {\n    const next = () => {\n      this.getPlugins()?.getEvents().trigger('editor-submit')\n      this.opts.getEvents().trigger('editor-submit')\n    }\n    const beforeSubmit = this.opts.getConf().get().beforeSubmit\n    if (beforeSubmit) {\n      beforeSubmit(this, next)\n    } else {\n      next()\n    }\n  }\n}\n","export default \"<div class=\\\"atk-main-editor\\\">\\n  <div class=\\\"atk-header\\\">\\n    <input name=\\\"name\\\" class=\\\"atk-name\\\" type=\\\"text\\\" required=\\\"required\\\" />\\n    <input name=\\\"email\\\" class=\\\"atk-email\\\" type=\\\"email\\\" required=\\\"required\\\" />\\n    <input name=\\\"link\\\" class=\\\"atk-link\\\" type=\\\"url\\\" />\\n  </div>\\n  <div class=\\\"atk-textarea-wrap\\\">\\n    <textarea class=\\\"atk-textarea\\\"></textarea>\\n  </div>\\n  <div class=\\\"atk-plug-panel-wrap\\\" style=\\\"display: none\\\"></div>\\n  <div class=\\\"atk-bottom\\\">\\n    <div class=\\\"atk-item atk-bottom-left\\\">\\n      <span class=\\\"atk-state-wrap\\\"></span>\\n      <span class=\\\"atk-plug-btn-wrap\\\"></span>\\n    </div>\\n    <div class=\\\"atk-item\\\">\\n      <button type=\\\"button\\\" class=\\\"atk-send-btn\\\"></button>\\n    </div>\\n  </div>\\n  <div class=\\\"atk-notify-wrap\\\"></div>\\n</div>\\n\"","import type {\n  NotifyData,\n  PageData,\n  CommentData,\n  DataManager as IDataManager,\n  ListFetchParams,\n  ListLastFetchData,\n  EventManager,\n} from '@/types'\n\nexport class DataManager implements IDataManager {\n  /** Loading status */\n  private loading: boolean = false\n\n  /** List last fetch data */\n  private listLastFetch?: ListLastFetchData\n\n  /** Comment list (Flatten list and unordered) */\n  private comments: CommentData[] = []\n\n  /** Notify list */\n  private notifies: NotifyData[] = []\n\n  /** Page data */\n  private page?: PageData\n\n  constructor(protected events: EventManager) {}\n\n  getLoading() {\n    return this.loading\n  }\n\n  setLoading(val: boolean) {\n    this.loading = val\n  }\n\n  getListLastFetch() {\n    return this.listLastFetch\n  }\n\n  setListLastFetch(val: ListLastFetchData) {\n    this.listLastFetch = val\n  }\n\n  // -------------------------------------------------------------------\n  //  Comments\n  // -------------------------------------------------------------------\n  getComments() {\n    return this.comments\n  }\n\n  fetchComments(params: Partial<ListFetchParams>) {\n    this.events.trigger('list-fetch', params)\n  }\n\n  findComment(id: number) {\n    return this.comments.find((c) => c.id === id)\n  }\n\n  clearComments() {\n    this.comments = []\n    this.events.trigger('list-loaded', this.comments)\n  }\n\n  loadComments(partialComments: CommentData[]) {\n    this.events.trigger('list-load', partialComments)\n\n    this.comments.push(...partialComments)\n\n    this.events.trigger('list-loaded', this.comments)\n  }\n\n  insertComment(comment: CommentData) {\n    this.comments.push(comment)\n\n    this.events.trigger('comment-inserted', comment)\n    this.events.trigger('list-loaded', this.comments) // list-loaded should always keep the last\n  }\n\n  updateComment(comment: CommentData) {\n    this.comments = this.comments.map((c) => {\n      if (c.id === comment.id) return comment\n      return c\n    })\n\n    this.events.trigger('comment-updated', comment)\n    this.events.trigger('list-loaded', this.comments)\n  }\n\n  deleteComment(id: number) {\n    const comment = this.comments.find((c) => c.id === id)\n    if (!comment) throw new Error(`Comment ${id} not found`)\n    this.comments = this.comments.filter((c) => c.id !== id)\n\n    this.events.trigger('comment-deleted', comment)\n    this.events.trigger('list-loaded', this.comments)\n  }\n\n  // -------------------------------------------------------------------\n  //  Notifies\n  // -------------------------------------------------------------------\n  getNotifies() {\n    return this.notifies\n  }\n\n  updateNotifies(notifies: NotifyData[]) {\n    this.notifies = notifies\n\n    this.events.trigger('notifies-updated', this.notifies)\n  }\n\n  // -------------------------------------------------------------------\n  // Page\n  // -------------------------------------------------------------------\n  getPage() {\n    return this.page\n  }\n\n  updatePage(pageData: PageData) {\n    this.page = pageData\n\n    this.events.trigger('page-loaded', pageData)\n  }\n}\n","import type { Layer as ILayer } from '@/types/layer'\n\nexport interface LayerOptions {\n  onShow: () => void\n  onHide: () => void\n}\n\nexport class Layer implements ILayer {\n  private allowMaskClose = true\n  private onAfterHide?: () => void\n\n  constructor(\n    private $el: HTMLElement,\n    private opts: LayerOptions,\n  ) {}\n\n  setOnAfterHide(func: () => void) {\n    this.onAfterHide = func\n  }\n\n  setAllowMaskClose(allow: boolean) {\n    this.allowMaskClose = allow\n  }\n\n  getAllowMaskClose() {\n    return this.allowMaskClose\n  }\n\n  getEl() {\n    return this.$el\n  }\n\n  show() {\n    this.opts.onShow()\n    this.$el.style.display = ''\n  }\n\n  hide() {\n    this.opts.onHide()\n    this.$el.style.display = 'none'\n    this.onAfterHide && this.onAfterHide()\n  }\n\n  destroy() {\n    this.opts.onHide()\n    this.$el.remove()\n    this.onAfterHide && this.onAfterHide()\n  }\n}\n","import * as Ui from '@/lib/ui'\n\nlet bodyOrgOverflow: string\nlet bodyOrgPaddingRight: string\n\nexport function getScrollbarHelper() {\n  return {\n    init() {\n      bodyOrgOverflow = document.body.style.overflow\n      bodyOrgPaddingRight = document.body.style.paddingRight\n    },\n\n    unlock() {\n      document.body.style.overflow = bodyOrgOverflow\n      document.body.style.paddingRight = bodyOrgPaddingRight\n    },\n\n    lock() {\n      document.body.style.overflow = 'hidden'\n      const barPaddingRight = parseInt(\n        window.getComputedStyle(document.body, null).getPropertyValue('padding-right'),\n        10,\n      )\n      document.body.style.paddingRight = `${Ui.getScrollBarWidth() + barPaddingRight || 0}px`\n    },\n  }\n}\n","import { getScrollbarHelper } from './scrollbar-helper'\nimport { Layer } from './layer'\nimport * as Utils from '@/lib/utils'\n\nexport class LayerWrap {\n  private $wrap: HTMLElement\n  private $mask: HTMLElement\n  private items: Layer[] = []\n\n  constructor() {\n    this.$wrap = Utils.createElement(\n      `<div class=\"atk-layer-wrap\" style=\"display: none;\"><div class=\"atk-layer-mask\"></div></div>`,\n    )\n    this.$mask = this.$wrap.querySelector<HTMLElement>('.atk-layer-mask')!\n  }\n\n  createItem(name: string, el?: HTMLElement) {\n    // init element\n    el = el || this.createItemElement(name)\n    el.setAttribute('data-layer-name', name)\n    this.$wrap.appendChild(el)\n\n    // create layer instance\n    const layer = new Layer(el, {\n      onHide: () => this.hideWrap(el!),\n      onShow: () => this.showWrap(),\n    })\n\n    // register mask click event\n    this.getMask().addEventListener('click', () => {\n      layer.getAllowMaskClose() && layer.hide()\n    })\n\n    // add to items\n    this.items.push(layer)\n\n    return layer\n  }\n\n  private createItemElement(name: string) {\n    const el = document.createElement('div')\n    el.classList.add('atk-layer-item')\n    el.style.display = 'none'\n    this.$wrap.appendChild(el)\n    return el\n  }\n\n  getWrap() {\n    return this.$wrap\n  }\n\n  getMask() {\n    return this.$mask\n  }\n\n  showWrap() {\n    this.$wrap.style.display = 'block'\n    this.$mask.style.display = 'block'\n    this.$mask.classList.add('atk-fade-in')\n    getScrollbarHelper().lock()\n  }\n\n  hideWrap($el: HTMLElement) {\n    // if wrap contains more than one item, do not hide entire wrap\n    if (\n      this.items\n        .map((l) => l.getEl())\n        .filter((e) => e !== $el && e.isConnected && e.style.display !== 'none').length > 0\n    ) {\n      return\n    }\n\n    this.$wrap.style.display = 'none'\n    getScrollbarHelper().unlock()\n  }\n}\n","import { getScrollbarHelper } from './scrollbar-helper'\nimport { LayerWrap } from './wrap'\nimport type { LayerManager as ILayerManager } from '@/types'\n\nexport class LayerManager implements ILayerManager {\n  private wrap = new LayerWrap()\n\n  constructor() {\n    getScrollbarHelper().init()\n  }\n\n  getEl() {\n    return this.wrap.getWrap()\n  }\n\n  create(name: string, el?: HTMLElement) {\n    return this.wrap.createItem(name, el)\n  }\n\n  destroy() {\n    this.wrap.getWrap().remove()\n  }\n}\n","import type { LayoutStrategyCreator } from '.'\nimport type { CommentNode } from '@/comment'\nimport * as ListNest from '@/list/nest'\n\nexport const createNestStrategy: LayoutStrategyCreator = (opts) => ({\n  import: (comments) => {\n    // 遍历 root 评论\n    const rootNodes = ListNest.makeNestCommentNodeList(comments, opts.nestSortBy, opts.nestMax)\n    rootNodes.forEach((rootNode: ListNest.CommentNode) => {\n      const rootC = opts.createCommentNode(rootNode.comment)\n\n      // 显示并播放渐入动画\n      opts.$commentsWrap?.appendChild(rootC.getEl())\n      rootC.getRender().playFadeAnim()\n\n      // 加载子评论\n      const loadChildren = (parentC: CommentNode, parentNode: ListNest.CommentNode) => {\n        parentNode.children.forEach((node: ListNest.CommentNode) => {\n          const replyD = comments.find((c) => c.id === node.comment.rid)\n          const childD = node.comment\n          const childC = opts.createCommentNode(childD, replyD)\n\n          // 插入到父评论中\n          parentC.putChild(childC)\n\n          // 递归加载子评论\n          loadChildren(childC, node)\n        })\n      }\n      loadChildren(rootC, rootNode)\n\n      // 限高检测\n      rootC.getRender().checkHeightLimit()\n    })\n  },\n  insert: (comment, replyComment) => {\n    // 嵌套模式\n    const node = opts.createCommentNode(comment, replyComment)\n\n    if (comment.rid === 0) {\n      // root评论 新增\n      opts.$commentsWrap?.prepend(node.getEl())\n    } else {\n      // 子评论 新增\n      const parent = opts.findCommentNode(comment.rid)\n      if (parent) {\n        parent.putChild(node, opts.nestSortBy === 'DATE_ASC' ? 'append' : 'prepend')\n\n        // 若父评论存在 “子评论部分” 限高，取消限高\n        node.getParents().forEach((p) => {\n          p.getRender().heightLimitRemoveForChildren()\n        })\n      }\n    }\n\n    node.getRender().checkHeightLimit()\n\n    node.scrollIntoView() // 滚动到可以见\n    node.getRender().playFadeAnim() // 播放评论渐出动画\n  },\n})\n","import type { CommentData } from '@/types'\n\nexport type CommentNode = {\n  id: number\n  comment: CommentData\n  children: CommentNode[]\n  parent?: CommentNode\n  level: number\n}\n\nexport type SortByType = 'DATE_DESC' | 'DATE_ASC' | 'SRC_INDEX' | 'VOTE_UP_DESC'\n\n// 构建树状结构列表\nexport function makeNestCommentNodeList(\n  srcData: CommentData[],\n  sortBy: SortByType = 'DATE_DESC',\n  nestMax = 2,\n) {\n  const nodeList: CommentNode[] = []\n\n  const roots = srcData.filter((o) => o.rid === 0)\n  roots.forEach((root: CommentData) => {\n    const rootNode: CommentNode = {\n      id: root.id,\n      comment: root,\n      children: [],\n      level: 1,\n    }\n\n    rootNode.parent = rootNode\n    nodeList.push(rootNode)\n    ;(function loadChildren(parentNode: CommentNode) {\n      const children = srcData.filter((o) => o.rid === parentNode.id)\n      if (children.length === 0) return\n      if (parentNode.level >= nestMax) parentNode = parentNode.parent!\n      children.forEach((child: CommentData) => {\n        const childNode: CommentNode = {\n          id: child.id,\n          comment: child,\n          children: [],\n          parent: parentNode,\n          level: parentNode.level + 1,\n        }\n\n        parentNode.children.push(childNode)\n        loadChildren(childNode)\n      })\n    })(rootNode)\n  })\n\n  // 排序\n  const sortFunc = (a: CommentNode, b: CommentNode): number => {\n    let v = a.id - b.id\n    if (sortBy === 'DATE_ASC') v = +new Date(a.comment.date) - +new Date(b.comment.date)\n    else if (sortBy === 'DATE_DESC') v = +new Date(b.comment.date) - +new Date(a.comment.date)\n    else if (sortBy === 'SRC_INDEX') v = srcData.indexOf(a.comment) - srcData.indexOf(b.comment)\n    else if (sortBy === 'VOTE_UP_DESC') v = b.comment.vote_up - a.comment.vote_up\n    return v\n  }\n\n  ;(function sortLevels(nodes: CommentNode[]) {\n    nodes.forEach((node) => {\n      node.children = node.children.sort(sortFunc)\n      sortLevels(node.children)\n    })\n  })(nodeList)\n\n  return nodeList\n}\n","import type { LayoutStrategyCreator, LayoutOptions } from '.'\nimport type { CommentData } from '@/types'\n\nexport const createFlatStrategy: LayoutStrategyCreator = (opts) => ({\n  import: (comments) => {\n    comments.forEach((comment: CommentData) => {\n      const replyComment =\n        comment.rid === 0 ? undefined : comments.find((c) => c.id === comment.rid)\n      insertComment(opts, 'append', comment, replyComment)\n    })\n  },\n  insert: (comment, replyComment) => {\n    const node = insertComment(opts, 'prepend', comment, replyComment)\n    node.scrollIntoView()\n  },\n})\n\n/** 导入评论 · 平铺模式 */\nfunction insertComment(\n  opts: LayoutOptions,\n  insertMode: 'append' | 'prepend',\n  comment: CommentData,\n  replyComment?: CommentData | undefined,\n) {\n  if (comment.is_collapsed) comment.is_allow_reply = false\n  const node = opts.createCommentNode(comment, replyComment)\n\n  // 可见评论添加到界面\n  // 注：不可见评论用于显示 “引用内容”\n  if (comment.visible) {\n    const $comment = node.getEl()\n    const $listCommentsWrap = opts.$commentsWrap\n    if (insertMode === 'append') $listCommentsWrap?.append($comment)\n    if (insertMode === 'prepend') $listCommentsWrap?.prepend($comment)\n    node.getRender().playFadeAnim()\n  }\n\n  // 平铺评论插入后 · 内容限高检测\n  // 插入列表的评论 (visible=true) 和关联的评论 (visible=false) 都需要检测\n  node.getRender().checkHeightLimit()\n\n  return node\n}\n","import * as ListNest from '../nest'\nimport { createNestStrategy } from './nest'\nimport { createFlatStrategy } from './flat'\nimport type { CommentNode } from '@/comment'\nimport type { CommentData } from '@/types'\n\nexport interface LayoutOptions {\n  /** The comments wrap of list */\n  $commentsWrap: HTMLElement\n  nestSortBy: ListNest.SortByType\n  nestMax: number\n  flatMode: boolean\n\n  createCommentNode(comment: CommentData, replyComment?: CommentData): CommentNode\n  findCommentNode(id: number): CommentNode | undefined\n}\n\nexport interface LayoutStrategy {\n  import(comments: CommentData[]): void\n  insert(comment: CommentData, replyComment?: CommentData): void\n}\n\nexport type LayoutStrategyCreator = (opts: LayoutOptions) => LayoutStrategy\n\nexport class ListLayout {\n  constructor(private options: LayoutOptions) {}\n\n  private getStrategy() {\n    return this.options.flatMode\n      ? createFlatStrategy(this.options)\n      : createNestStrategy(this.options)\n  }\n\n  import(comments: CommentData[]) {\n    this.getStrategy().import(comments)\n  }\n\n  insert(comment: CommentData, replyComment?: CommentData) {\n    this.getStrategy().insert(comment, replyComment)\n  }\n}\n","import * as Utils from '../lib/utils'\nimport $t from '../i18n'\n\nexport interface IHeightLimitConf {\n  /** After expand btn click */\n  afterExpandBtnClick?: () => void\n  /** Allow Scroll */\n  scrollable?: boolean\n}\n\nexport interface IHeightLimitRule {\n  /** Target element need to check */\n  el: HTMLElement | null | undefined\n\n  /** Max height (unit: px) */\n  max: number\n\n  /** Whether or not the element contains `<img />` */\n  imgCheck?: boolean\n}\n\nexport type THeightLimitRuleSet = IHeightLimitRule[]\n\n/** Check all elements below the max height limit */\nexport function check(conf: IHeightLimitConf, rules: THeightLimitRuleSet) {\n  rules.forEach(({ el, max, imgCheck }) => {\n    if (!el) return\n\n    // set max height for avoiding img exceed the limit while loading\n    if (imgCheck) el.style.maxHeight = `${max + 1}px` // allow 1px more for next detecting\n\n    let lock = false\n    const _check = () => {\n      if (lock) return\n      if (Utils.getHeight(el) <= max) return // if not exceed the limit, do nothing\n\n      const afterExpandBtnClick = () => {\n        lock = true // add lock to prevent collapse again after expand when image lazy loaded\n        conf.afterExpandBtnClick?.()\n      }\n\n      !conf.scrollable\n        ? applyHeightLimit({ el, max, afterExpandBtnClick })\n        : applyScrollableHeightLimit({ el, max })\n    }\n\n    // check immediately\n    _check()\n\n    // check images after loaded\n    if (imgCheck) {\n      // check again when image loaded\n      const imgs = el.querySelectorAll<HTMLImageElement>('.atk-content img')\n      if (imgs.length === 0) el.style.maxHeight = ''\n      imgs.forEach((img) => {\n        img.onload = () => _check()\n      })\n    }\n  })\n}\n\n/** Height limit CSS class name */\nconst HEIGHT_LIMIT_CSS = 'atk-height-limit'\n\n/** Apply height limit on an element and add expand btn */\nexport function applyHeightLimit(obj: {\n  el: HTMLElement\n  max: number\n  afterExpandBtnClick?: (e: MouseEvent) => void\n}) {\n  if (!obj.el) return\n  if (!obj.max) return\n  if (obj.el.classList.contains(HEIGHT_LIMIT_CSS)) return\n\n  obj.el.classList.add(HEIGHT_LIMIT_CSS)\n  obj.el.style.height = `${obj.max}px`\n  obj.el.style.overflow = 'hidden'\n\n  /* Expand button */\n  const $expandBtn = Utils.createElement(\n    `<div class=\"atk-height-limit-btn\">${$t('readMore')}</span>`,\n  )\n  $expandBtn.onclick = (e) => {\n    e.stopPropagation()\n    disposeHeightLimit(obj.el)\n\n    if (obj.afterExpandBtnClick) obj.afterExpandBtnClick(e)\n  }\n  obj.el.append($expandBtn)\n}\n\n/** Dispose height limit on an element and remove expand btn */\nexport function disposeHeightLimit($el: HTMLElement) {\n  if (!$el) return\n  if (!$el.classList.contains(HEIGHT_LIMIT_CSS)) return\n\n  $el.classList.remove(HEIGHT_LIMIT_CSS)\n  Array.from($el.children).forEach((e) => {\n    if (e.classList.contains('atk-height-limit-btn')) e.remove()\n  })\n  $el.style.height = ''\n  $el.style.maxHeight = ''\n  $el.style.overflow = ''\n}\n\n/** Height limit scrollable CSS class name */\nconst HEIGHT_LIMIT_SCROLL_CSS = 'atk-height-limit-scroll'\n\n/** Apply scrollable height limit */\nexport function applyScrollableHeightLimit(opt: { el: HTMLElement; max: number }) {\n  if (!opt.el) return\n  if (opt.el.classList.contains(HEIGHT_LIMIT_SCROLL_CSS)) return\n  opt.el.classList.add(HEIGHT_LIMIT_SCROLL_CSS)\n  opt.el.style.height = `${opt.max}px`\n}\n","import * as Utils from '../../lib/utils'\nimport type Render from '../render'\nimport $t from '@/i18n'\n\n/**\n * 评论头部界面\n */\nexport default function renderHeader(r: Render) {\n  Object.entries({\n    renderNick,\n    renderVerifyBadge,\n    renderDate,\n    renderUABadge,\n  }).forEach(([name, render]) => {\n    render(r)\n  })\n}\n\nfunction renderNick(r: Render) {\n  r.$headerNick = r.$el.querySelector<HTMLElement>('.atk-nick')!\n\n  if (r.data.link) {\n    const $nickA = Utils.createElement<HTMLLinkElement>(\n      '<a target=\"_blank\" rel=\"noreferrer noopener nofollow\"></a>',\n    )\n    $nickA.innerText = r.data.nick\n    $nickA.href = Utils.isValidURL(r.data.link) ? r.data.link : `https://${r.data.link}`\n    r.$headerNick.append($nickA)\n  } else {\n    r.$headerNick.innerText = r.data.nick\n  }\n}\n\nfunction renderVerifyBadge(ctx: Render) {\n  ctx.$headerBadgeWrap = ctx.$el.querySelector<HTMLElement>('.atk-badge-wrap')!\n  ctx.$headerBadgeWrap.innerHTML = ''\n\n  const badgeText = ctx.data.badge_name\n  const badgeColor = ctx.data.badge_color\n  if (badgeText) {\n    const $badge = Utils.createElement(`<span class=\"atk-badge\"></span>`)\n    $badge.innerText = badgeText.replace('管理员', $t('admin')) // i18n patch\n    $badge.style.backgroundColor = badgeColor || ''\n    ctx.$headerBadgeWrap.append($badge)\n  } else if (ctx.data.is_verified) {\n    const $verifiedBadge = Utils.createElement(\n      `<span class=\"atk-icon-verified\" title=\"${$t('emailVerified')}\"></span>`,\n    ) // 邮箱验证徽章\n    ctx.$headerBadgeWrap.append($verifiedBadge)\n  }\n\n  if (ctx.data.is_pinned) {\n    const $pinnedBadge = Utils.createElement(`<span class=\"atk-pinned-badge\">${$t('pin')}</span>`) // 置顶徽章\n    ctx.$headerBadgeWrap.append($pinnedBadge)\n  }\n}\n\nfunction renderDate(ctx: Render) {\n  const $date = ctx.$el.querySelector<HTMLElement>('.atk-date')!\n  $date.innerText = ctx.comment.getDateFormatted()\n  $date.setAttribute('data-atk-comment-date', String(+new Date(ctx.data.date)))\n}\n\nfunction renderUABadge(ctx: Render) {\n  if (!ctx.opts.uaBadge && !ctx.data.ip_region) return\n\n  let $uaWrap = ctx.$header.querySelector('atk-ua-wrap')\n  if (!$uaWrap) {\n    $uaWrap = Utils.createElement(`<span class=\"atk-ua-wrap\"></span>`)\n    ctx.$header.append($uaWrap)\n  }\n\n  $uaWrap.innerHTML = ''\n\n  if (ctx.data.ip_region) {\n    const $regionBadge = Utils.createElement(`<span class=\"atk-region-badge\"></span>`)\n    $regionBadge.innerText = ctx.data.ip_region\n    $uaWrap.append($regionBadge)\n  }\n\n  if (ctx.opts.uaBadge) {\n    const { browser, os } = ctx.comment.getUserUA()\n    if (String(browser).trim()) {\n      const $uaBrowser = Utils.createElement(`<span class=\"atk-ua ua-browser\"></span>`)\n      $uaBrowser.innerText = browser\n      $uaWrap.append($uaBrowser)\n    }\n\n    if (String(os).trim()) {\n      const $usOS = Utils.createElement(`<span class=\"atk-ua ua-os\"></span>`)\n      $usOS.innerText = os\n      $uaWrap.append($usOS)\n    }\n  }\n}\n","import * as Utils from '../lib/utils'\nimport $t from '@/i18n'\n\ninterface ActionBtnOptions {\n  /** 按钮文字 (动态/静态) */\n  text: (() => string) | string\n\n  /** 仅管理员可用 */\n  adminOnly?: boolean\n\n  /** 确认操作 */\n  confirm?: boolean\n\n  /** 确认时提示文字 */\n  confirmText?: string\n}\n\n/**\n * 通用操作按钮\n */\nexport default class ActionBtn {\n  private opts: ActionBtnOptions\n  public $el: HTMLElement\n\n  public isLoading = false // 正在加载\n\n  public msgRecTimer?: number // 消息显示复原定时器\n  public msgRecTimerFunc?: () => void // 消息显示复原操作\n  public get isMessaging() {\n    return !!this.msgRecTimer\n  } // 消息正在显示\n\n  public isConfirming = false // 正在确认\n  public confirmRecTimer?: number // 确认消息复原定时器\n\n  /** 构造函数 */\n  constructor(opts: ActionBtnOptions | string | (() => string)) {\n    this.$el = Utils.createElement(`<span class=\"atk-common-action-btn\"></span>`)\n\n    this.opts = typeof opts !== 'object' ? { text: opts } : opts\n    this.$el.innerText = this.getText()\n\n    // 仅管理员可操作\n    if (this.opts.adminOnly) this.$el.setAttribute('atk-only-admin-show', '')\n  }\n\n  /** 将按钮装载到指定元素 */\n  public appendTo(dom: HTMLElement) {\n    dom.append(this.$el)\n    return this\n  }\n\n  /** 获取按钮文字（动态/静态） */\n  private getText() {\n    return typeof this.opts.text === 'string' ? this.opts.text : this.opts.text()\n  }\n\n  /** 设置点击事件 */\n  public setClick(func: () => void) {\n    this.$el.onclick = (e) => {\n      e.stopPropagation() // 防止穿透\n\n      // 按钮处于加载状态，禁止点击\n      if (this.isLoading) {\n        return\n      }\n\n      // 操作确认\n      if (this.opts.confirm && !this.isMessaging) {\n        const confirmRestore = () => {\n          this.isConfirming = false\n          this.$el.classList.remove('atk-btn-confirm')\n          this.$el.innerText = this.getText()\n        }\n\n        if (!this.isConfirming) {\n          this.isConfirming = true\n          this.$el.classList.add('atk-btn-confirm')\n          this.$el.innerText = this.opts.confirmText || $t('actionConfirm')\n          this.confirmRecTimer = window.setTimeout(() => confirmRestore(), 5000)\n          return\n        }\n\n        if (this.confirmRecTimer) window.clearTimeout(this.confirmRecTimer)\n        confirmRestore()\n      }\n\n      // 立刻释放掉原有的定时器（当显示消息后，用户立刻点击时）\n      if (this.msgRecTimer) {\n        this.fireMsgRecTimer()\n        this.clearMsgRecTimer()\n        return\n      }\n\n      // 触发设定的点击事件\n      func()\n    }\n  }\n\n  /** 文字刷新（动态/静态） */\n  public updateText(text?: (() => string) | string) {\n    if (text) this.opts.text = text\n    this.setLoading(false)\n    this.$el.innerText = this.getText()\n  }\n\n  /** 设置加载状态 */\n  public setLoading(value: boolean, loadingText?: string) {\n    if (this.isLoading === value) return\n    this.isLoading = value\n    if (value) {\n      this.$el.classList.add('atk-btn-loading')\n      this.$el.innerText = loadingText || `${$t('loading')}...`\n    } else {\n      this.$el.classList.remove('atk-btn-loading')\n      this.$el.innerText = this.getText()\n    }\n  }\n\n  /** 错误消息 */\n  public setError(text: string) {\n    this.setMsg(text, 'atk-btn-error')\n  }\n\n  /** 警告消息 */\n  public setWarn(text: string) {\n    this.setMsg(text, 'atk-btn-warn')\n  }\n\n  /** 成功消息 */\n  public setSuccess(text: string) {\n    this.setMsg(text, 'atk-btn-success')\n  }\n\n  /** 设置消息 */\n  public setMsg(text: string, className?: string, duringTime?: number, after?: () => void) {\n    this.setLoading(false)\n    if (className) this.$el.classList.add(className)\n    this.$el.innerText = text\n\n    // 设定复原 timer\n    this.setMsgRecTimer(() => {\n      this.$el.innerText = this.getText()\n      if (className) this.$el.classList.remove(className)\n      if (after) after()\n    }, duringTime || 2500) // 消息默认显示持续 2500s\n  }\n\n  /** 设置消息复原操作定时器 */\n  private setMsgRecTimer(func: () => void, duringTime: number) {\n    this.fireMsgRecTimer()\n    this.clearMsgRecTimer()\n\n    this.msgRecTimerFunc = func\n    this.msgRecTimer = window.setTimeout(() => {\n      func()\n      this.clearMsgRecTimer()\n    }, duringTime)\n  }\n\n  /** 立刻触发器复原定时器 */\n  private fireMsgRecTimer() {\n    if (this.msgRecTimerFunc) this.msgRecTimerFunc()\n  }\n\n  /** 仅清除 timer */\n  private clearMsgRecTimer() {\n    if (this.msgRecTimer) window.clearTimeout(this.msgRecTimer)\n    this.msgRecTimer = undefined\n    this.msgRecTimerFunc = undefined\n  }\n}\n","import ActionBtn from '../../components/action-btn'\nimport type Render from '../render'\nimport $t from '@/i18n'\n\n/**\n * 评论操作按钮界面\n */\nexport default function renderActions(r: Render) {\n  Object.entries({\n    renderVote,\n    renderReply,\n    // 管理员操作\n    renderCollapse,\n    renderModerator,\n    renderPin,\n    renderEdit,\n    renderDel,\n  }).forEach(([name, render]) => {\n    render(r)\n  })\n}\n\n// 操作按钮 - 投票\nfunction renderVote(r: Render) {\n  if (!r.opts.vote) return // 关闭投票功能\n\n  // 赞同按钮\n  r.voteBtnUp = new ActionBtn(() => `${$t('voteUp')} (${r.data.vote_up || 0})`).appendTo(r.$actions)\n  r.voteBtnUp.setClick(() => {\n    r.comment.getActions().vote('up')\n  })\n\n  // 反对按钮\n  if (r.opts.voteDown) {\n    r.voteBtnDown = new ActionBtn(() => `${$t('voteDown')} (${r.data.vote_down || 0})`).appendTo(\n      r.$actions,\n    )\n    r.voteBtnDown.setClick(() => {\n      r.comment.getActions().vote('down')\n    })\n  }\n}\n\n// 操作按钮 - 回复\nfunction renderReply(r: Render) {\n  if (!r.data.is_allow_reply) return // 不允许回复\n  const replyBtn = new ActionBtn({\n    text: $t('reply'),\n  })\n  replyBtn.appendTo(r.$actions)\n  replyBtn.setClick(() => {\n    r.opts.replyComment(r.data, r.$el)\n  })\n}\n\n// 操作按钮 - 折叠\nfunction renderCollapse(r: Render) {\n  const collapseBtn = new ActionBtn({\n    text: () => (r.data.is_collapsed ? $t('expand') : $t('collapse')),\n    adminOnly: true,\n  })\n  collapseBtn.appendTo(r.$actions)\n  collapseBtn.setClick(() => {\n    r.comment.getActions().adminEdit('collapsed', collapseBtn)\n  })\n}\n\n// 操作按钮 - 审核\nfunction renderModerator(r: Render) {\n  const pendingBtn = new ActionBtn({\n    text: () => (r.data.is_pending ? $t('pending') : $t('approved')),\n    adminOnly: true,\n  })\n  pendingBtn.appendTo(r.$actions)\n  pendingBtn.setClick(() => {\n    r.comment.getActions().adminEdit('pending', pendingBtn)\n  })\n}\n\n// 操作按钮 - 置顶\nfunction renderPin(r: Render) {\n  const pinnedBtn = new ActionBtn({\n    text: () => (r.data.is_pinned ? $t('unpin') : $t('pin')),\n    adminOnly: true,\n  })\n  pinnedBtn.appendTo(r.$actions)\n  pinnedBtn.setClick(() => {\n    r.comment.getActions().adminEdit('pinned', pinnedBtn)\n  })\n}\n\n// 操作按钮 - 编辑\nfunction renderEdit(r: Render) {\n  const editBtn = new ActionBtn({\n    text: $t('edit'),\n    adminOnly: true,\n  })\n  editBtn.appendTo(r.$actions)\n  editBtn.setClick(() => {\n    r.opts.editComment(r.data, r.$el)\n  })\n}\n\n// 操作按钮 - 删除\nfunction renderDel(r: Render) {\n  const delBtn = new ActionBtn({\n    text: $t('delete'),\n    confirm: true,\n    confirmText: $t('deleteConfirm'),\n    adminOnly: true,\n  })\n  delBtn.appendTo(r.$actions)\n  delBtn.setClick(() => {\n    r.comment.getActions().adminDelete(delBtn)\n  })\n}\n","import type Render from '../render'\nimport Avatar from './avatar'\nimport Header from './header'\nimport Content from './content'\nimport ReplyAt from './reply-at'\nimport ReplyTo from './reply-to'\nimport Pending from './pending'\nimport Actions from './actions'\n\nconst Renders = {\n  Avatar,\n  Header,\n  Content,\n  ReplyAt,\n  ReplyTo,\n  Pending,\n  Actions,\n}\n\nexport default function loadRenders(r: Render) {\n  Object.entries(Renders).forEach(([name, render]) => {\n    render(r)\n  })\n}\n","import * as Utils from '../../lib/utils'\nimport type Render from '../render'\n\n/**\n * 评论头像界面\n */\nexport default function renderAvatar(r: Render) {\n  const $avatar = r.$el.querySelector<HTMLElement>('.atk-avatar')!\n  const $avatarImg = Utils.createElement<HTMLImageElement>('<img />')\n\n  const avatarURLBuilder = r.opts.avatarURLBuilder\n  $avatarImg.src = avatarURLBuilder ? avatarURLBuilder(r.data) : r.comment.getGravatarURL()\n\n  if (r.data.link) {\n    const $avatarA = Utils.createElement<HTMLLinkElement>(\n      '<a target=\"_blank\" rel=\"noreferrer noopener nofollow\"></a>',\n    )\n    $avatarA.href = Utils.isValidURL(r.data.link) ? r.data.link : `https://${r.data.link}`\n    $avatarA.append($avatarImg)\n    $avatar.append($avatarA)\n  } else {\n    $avatar.append($avatarImg)\n  }\n}\n","import * as Utils from '../../lib/utils'\nimport * as Ui from '../../lib/ui'\nimport type Render from '../render'\nimport $t from '@/i18n'\n\n/**\n * 评论内容界面\n */\nexport default function renderContent(r: Render) {\n  if (!r.data.is_collapsed) {\n    r.$content.innerHTML = r.comment.getContentMarked()\n    r.$content.classList.remove('atk-hide', 'atk-collapsed')\n    return\n  }\n\n  // 内容 & 折叠\n  r.$content.classList.add('atk-hide', 'atk-type-collapsed')\n  const collapsedInfoEl = Utils.createElement(`\n    <div class=\"atk-collapsed\">\n      <span class=\"atk-text\">${$t('collapsedMsg')}</span>\n      <span class=\"atk-show-btn\">${$t('expand')}</span>\n    </div>`)\n  r.$body.insertAdjacentElement('beforeend', collapsedInfoEl)\n\n  const contentShowBtn = collapsedInfoEl.querySelector<HTMLElement>('.atk-show-btn')!\n  contentShowBtn.addEventListener('click', (e) => {\n    e.stopPropagation() // 防止穿透\n\n    if (r.$content.classList.contains('atk-hide')) {\n      r.$content.innerHTML = r.comment.getContentMarked()\n      r.$content.classList.remove('atk-hide')\n      Ui.playFadeInAnim(r.$content)\n      contentShowBtn.innerText = $t('collapse')\n    } else {\n      r.$content.innerHTML = ''\n      r.$content.classList.add('atk-hide')\n      contentShowBtn.innerText = $t('expand')\n    }\n  })\n}\n","import * as Utils from '../../lib/utils'\nimport type Render from '../render'\n\n/**\n * Reply user indicator (with arrow icon) in the comment meta header\n */\nexport default function renderReplyAt(r: Render) {\n  if (r.opts.flatMode || r.data.rid === 0) return // if not nested mode or root comment\n  if (!r.opts.replyTo) return // if no replyTo data\n\n  r.$replyAt = Utils.createElement(\n    `<span class=\"atk-item atk-reply-at\"><span class=\"atk-arrow\"></span><span class=\"atk-nick\"></span></span>`,\n  )\n  r.$replyAt.querySelector<HTMLElement>('.atk-nick')!.innerText = `${r.opts.replyTo.nick}`\n  r.$replyAt.onclick = () => {\n    r.comment.getActions().goToReplyComment()\n  }\n\n  r.$headerBadgeWrap.insertAdjacentElement('afterend', r.$replyAt)\n}\n","import type Render from '../render'\nimport * as Utils from '@/lib/utils'\nimport marked from '@/lib/marked'\nimport $t from '@/i18n'\n\n/**\n * 关联评论显示 (被回复的评论)\n */\nexport default function renderReplyTo(r: Render) {\n  if (!r.opts.flatMode) return // 仅平铺模式显示\n  if (!r.opts.replyTo) return\n\n  r.$replyTo = Utils.createElement(`\n    <div class=\"atk-reply-to\">\n      <div class=\"atk-meta\">${$t('reply')} <span class=\"atk-nick\"></span>:</div>\n      <div class=\"atk-content\"></div>\n    </div>`)\n\n  // Comment author name\n  const $nick = r.$replyTo.querySelector<HTMLElement>('.atk-nick')!\n  $nick.innerText = `@${r.opts.replyTo.nick}`\n  $nick.onclick = () => {\n    r.comment.getActions().goToReplyComment()\n  }\n\n  // Comment content\n  let replyContent = marked(r.opts.replyTo.content)\n  if (r.opts.replyTo.is_collapsed) replyContent = `[${$t('collapsed')}]`\n  r.$replyTo.querySelector<HTMLElement>('.atk-content')!.innerHTML = replyContent\n\n  // Mount the replyTo element\n  r.$body.prepend(r.$replyTo)\n}\n","import * as Utils from '../../lib/utils'\nimport type Render from '../render'\nimport $t from '@/i18n'\n\n/**\n * 待审核状态界面\n */\nexport default function renderPending(r: Render) {\n  if (!r.data.is_pending) return\n\n  const pendingEl = Utils.createElement(`<div class=\"atk-pending\">${$t('pendingMsg')}</div>`)\n  r.$body.prepend(pendingEl)\n}\n","import ActionBtn from '../components/action-btn'\nimport * as Utils from '../lib/utils'\nimport * as Ui from '../lib/ui'\n\nimport * as HeightLimit from './height-limit'\nimport CommentHTML from './comment.html?raw'\nimport loadRenders from './renders'\nimport type { CommentNode } from '.'\n\nexport default class Render {\n  public comment: CommentNode\n\n  public get data() {\n    return this.comment.getData()\n  }\n  public get opts() {\n    return this.comment.getOpts()\n  }\n\n  public $el!: HTMLElement\n  public $main!: HTMLElement\n  public $header!: HTMLElement\n  public $headerNick!: HTMLElement\n  public $headerBadgeWrap!: HTMLElement\n  public $body!: HTMLElement\n  public $content!: HTMLElement\n  public $childrenWrap!: HTMLElement | null\n  public $actions!: HTMLElement\n  public voteBtnUp?: ActionBtn\n  public voteBtnDown?: ActionBtn\n\n  public $replyTo?: HTMLElement // 回复评论内容 (平铺下显示)\n  public $replyAt?: HTMLElement // 回复 AT（层级嵌套下显示）\n\n  public constructor(comment: CommentNode) {\n    this.comment = comment\n  }\n\n  /**\n   * Render the comment ui\n   *\n   * If comment data is updated, call this method to re-render the comment ui.\n   * The method will be called multiple times, so it should be idempotent.\n   *\n   * Renders may add event listeners to the comment ui, so it should be called only once or override the original.\n   * Please be aware of the memory leak caused by the event listener.\n   */\n  public render() {\n    // init ui elements\n    this.$el = Utils.createElement(CommentHTML)\n\n    this.$main = this.$el.querySelector('.atk-main')!\n    this.$header = this.$el.querySelector('.atk-header')!\n    this.$body = this.$el.querySelector('.atk-body')!\n    this.$content = this.$body.querySelector('.atk-content')!\n    this.$actions = this.$el.querySelector('.atk-actions')!\n\n    this.$el.setAttribute('id', `atk-comment-${this.data.id}`)\n\n    // call all renders\n    loadRenders(this)\n\n    // append children wrap if exists\n    if (this.$childrenWrap) {\n      this.$main.append(this.$childrenWrap)\n    }\n\n    return this.$el\n  }\n\n  /** 内容限高检测 */\n  public checkHeightLimit() {\n    const conf = this.opts.heightLimit\n    if (!conf || !conf.content || !conf.children) return // 关闭限高\n\n    const contentMaxH = conf.content\n    const childrenMaxH = conf.children\n\n    HeightLimit.check(\n      {\n        afterExpandBtnClick: () => {\n          // 子评论数仅有 1，直接取消限高\n          const children = this.comment.getChildren()\n          if (children.length === 1)\n            HeightLimit.disposeHeightLimit(children[0].getRender().$content)\n        },\n        scrollable: conf.scrollable,\n      },\n      [\n        // 评论内容限高\n        { el: this.$content, max: contentMaxH, imgCheck: true },\n        { el: this.$replyTo, max: contentMaxH, imgCheck: true },\n        // 子评论区域限高（仅嵌套模式）\n        { el: this.$childrenWrap, max: childrenMaxH, imgCheck: false },\n      ],\n    )\n  }\n\n  /** 子评论区域移除限高 */\n  public heightLimitRemoveForChildren() {\n    if (!this.$childrenWrap) return\n    HeightLimit.disposeHeightLimit(this.$childrenWrap)\n  }\n\n  /** 渐出动画 */\n  playFadeAnim() {\n    Ui.playFadeInAnim(this.comment.getRender().$el)\n  }\n\n  /** 渐出动画 · 评论内容区域 */\n  playFadeAnimForBody() {\n    Ui.playFadeInAnim(this.comment.getRender().$body)\n  }\n\n  /** Perform the flash animation */\n  playFlashAnim() {\n    // Make sure the class is removed\n    this.$el.classList.remove('atk-flash-once')\n    window.setTimeout(() => {\n      // Add the class to perform the animation\n      this.$el.classList.add('atk-flash-once')\n    }, 150)\n  }\n\n  /** 获取子评论 Wrap */\n  public getChildrenWrap() {\n    if (!this.$childrenWrap) {\n      // if not exists, create a new one\n      this.$childrenWrap = Utils.createElement('<div class=\"atk-comment-children\"></div>')\n      this.$main.append(this.$childrenWrap)\n    }\n    return this.$childrenWrap\n  }\n\n  /** 设置已读 */\n  public setUnread(val: boolean) {\n    if (val) this.$el.classList.add('atk-unread')\n    else this.$el.classList.remove('atk-unread')\n  }\n\n  /** 设置为可点击的评论 */\n  public setOpenable(val: boolean) {\n    if (val) this.$el.classList.add('atk-openable')\n    else this.$el.classList.remove('atk-openable')\n  }\n\n  /** 设置点击评论打开置顶 URL */\n  public setOpenURL(url: string) {\n    this.setOpenable(true)\n    this.$el.onclick = (evt) => {\n      evt.stopPropagation()\n      window.open(url)\n    }\n  }\n\n  /** 设置点击评论时的操作 */\n  public setOpenAction(action: () => void) {\n    this.setOpenable(true)\n    this.$el.onclick = (evt) => {\n      evt.stopPropagation()\n      action()\n    }\n  }\n}\n","export default \"<div class=\\\"atk-comment-wrap\\\">\\n  <div class=\\\"atk-comment\\\">\\n    <div class=\\\"atk-avatar\\\"></div>\\n    <div class=\\\"atk-main\\\">\\n      <div class=\\\"atk-header\\\">\\n        <span class=\\\"atk-item atk-nick\\\"></span>\\n        <span class=\\\"atk-badge-wrap\\\"></span>\\n        <span class=\\\"atk-item atk-date\\\"></span>\\n      </div>\\n      <div class=\\\"atk-body\\\">\\n        <div class=\\\"atk-content\\\"></div>\\n      </div>\\n      <div class=\\\"atk-footer\\\">\\n        <div class=\\\"atk-actions\\\"></div>\\n      </div>\\n    </div>\\n  </div>\\n</div>\\n\"","import type { CommentNode } from '.'\nimport ActionBtn from '@/components/action-btn'\nimport $t from '@/i18n'\n\nexport default class CommentActions {\n  private comment: CommentNode\n\n  private get data() {\n    return this.comment.getData()\n  }\n  private get opts() {\n    return this.comment.getOpts()\n  }\n  private getApi() {\n    return this.comment.getOpts().getApi()\n  }\n\n  public constructor(comment: CommentNode) {\n    this.comment = comment\n  }\n\n  /** 投票操作 */\n  public vote(choice: 'up' | 'down') {\n    const actionBtn =\n      choice === 'up' ? this.comment.getRender().voteBtnUp : this.comment.getRender().voteBtnDown\n\n    this.getApi()\n      .votes.createVote('comment', this.data.id, choice, {\n        ...this.getApi().getUserFields(),\n      })\n      .then((res) => {\n        this.data.vote_up = res.data.up\n        this.data.vote_down = res.data.down\n        this.comment.getRender().voteBtnUp?.updateText()\n        this.comment.getRender().voteBtnDown?.updateText()\n      })\n      .catch((err) => {\n        actionBtn?.setError($t('voteFail'))\n        console.error(err)\n      })\n  }\n\n  /** 管理员 - 评论状态修改 */\n  public adminEdit(type: 'collapsed' | 'pending' | 'pinned', btnElem: ActionBtn) {\n    if (btnElem.isLoading) return // 若正在修改中\n\n    btnElem.setLoading(true, `${$t('editing')}...`)\n\n    // 克隆并修改当前数据\n    const modify = { ...this.data }\n    if (type === 'collapsed') {\n      modify.is_collapsed = !modify.is_collapsed\n    } else if (type === 'pending') {\n      modify.is_pending = !modify.is_pending\n    } else if (type === 'pinned') {\n      modify.is_pinned = !modify.is_pinned\n    }\n\n    this.getApi()\n      .comments.updateComment(this.data.id, {\n        ...modify,\n      })\n      .then((res) => {\n        btnElem.setLoading(false)\n\n        // 刷新当前 Comment UI\n        this.comment.setData(res.data)\n      })\n      .catch((err) => {\n        console.error(err)\n        btnElem.setError($t('editFail'))\n      })\n  }\n\n  /** 管理员 - 评论删除 */\n  public adminDelete(btnElem: ActionBtn) {\n    if (btnElem.isLoading) return // 若正在删除中\n\n    btnElem.setLoading(true, `${$t('deleting')}...`)\n    this.getApi()\n      .comments.deleteComment(this.data.id)\n      .then(() => {\n        btnElem.setLoading(false)\n        if (this.opts.onDelete) this.opts.onDelete(this.comment)\n      })\n      .catch((e) => {\n        console.error(e)\n        btnElem.setError($t('deleteFail'))\n      })\n  }\n\n  /** 快速跳转到该评论 */\n  public goToReplyComment() {\n    const origHash = window.location.hash\n    const modifyHash = `#atk-comment-${this.data.rid}`\n\n    window.location.hash = modifyHash\n    if (modifyHash === origHash) window.dispatchEvent(new Event('hashchange')) // 强制触发事件\n  }\n}\n","import type { Api } from '../api'\nimport * as Ui from '../lib/ui'\nimport * as Utils from '../lib/utils'\nimport marked from '../lib/marked'\nimport UADetect from '../lib/detect'\nimport CommentUI from './render'\nimport CommentActions from './actions'\nimport $t from '@/i18n'\nimport type { CommentData, Config, Context } from '@/types'\n\nexport interface CommentOptions {\n  // Hooks\n  onAfterRender?: () => void\n  onDelete?: (c: CommentNode) => void\n\n  /** The comment being replied to (linked comment) */\n  replyTo?: CommentData\n\n  // Referenced from ArtalkConfig\n  flatMode: boolean\n  vote: boolean\n  voteDown: boolean\n  uaBadge: boolean\n  nestMax: number\n  gravatar: Config['gravatar']\n  heightLimit: Config['heightLimit']\n  avatarURLBuilder: Config['avatarURLBuilder']\n  scrollRelativeTo: Config['scrollRelativeTo']\n  dateFormatter: Config['dateFormatter']\n\n  // TODO: Move to plugin folder and remove from core\n  getApi: () => Api\n  replyComment: Context['replyComment']\n  editComment: Context['editComment']\n}\n\nexport default class CommentNode {\n  $el?: HTMLElement\n\n  private renderInstance: CommentUI\n  private actionInstance: CommentActions\n\n  private data: CommentData\n  private opts: CommentOptions\n\n  private parent: CommentNode | null\n  private children: CommentNode[] = []\n\n  private nestCurt: number // 当前嵌套层数\n\n  constructor(data: CommentData, opts: CommentOptions) {\n    this.opts = opts\n    this.data = { ...data }\n    this.data.date = this.data.date.replace(/-/g, '/') // 解决 Safari 日期解析 NaN 问题\n\n    this.parent = null\n    this.nestCurt = 1 // 现在已嵌套 n 层\n\n    this.actionInstance = new CommentActions(this)\n    this.renderInstance = new CommentUI(this)\n  }\n\n  /** 渲染 UI */\n  public render() {\n    const newEl = this.renderInstance.render()\n\n    if (this.$el) this.$el.replaceWith(newEl)\n    this.$el = newEl\n    // Please be aware of the memory leak, the $el may be replaced multiple times.\n    // If somewhere else has a reference to the old $el, it will cause a memory leak.\n    // So it's limited to use the $el reference by `getEl()`.\n    // The `getEl()` will always return the latest $el.\n\n    if (this.opts.onAfterRender) this.opts.onAfterRender()\n  }\n\n  /** 获取评论操作实例对象 */\n  public getActions() {\n    return this.actionInstance\n  }\n\n  /** 获取评论渲染器实例对象 */\n  public getRender() {\n    return this.renderInstance\n  }\n\n  /** 获取评论数据 */\n  public getData() {\n    return this.data\n  }\n\n  /** 设置数据 */\n  public setData(data: CommentData) {\n    this.data = data\n\n    this.render()\n    this.getRender().playFadeAnimForBody()\n  }\n\n  /** 获取父评论 */\n  public getParent() {\n    return this.parent\n  }\n\n  /** 获取所有子评论 */\n  public getChildren() {\n    return this.children\n  }\n\n  /** 获取当前嵌套层数 */\n  public getNestCurt() {\n    return this.nestCurt\n  }\n\n  /** 判断是否为根评论 */\n  public getIsRoot() {\n    return this.data.rid === 0\n  }\n\n  /** 获取评论 ID */\n  public getID() {\n    return this.data.id\n  }\n\n  /** 置入子评论 */\n  public putChild(childNode: CommentNode, insertMode: 'append' | 'prepend' = 'append') {\n    childNode.parent = this\n    childNode.nestCurt = this.nestCurt + 1 // 嵌套层数 +1\n    this.children.push(childNode)\n\n    const $childrenWrap = this.getChildrenWrapEl()\n    const $childComment = childNode.getEl()\n    if (insertMode === 'append') $childrenWrap.append($childComment)\n    else if (insertMode === 'prepend') $childrenWrap.prepend($childComment)\n\n    childNode.getRender().playFadeAnim()\n    childNode.getRender().checkHeightLimit() // 内容限高\n  }\n\n  /** 获取存放子评论的元素对象 */\n  public getChildrenWrapEl(): HTMLElement {\n    // console.log(this.nestCurt)\n    if (this.nestCurt >= this.opts.nestMax) {\n      return this.parent!.getChildrenWrapEl()\n    }\n    return this.getRender().getChildrenWrap()\n  }\n\n  /** 获取所有父评论 */\n  public getParents() {\n    const flattenParents: CommentNode[] = []\n    let parent = this.parent\n    while (parent) {\n      flattenParents.push(parent)\n      parent = parent.getParent()\n    }\n    return flattenParents\n  }\n\n  /**\n   * Get the element of the comment\n   *\n   * The `getEl()` will always return the latest $el after calling `render()`.\n   * Please be aware of the memory leak if you use the $el reference directly.\n   */\n  public getEl() {\n    if (!this.$el) throw new Error('comment element not initialized before `getEl()`')\n    return this.$el\n  }\n\n  /**\n   * Focus on the comment\n   *\n   * Scroll to the comment and perform flash animation\n   */\n  focus() {\n    if (!this.$el) throw new Error('comment element not initialized before `focus()`')\n\n    // 若父评论存在 “子评论部分” 限高，取消限高\n    this.getParents().forEach((p) => {\n      p.getRender().heightLimitRemoveForChildren()\n    })\n\n    // Scroll to comment\n    this.scrollIntoView()\n\n    // Perform flash animation\n    this.getRender().playFlashAnim()\n  }\n\n  scrollIntoView() {\n    this.$el &&\n      Ui.scrollIntoView(this.$el, false, this.opts.scrollRelativeTo && this.opts.scrollRelativeTo())\n  }\n\n  /**\n   * Remove the comment node\n   */\n  remove() {\n    this.$el?.remove()\n  }\n\n  /** 获取 Gravatar 头像 URL */\n  public getGravatarURL() {\n    return Utils.getGravatarURL({\n      mirror: this.opts.gravatar.mirror,\n      params: this.opts.gravatar.params,\n      emailHash: this.data.email_encrypted,\n    })\n  }\n\n  /** 获取评论 markdown 解析后的内容 */\n  public getContentMarked() {\n    return marked(this.data.content)\n  }\n\n  /** 获取格式化后的日期 */\n  public getDateFormatted() {\n    const date = new Date(this.data.date)\n    return this.opts.dateFormatter?.(date) || Utils.timeAgo(date, $t)\n  }\n\n  /** 获取用户 UserAgent 信息 */\n  public getUserUA() {\n    const info = UADetect(this.data.ua)\n    return {\n      browser: `${info.browser} ${info.version}`,\n      os: `${info.os} ${info.osVersion}`,\n    }\n  }\n\n  /** 获取配置 */\n  public getOpts() {\n    return this.opts\n  }\n}\n","function Detect(userAgent?: string) {\n  const win = (window as any) || {}\n  const nav = navigator || {}\n\n  const u = String(userAgent || nav.userAgent)\n  const dest = {\n    os: '',\n    osVersion: '',\n    engine: '',\n    browser: '',\n    device: '',\n    language: '',\n    version: ''\n  }\n\n  // 内核\n  const engineMatch = {\n    Trident: u.includes('Trident') || u.includes('NET CLR'),\n    Presto: u.includes('Presto'),\n    WebKit: u.includes('AppleWebKit'),\n    Gecko: u.includes('Gecko/')\n  }\n\n  // 浏览器\n  const browserMatch = {\n    Safari: u.includes('Safari'),\n    Chrome: u.includes('Chrome') || u.includes('CriOS'),\n    IE: u.includes('MSIE') || u.includes('Trident'),\n    Edge: u.includes('Edge') || u.includes('Edg'),\n    Firefox: u.includes('Firefox') || u.includes('FxiOS'),\n    'Firefox Focus': u.includes('Focus'),\n    Chromium: u.includes('Chromium'),\n    Opera: u.includes('Opera') || u.includes('OPR'),\n    Vivaldi: u.includes('Vivaldi'),\n    Yandex: u.includes('YaBrowser'),\n    Kindle: u.includes('Kindle') || u.includes('Silk/'),\n    360: u.includes('360EE') || u.includes('360SE'),\n    UC: u.includes('UC') || u.includes(' UBrowser'),\n    QQBrowser: u.includes('QQBrowser'),\n    QQ: u.includes('QQ/'),\n    Baidu: u.includes('Baidu') || u.includes('BIDUBrowser'),\n    Maxthon: u.includes('Maxthon'),\n    Sogou: u.includes('MetaSr') || u.includes('Sogou'),\n    LBBROWSER: u.includes('LBBROWSER'),\n    '2345Explorer': u.includes('2345Explorer'),\n    TheWorld: u.includes('TheWorld'),\n    MIUI: u.includes('MiuiBrowser'),\n    Quark: u.includes('Quark'),\n    Qiyu: u.includes('Qiyu'),\n    Wechat: u.includes('MicroMessenger'),\n    Taobao: u.includes('AliApp(TB'),\n    Alipay: u.includes('AliApp(AP'),\n    Weibo: u.includes('Weibo'),\n    Douban: u.includes('com.douban.frodo'),\n    Suning: u.includes('SNEBUY-APP'),\n    iQiYi: u.includes('IqiyiApp'),\n  }\n\n  // 系统或平台\n  const osMatch = {\n    Windows: u.includes('Windows'),\n    Linux: u.includes('Linux') || u.includes('X11'),\n    'macOS': u.includes('Macintosh'),\n    Android: u.includes('Android') || u.includes('Adr'),\n    Ubuntu: u.includes('Ubuntu'),\n    FreeBSD: u.includes('FreeBSD'),\n    Debian: u.includes('Debian'),\n    'Windows Phone': u.includes('IEMobile') || u.includes('Windows Phone'),\n    BlackBerry: u.includes('BlackBerry') || u.includes('RIM'),\n    MeeGo: u.includes('MeeGo'),\n    Symbian: u.includes('Symbian'),\n    iOS: u.includes('like Mac OS X'),\n    'Chrome OS': u.includes('CrOS'),\n    WebOS: u.includes('hpwOS'),\n  }\n\n  // 设备\n  const deviceMatch = {\n    Mobile: u.includes('Mobi') || u.includes('iPh') || u.includes('480'),\n    Tablet: u.includes('Tablet') || u.includes('Pad') || u.includes('Nexus 7')\n  }\n\n  // 修正\n  if (deviceMatch.Mobile) {\n    deviceMatch.Mobile = !(u.includes('iPad'))\n  } else if (browserMatch.Chrome && u.includes('Edg')) {\n    // Chrome 内核的 Edge\n    browserMatch.Chrome = false\n    browserMatch.Edge = true\n  } else if (win.showModalDialog && win.chrome) {\n    browserMatch.Chrome = false\n    browserMatch['360'] = true\n  }\n\n  // 默认设备\n  dest.device = 'PC'\n\n  // 语言\n  dest.language = (() => {\n    const g = ((nav as any).browserLanguage || nav.language)\n    const arr = g.split('-')\n    if (arr[1]) arr[1] = arr[1].toUpperCase()\n    return arr.join('_')\n  })()\n\n  // 应用判断数据\n  const hash = {\n    engine: engineMatch,\n    browser: browserMatch,\n    os: osMatch,\n    device: deviceMatch,\n  }\n  Object.entries(hash).forEach(([type, match]) => {\n    Object.entries(match).forEach(([name, result]) => {\n      if (result === true) dest[type] = name\n    })\n  })\n\n  // 系统版本信息\n  const osVersion = {\n    Windows: () => {\n      const v = u.replace(/^.*Windows NT ([\\d.]+);.*$/, '$1')\n      const wvHash = {\n        '6.4': '10',\n        '6.3': '8.1',\n        '6.2': '8',\n        '6.1': '7',\n        '6.0': 'Vista',\n        '5.2': 'XP',\n        '5.1': 'XP',\n        '5.0': '2000',\n        '10.0': '10',\n        '11.0': '11' // 自定的，不是微软官方的判断方法\n      }\n      return wvHash[v] || v\n    },\n    Android: () => u.replace(/^.*Android ([\\d.]+);.*$/, '$1'),\n    iOS: () => u.replace(/^.*OS ([\\d_]+) like.*$/, '$1').replace(/_/g, '.'),\n    Debian: () => u.replace(/^.*Debian\\/([\\d.]+).*$/, '$1'),\n    'Windows Phone': () => u.replace(/^.*Windows Phone( OS)? ([\\d.]+);.*$/, '$2'),\n    'macOS': () => u.replace(/^.*Mac OS X ([\\d_]+).*$/, '$1').replace(/_/g, '.'),\n    WebOS: () => u.replace(/^.*hpwOS\\/([\\d.]+);.*$/, '$1')\n  }\n\n  dest.osVersion = ''\n  if (osVersion[dest.os]) {\n    dest.osVersion = osVersion[dest.os]()\n    if (dest.osVersion === u) {\n      dest.osVersion = ''\n    }\n  }\n\n  // 浏览器版本信息\n  const version = {\n    Safari: () => u.replace(/^.*Version\\/([\\d.]+).*$/, '$1'),\n    Chrome: () => u.replace(/^.*Chrome\\/([\\d.]+).*$/, '$1').replace(/^.*CriOS\\/([\\d.]+).*$/, '$1'),\n    IE: () => u.replace(/^.*MSIE ([\\d.]+).*$/, '$1').replace(/^.*rv:([\\d.]+).*$/, '$1'),\n    Edge: () => u.replace(/^.*(Edge|Edg|Edg[A-Z]{1})\\/([\\d.]+).*$/, '$2'),\n    Firefox: () => u.replace(/^.*Firefox\\/([\\d.]+).*$/, '$1').replace(/^.*FxiOS\\/([\\d.]+).*$/, '$1'),\n    'Firefox Focus': () => u.replace(/^.*Focus\\/([\\d.]+).*$/, '$1'),\n    Chromium: () => u.replace(/^.*Chromium\\/([\\d.]+).*$/, '$1'),\n    Opera: () => u.replace(/^.*Opera\\/([\\d.]+).*$/, '$1').replace(/^.*OPR\\/([\\d.]+).*$/, '$1'),\n    Vivaldi: () => u.replace(/^.*Vivaldi\\/([\\d.]+).*$/, '$1'),\n    Yandex: () => u.replace(/^.*YaBrowser\\/([\\d.]+).*$/, '$1'),\n    Kindle: () => u.replace(/^.*Version\\/([\\d.]+).*$/, '$1'),\n    Maxthon: () => u.replace(/^.*Maxthon\\/([\\d.]+).*$/, '$1'),\n    QQBrowser: () => u.replace(/^.*QQBrowser\\/([\\d.]+).*$/, '$1'),\n    QQ: () => u.replace(/^.*QQ\\/([\\d.]+).*$/, '$1'),\n    Baidu: () => u.replace(/^.*BIDUBrowser[\\s/]([\\d.]+).*$/, '$1'),\n    UC: () => u.replace(/^.*UC?Browser\\/([\\d.]+).*$/, '$1'),\n    Sogou: () => u.replace(/^.*SE ([\\d.X]+).*$/, '$1').replace(/^.*SogouMobileBrowser\\/([\\d.]+).*$/, '$1'),\n    '2345Explorer': () => u.replace(/^.*2345Explorer\\/([\\d.]+).*$/, '$1'),\n    TheWorld: () => u.replace(/^.*TheWorld ([\\d.]+).*$/, '$1'),\n    MIUI: () => u.replace(/^.*MiuiBrowser\\/([\\d.]+).*$/, '$1'),\n    Quark: () => u.replace(/^.*Quark\\/([\\d.]+).*$/, '$1'),\n    Qiyu: () => u.replace(/^.*Qiyu\\/([\\d.]+).*$/, '$1'),\n    Wechat: () => u.replace(/^.*MicroMessenger\\/([\\d.]+).*$/, '$1'),\n    Taobao: () => u.replace(/^.*AliApp\\(TB\\/([\\d.]+).*$/, '$1'),\n    Alipay: () => u.replace(/^.*AliApp\\(AP\\/([\\d.]+).*$/, '$1'),\n    Weibo: () => u.replace(/^.*weibo__([\\d.]+).*$/, '$1'),\n    Douban: () => u.replace(/^.*com.douban.frodo\\/([\\d.]+).*$/, '$1'),\n    Suning: () => u.replace(/^.*SNEBUY-APP([\\d.]+).*$/, '$1'),\n    iQiYi: () => u.replace(/^.*IqiyiVersion\\/([\\d.]+).*$/, '$1'),\n  }\n\n  dest.version = ''\n  if (version[dest.browser]) {\n    dest.version = version[dest.browser]()\n    if (dest.version === u) {\n      dest.version = ''\n    }\n  }\n\n  // 简化版本号\n  /* if (_this.osVersion.indexOf('.')) {\n    _this.osVersion = _this.osVersion.substring(0, _this.osVersion.indexOf('.'))\n  } */\n  if (dest.version.indexOf('.')) {\n    dest.version = dest.version.substring(0, dest.version.indexOf('.'))\n  }\n\n  // 修正\n  if (dest.os === 'iOS' && u.includes('iPad')) {\n    dest.os = 'iPadOS'\n  } else if (dest.browser === 'Edge' && !u.includes('Edg')) {\n    dest.engine = 'EdgeHTML'\n  } else if (dest.browser === 'MIUI') {\n    dest.os = 'Android'\n  } else if (dest.browser === 'Chrome' && Number(dest.version) > 27) {\n    dest.engine = 'Blink'\n  } else if (dest.browser === 'Opera' && Number(dest.version) > 12) {\n    dest.engine = 'Blink'\n  } else if (dest.browser === 'Yandex') {\n    dest.engine = 'Blink'\n  } else if (dest.browser === undefined) {\n    dest.browser = 'Unknow App'\n  }\n\n  return dest\n}\n\nexport default Detect\n","import * as Utils from '../lib/utils'\n\nexport interface ReadMoreBtnOptions {\n  /** 回调函数 */\n  onClick: (offset: number) => void\n\n  pageSize: number\n\n  text?: string\n}\n\n/**\n * 阅读更多按钮\n */\nexport default class ReadMoreBtn {\n  public opts: ReadMoreBtnOptions\n  public $el: HTMLElement\n  private $loading: HTMLElement\n  private $text: HTMLElement\n  private offset: number = 0\n  private total: number = 0\n  private origText: string = 'Load More'\n\n  /** 是否有更多内容 */\n  get hasMore() {\n    return this.total > this.offset + this.opts.pageSize\n  }\n\n  public constructor(opts: ReadMoreBtnOptions) {\n    this.opts = opts\n    this.origText = this.opts.text || this.origText\n\n    this.$el = Utils.createElement(\n      `<div class=\"atk-list-read-more\" style=\"display: none;\">\n      <div class=\"atk-list-read-more-inner\">\n        <div class=\"atk-loading-icon\" style=\"display: none;\"></div>\n        <span class=\"atk-text\">${this.origText}</span>\n      </div>\n    </div>`,\n    )\n\n    this.$loading = this.$el.querySelector<HTMLElement>('.atk-loading-icon')!\n    this.$text = this.$el.querySelector<HTMLElement>('.atk-text')!\n\n    this.$el.onclick = () => {\n      this.click()\n    }\n  }\n\n  click() {\n    if (this.hasMore) this.opts.onClick(this.offset + this.opts.pageSize)\n    this.checkDisabled()\n  }\n\n  /** 显示 */\n  show() {\n    this.$el.style.display = ''\n  }\n\n  /** 隐藏 */\n  hide() {\n    this.$el.style.display = 'none'\n  }\n\n  /** 加载 */\n  setLoading(isLoading: boolean) {\n    this.$loading.style.display = isLoading ? '' : 'none'\n    this.$text.style.display = isLoading ? 'none' : ''\n  }\n\n  /** 错误提示 */\n  showErr(errMsg: string) {\n    this.setLoading(false)\n\n    this.$text.innerText = errMsg\n    this.$el.classList.add('atk-err')\n    window.setTimeout(() => {\n      this.$text.innerText = this.origText\n      this.$el.classList.remove('atk-err')\n    }, 2000) // 2s后错误提示复原\n  }\n\n  /** 更新数据 */\n  public update(offset: number, total: number) {\n    this.offset = offset\n    this.total = total\n\n    this.checkDisabled()\n  }\n\n  public checkDisabled() {\n    if (this.hasMore) this.show()\n    else this.hide()\n  }\n}\n","import type { Paginator, IPgHolderOpt } from '.'\nimport ReadMoreBtn from '@/components/read-more-btn'\nimport $t from '@/i18n'\n\n/**\n * 阅读更多形式的分页\n */\nexport default class ReadMorePaginator implements Paginator {\n  private instance!: ReadMoreBtn\n  private onReachedBottom: (() => void) | null = null\n  private opt!: IPgHolderOpt\n\n  create(opt: IPgHolderOpt) {\n    this.opt = opt\n\n    this.instance = new ReadMoreBtn({\n      pageSize: opt.pageSize,\n      onClick: async (o) => {\n        opt.getData().fetchComments({\n          offset: o,\n        })\n      },\n      text: $t('loadMore'),\n    })\n\n    // 滚动到底部自动加载\n    if (opt.readMoreAutoLoad) {\n      this.onReachedBottom = () => {\n        if (!this.instance.hasMore || this.opt.getData().getLoading()) return\n        this.instance.click()\n      }\n      this.opt.getEvents().on('list-reach-bottom', this.onReachedBottom)\n    }\n\n    return this.instance.$el\n  }\n\n  setLoading(val: boolean) {\n    this.instance.setLoading(val)\n  }\n\n  update(offset: number, total: number) {\n    this.instance.update(offset, total)\n  }\n\n  showErr(msg: string) {\n    this.instance.showErr(msg)\n  }\n\n  next() {\n    this.instance.click()\n  }\n\n  getHasMore(): boolean {\n    return this.instance.hasMore\n  }\n\n  getIsClearComments(params: { offset?: number }): boolean {\n    return params.offset === 0\n  }\n\n  dispose(): void {\n    this.onReachedBottom && this.opt.getEvents().off('list-reach-bottom', this.onReachedBottom)\n    this.instance.$el.remove()\n  }\n}\n","import * as Utils from '../lib/utils'\nimport * as Ui from '../lib/ui'\n\nexport interface PaginationOptions {\n  /** 每页条数 */\n  pageSize: number\n\n  /** 回调函数 */\n  onChange: (offset: number) => void\n}\n\nexport default class Pagination {\n  private opts: PaginationOptions\n  public total: number\n  public $el: HTMLElement\n  public $input: HTMLInputElement\n  public inputTimer?: number\n  public $prevBtn: HTMLElement\n  public $nextBtn: HTMLElement\n\n  public page: number = 1\n  get pageSize(): number {\n    return this.opts.pageSize\n  }\n  get offset(): number {\n    return this.pageSize * (this.page - 1)\n  }\n  get maxPage(): number {\n    return Math.ceil(this.total / this.pageSize)\n  }\n\n  public constructor(total: number, opts: PaginationOptions) {\n    this.total = total\n    this.opts = opts\n\n    this.$el = Utils.createElement(\n      `<div class=\"atk-pagination-wrap\">\n        <div class=\"atk-pagination\">\n          <div class=\"atk-btn atk-btn-prev\" aria-label=\"Previous page\">\n            <svg stroke=\"currentColor\" fill=\"currentColor\" stroke-width=\"0\" viewBox=\"0 0 512 512\" height=\"14px\" width=\"14px\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M217.9 256L345 129c9.4-9.4 9.4-24.6 0-33.9-9.4-9.4-24.6-9.3-34 0L167 239c-9.1 9.1-9.3 23.7-.7 33.1L310.9 417c4.7 4.7 10.9 7 17 7s12.3-2.3 17-7c9.4-9.4 9.4-24.6 0-33.9L217.9 256z\"></path></svg>\n          </div>\n          <input type=\"text\" class=\"atk-input\" aria-label=\"Enter the number of page\" />\n          <div class=\"atk-btn atk-btn-next\" aria-label=\"Next page\">\n            <svg stroke=\"currentColor\" fill=\"currentColor\" stroke-width=\"0\" viewBox=\"0 0 512 512\" height=\"14px\" width=\"14px\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M294.1 256L167 129c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.3 34 0L345 239c9.1 9.1 9.3 23.7.7 33.1L201.1 417c-4.7 4.7-10.9 7-17 7s-12.3-2.3-17-7c-9.4-9.4-9.4-24.6 0-33.9l127-127.1z\"></path></svg>\n          </div>\n        </div>\n      </div>`,\n    )\n    this.$input = this.$el.querySelector('.atk-input')!\n    this.$input.value = `${this.page}`\n\n    this.$input.oninput = () => this.input()\n    this.$input.onkeydown = (e) => this.keydown(e)\n\n    this.$prevBtn = this.$el.querySelector('.atk-btn-prev')!\n    this.$nextBtn = this.$el.querySelector('.atk-btn-next')!\n\n    this.$prevBtn.onclick = () => this.prev()\n    this.$nextBtn.onclick = () => this.next()\n\n    this.checkDisabled()\n  }\n\n  public update(offset: number, total: number) {\n    this.page = Math.ceil(offset / this.pageSize) + 1\n    this.total = total\n\n    this.setInput(this.page)\n    this.checkDisabled()\n  }\n\n  public setInput(page: number) {\n    this.$input.value = `${page}`\n  }\n\n  public input(now: boolean = false) {\n    window.clearTimeout(this.inputTimer)\n\n    const value = this.$input.value.trim()\n\n    const modify = () => {\n      if (value === '') {\n        this.setInput(this.page)\n        return\n      }\n      let page = Number(value)\n      if (Number.isNaN(page)) {\n        this.setInput(this.page)\n        return\n      }\n      if (page < 1) {\n        this.setInput(this.page)\n        return\n      }\n      if (page > this.maxPage) {\n        this.setInput(this.maxPage)\n        page = this.maxPage\n      }\n      this.change(page)\n    }\n\n    // 延迟 800ms 执行\n    if (!now) this.inputTimer = window.setTimeout(() => modify(), 800)\n    else modify()\n  }\n\n  public prev() {\n    const page = this.page - 1\n    if (page < 1) {\n      return\n    }\n    this.change(page)\n  }\n\n  public next() {\n    const page = this.page + 1\n    if (page > this.maxPage) {\n      return\n    }\n    this.change(page)\n  }\n\n  public getHasMore() {\n    return this.page + 1 <= this.maxPage\n  }\n\n  public change(page: number) {\n    this.page = page\n    this.opts.onChange(this.offset)\n    this.setInput(page)\n    this.checkDisabled()\n  }\n\n  public checkDisabled() {\n    if (this.page + 1 > this.maxPage) {\n      this.$nextBtn.classList.add('atk-disabled')\n    } else {\n      this.$nextBtn.classList.remove('atk-disabled')\n    }\n\n    if (this.page - 1 < 1) {\n      this.$prevBtn.classList.add('atk-disabled')\n    } else {\n      this.$prevBtn.classList.remove('atk-disabled')\n    }\n  }\n\n  public keydown(e: KeyboardEvent) {\n    const keyCode = e.keyCode || e.which\n\n    if (keyCode === 38) {\n      // 上键\n      const page = Number(this.$input.value) + 1\n      if (page > this.maxPage) {\n        return\n      }\n      this.setInput(page)\n      this.input()\n    } else if (keyCode === 40) {\n      // 下键\n      const page = Number(this.$input.value) - 1\n      if (page < 1) {\n        return\n      }\n      this.setInput(page)\n      this.input()\n    } else if (keyCode === 13) {\n      // 回车\n      this.input(true)\n    }\n  }\n\n  /** 加载 */\n  setLoading(isLoading: boolean) {\n    if (isLoading) Ui.showLoading(this.$el)\n    else Ui.hideLoading(this.$el)\n  }\n}\n","import type { Paginator, IPgHolderOpt } from '.'\nimport PaginationComponent from '@/components/pagination'\n\n/**\n * 翻页形式的分页\n */\nexport default class UpDownPaginator implements Paginator {\n  private instance!: PaginationComponent\n\n  create(opt: IPgHolderOpt) {\n    this.instance = new PaginationComponent(opt.total, {\n      pageSize: opt.pageSize,\n      onChange: async (o) => {\n        opt.resetEditorState()\n\n        opt.getData().fetchComments({\n          offset: o,\n          onSuccess: () => {\n            opt.onListGotoFirst?.()\n          },\n        })\n      },\n    })\n\n    return this.instance.$el\n  }\n\n  setLoading(val: boolean) {\n    this.instance.setLoading(val)\n  }\n\n  update(offset: number, total: number) {\n    this.instance.update(offset, total)\n  }\n\n  next() {\n    this.instance.next()\n  }\n\n  getHasMore(): boolean {\n    return this.instance.getHasMore()\n  }\n\n  getIsClearComments(): boolean {\n    return true\n  }\n\n  dispose(): void {\n    this.instance.$el.remove()\n  }\n}\n","import type { ListOptions } from './list'\nimport { Paginator } from './paginator'\nimport ReadMorePaginator from './paginator/read-more'\nimport UpDownPaginator from './paginator/up-down'\nimport $t from '@/i18n'\nimport type { Config, List, ListLastFetchData } from '@/types'\n\nfunction createPaginatorByConf(conf: Pick<Config, 'pagination'>): Paginator {\n  if (conf.pagination.readMore) return new ReadMorePaginator()\n  return new UpDownPaginator()\n}\n\nfunction getPageDataByLastData(last: ListLastFetchData | undefined): {\n  offset: number\n  total: number\n} {\n  const r = { offset: 0, total: 0 }\n  if (!last) return r\n\n  r.offset = last.params.offset\n  if (last.data) r.total = last.params.flatMode ? last.data.count : last.data.roots_count\n\n  return r\n}\n\nexport interface PaginatorInitOptions extends ListOptions {\n  getList: () => List\n}\n\nexport const initListPaginatorFunc = (opts: PaginatorInitOptions) => {\n  let paginator: Paginator | null = null\n\n  // Init paginator when conf loaded\n  opts.getConf().watchConf(['pagination', 'locale'], (conf) => {\n    const list = opts.getList()\n    const data = opts.getData()\n\n    if (paginator) paginator.dispose() // if had been init, dispose it\n\n    // create paginator instance\n    paginator = createPaginatorByConf(conf)\n\n    // create paginator dom\n    const { offset, total } = getPageDataByLastData(data.getListLastFetch())\n    const $paginator = paginator.create({\n      pageSize: conf.pagination.pageSize,\n      total,\n\n      readMoreAutoLoad: conf.pagination.autoLoad,\n\n      ...opts,\n    })\n\n    // mount paginator dom\n    list.getCommentsWrapEl().after($paginator)\n\n    // update paginator info\n    paginator?.update(offset, total)\n  })\n\n  // When list loaded\n  opts.getEvents().on('list-loaded', (comments) => {\n    // update paginator info\n    const { offset, total } = getPageDataByLastData(opts.getData().getListLastFetch())\n    paginator?.update(offset, total)\n  })\n\n  // When list fetch\n  opts.getEvents().on('list-fetch', (params) => {\n    // if clear comments when fetch new page data\n    if (opts.getData().getComments().length > 0 && paginator?.getIsClearComments(params)) {\n      opts.getData().clearComments()\n    }\n  })\n\n  // When list error\n  opts.getEvents().on('list-failed', () => {\n    paginator?.showErr?.($t('loadFail'))\n  })\n\n  // loading\n  opts.getEvents().on('list-fetch', (params) => {\n    paginator?.setLoading(true)\n  })\n  opts.getEvents().on('list-fetched', ({ params }) => {\n    paginator?.setLoading(false)\n  })\n}\n","import ListHTML from './list.html?raw'\nimport { ListLayout } from './layout'\nimport { createCommentNode } from './comment'\nimport { initListPaginatorFunc } from './page'\nimport type { CommentData, EventManager, DataManager, ConfigManager, List as IList } from '@/types'\nimport * as Utils from '@/lib/utils'\nimport { CommentNode } from '@/comment'\nimport type { Api } from '@/api'\n\nexport interface ListOptions {\n  getApi: () => Api\n  getEvents: () => EventManager\n  getConf: () => ConfigManager\n  getData: () => DataManager\n\n  replyComment: (c: CommentData, $el: HTMLElement) => void\n  editComment: (c: CommentData, $el: HTMLElement) => void\n  resetEditorState: () => void\n  onListGotoFirst?: () => void\n}\n\nexport class List implements IList {\n  private opts: ListOptions\n  private $el: HTMLElement\n  getEl() {\n    return this.$el\n  }\n\n  private $commentsWrap: HTMLElement\n  getCommentsWrapEl() {\n    return this.$commentsWrap\n  }\n\n  private commentNodes: CommentNode[] = []\n  getCommentNodes() {\n    return this.commentNodes\n  }\n\n  constructor(opts: ListOptions) {\n    this.opts = opts\n\n    // Init base element\n    this.$el = Utils.createElement(ListHTML)\n    this.$commentsWrap = this.$el.querySelector('.atk-list-comments-wrap')!\n\n    // Init paginator\n    initListPaginatorFunc({\n      getList: () => this,\n      ...opts,\n    })\n\n    // Bind events\n    this.initCrudEvents()\n  }\n\n  getLayout({ forceFlatMode }: { forceFlatMode?: boolean } = {}) {\n    return new ListLayout({\n      $commentsWrap: this.$commentsWrap,\n      nestSortBy: this.opts.getConf().get().nestSort,\n      nestMax: this.opts.getConf().get().nestMax,\n      flatMode:\n        typeof forceFlatMode === 'boolean'\n          ? forceFlatMode\n          : (this.opts.getConf().get().flatMode as boolean),\n      // flatMode must be boolean because it had been handled when Artalk.init\n      createCommentNode: (d, r) => {\n        const node = createCommentNode({ forceFlatMode, ...this.opts }, d, r)\n        this.commentNodes.push(node) // store node instance\n        return node\n      },\n      findCommentNode: (id) => this.commentNodes.find((c) => c.getID() === id),\n    })\n  }\n\n  private initCrudEvents() {\n    this.opts.getEvents().on('list-load', (comments) => {\n      // 导入数据\n      this.getLayout().import(comments)\n    })\n\n    this.opts.getEvents().on('list-loaded', (comments) => {\n      if (comments.length === 0) {\n        this.commentNodes = []\n        this.$commentsWrap.innerHTML = ''\n      }\n    })\n\n    // When comment insert\n    this.opts.getEvents().on('comment-inserted', (comment) => {\n      const replyComment = comment.rid\n        ? this.commentNodes.find((c) => c.getID() === comment.rid)?.getData()\n        : undefined\n      this.getLayout().insert(comment, replyComment)\n    })\n\n    // When comment delete\n    this.opts.getEvents().on('comment-deleted', (comment) => {\n      const node = this.commentNodes.find((c) => c.getID() === comment.id)\n      if (!node) {\n        console.error(`comment node id=${comment.id} not found`)\n        return\n      }\n      node.remove()\n      this.commentNodes = this.commentNodes.filter((c) => c.getID() !== comment.id)\n      // TODO: remove child nodes\n    })\n\n    // When comment update\n    this.opts.getEvents().on('comment-updated', (comment) => {\n      const node = this.commentNodes.find((c) => c.getID() === comment.id)\n      node && node.setData(comment)\n    })\n  }\n}\n","export default \"<div class=\\\"atk-list\\\">\\n  <div class=\\\"atk-list-header\\\">\\n    <div class=\\\"atk-comment-count\\\">\\n      <div class=\\\"atk-text\\\"></div>\\n    </div>\\n    <div class=\\\"atk-right-action\\\">\\n      <span data-action=\\\"admin-close-comment\\\" class=\\\"atk-hide\\\" atk-only-admin-show></span>\\n      <span data-action=\\\"open-sidebar\\\" class=\\\"atk-hide atk-on\\\">\\n        <span class=\\\"atk-unread-badge\\\" style=\\\"display: none\\\"></span>\\n        <div class=\\\"atk-text\\\"></div>\\n      </span>\\n    </div>\\n  </div>\\n  <div class=\\\"atk-list-body\\\">\\n    <div class=\\\"atk-list-comments-wrap\\\"></div>\\n  </div>\\n  <div class=\\\"atk-list-footer\\\">\\n    <div class=\\\"atk-copyright\\\"></div>\\n  </div>\\n</div>\\n\"","import type { ConfigManager, EventManager, CommentData, DataManager } from '@/types'\nimport { CommentNode } from '@/comment'\nimport type { Api } from '@/api'\n\ninterface CreateCommentNodeOptions {\n  getApi: () => Api\n  getEvents: () => EventManager\n  getData: () => DataManager\n  getConf: () => ConfigManager\n  replyComment: (c: CommentData, $el: HTMLElement) => void\n  editComment: (c: CommentData, $el: HTMLElement) => void\n  forceFlatMode?: boolean\n}\n\nexport function createCommentNode(\n  opts: CreateCommentNodeOptions,\n  comment: CommentData,\n  replyComment?: CommentData,\n): CommentNode {\n  const conf = opts.getConf().get()\n\n  const instance = new CommentNode(comment, {\n    onAfterRender: () => {\n      opts.getEvents().trigger('comment-rendered', instance)\n    },\n    onDelete: (c: CommentNode) => {\n      opts.getData().deleteComment(c.getID())\n    },\n\n    replyTo: replyComment,\n\n    // TODO simplify reference\n    flatMode:\n      typeof opts?.forceFlatMode === 'boolean' ? opts?.forceFlatMode : (conf.flatMode as boolean),\n    gravatar: conf.gravatar,\n    nestMax: conf.nestMax,\n    heightLimit: conf.heightLimit,\n    avatarURLBuilder: conf.avatarURLBuilder,\n    scrollRelativeTo: conf.scrollRelativeTo,\n    vote: conf.vote,\n    voteDown: conf.voteDown,\n    uaBadge: conf.uaBadge,\n    dateFormatter: conf.dateFormatter,\n\n    // TODO: move to plugin folder and remove from core\n    getApi: opts.getApi,\n    replyComment: opts.replyComment,\n    editComment: opts.editComment,\n  })\n\n  // Render comment\n  instance.render()\n\n  return instance\n}\n","import SidebarHTML from './sidebar-layer.html?raw'\nimport type {\n  SidebarShowPayload,\n  ConfigManager,\n  UserManager,\n  LayerManager,\n  Layer,\n  SidebarLayer as ISidebarLayer,\n  CheckerManager,\n} from '@/types'\nimport * as Utils from '@/lib/utils'\nimport * as Ui from '@/lib/ui'\nimport type { Api } from '@/api'\n\nexport interface SidebarLayerOptions {\n  onShow?: () => void\n  onHide?: () => void\n\n  getCheckers: () => CheckerManager\n  getApi: () => Api\n  getConf: () => ConfigManager\n  getUser: () => UserManager\n  getLayers: () => LayerManager\n}\n\nexport class SidebarLayer implements ISidebarLayer {\n  private opts: SidebarLayerOptions\n  public $el: HTMLElement\n  public layer?: Layer\n  public $header: HTMLElement\n  public $closeBtn: HTMLElement\n  public $iframeWrap: HTMLElement\n  public $iframe?: HTMLIFrameElement\n\n  constructor(opts: SidebarLayerOptions) {\n    this.opts = opts\n    this.$el = Utils.createElement(SidebarHTML)\n    this.$header = this.$el.querySelector('.atk-sidebar-header')!\n    this.$closeBtn = this.$header.querySelector('.atk-sidebar-close')!\n    this.$iframeWrap = this.$el.querySelector('.atk-sidebar-iframe-wrap')!\n\n    this.$closeBtn.onclick = () => {\n      this.hide()\n    }\n  }\n\n  public async onUserChanged() {\n    this.refreshWhenShow = true\n  }\n\n  /** Refresh iFrame when show */\n  private refreshWhenShow = true\n\n  /** Animation timer */\n  private animTimer?: any = undefined\n\n  /** 显示 */\n  public async show(conf: SidebarShowPayload = {}) {\n    this.$el.style.transform = '' // 动画清除，防止二次打开失效\n\n    // init layer\n    this.initLayer()\n    this.layer!.show()\n\n    // init iframe\n    if (this.refreshWhenShow) {\n      this.refreshWhenShow = false\n      this.$iframeWrap.innerHTML = ''\n      this.$iframe = this.createIframe(conf.view)\n      this.$iframeWrap.append(this.$iframe)\n    } else {\n      // Sync Dark Mode (reload iframe if not match)\n      const $iframe = this.$iframe!\n      const iFrameSrc = $iframe.src\n      if (this.getDarkMode() !== iFrameSrc.includes('&darkMode=1')) {\n        this.iframeLoad(\n          $iframe,\n          iFrameSrc.replace(/&darkMode=\\d/, `&darkMode=${Number(this.getDarkMode())}`),\n        )\n      }\n    }\n\n    // 管理员身份验证 (若身份失效，弹出验证窗口)\n    this.authCheck({\n      onSuccess: () => this.show(conf), // retry show after auth check\n    })\n\n    // 执行滑动显示动画\n    this.animTimer = setTimeout(() => {\n      this.animTimer = undefined\n      this.$el.style.transform = 'translate(0, 0)'\n\n      this.opts.onShow?.()\n    }, 100)\n  }\n\n  /** 隐藏 */\n  public hide() {\n    this.layer?.hide()\n  }\n\n  // --------------------------------------------------\n\n  private async authCheck(opts: { onSuccess: () => void }) {\n    const data = (\n      await this.opts.getApi().user.getUserStatus({\n        ...this.opts.getApi().getUserFields(),\n      })\n    ).data\n    if (data.is_admin && !data.is_login) {\n      this.refreshWhenShow = true\n\n      // show checker layer\n      this.opts.getCheckers().checkAdmin({\n        onSuccess: () => {\n          setTimeout(() => {\n            opts.onSuccess()\n          }, 500)\n        },\n        onCancel: () => {\n          this.hide()\n        },\n      })\n\n      // hide sidebar layer\n      this.hide()\n    }\n  }\n\n  private initLayer() {\n    if (this.layer) return\n\n    this.layer = this.opts.getLayers().create('sidebar', this.$el)\n    this.layer.setOnAfterHide(() => {\n      // interrupt animation\n      this.animTimer && clearTimeout(this.animTimer)\n\n      // perform transform\n      this.$el.style.transform = ''\n\n      // trigger event\n      this.opts.onHide?.()\n    })\n  }\n\n  private createIframe(view?: string) {\n    const $iframe = Utils.createElement<HTMLIFrameElement>(\n      '<iframe referrerpolicy=\"strict-origin-when-cross-origin\"></iframe>',\n    )\n\n    // 准备 Iframe 参数\n    const baseURL = import.meta.env.DEV\n      ? 'http://localhost:23367/'\n      : Utils.getURLBasedOnApi({\n          base: this.opts.getConf().get().server,\n          path: '/sidebar/',\n        })\n\n    const query: any = {\n      pageKey: this.opts.getConf().get().pageKey,\n      site: this.opts.getConf().get().site || '',\n      user: JSON.stringify(this.opts.getUser().getData()),\n      time: +new Date(),\n    }\n\n    if (view) query.view = view\n    query.darkMode = this.getDarkMode() ? '1' : '0'\n\n    const urlParams = new URLSearchParams(query)\n    this.iframeLoad($iframe, `${baseURL}?${urlParams.toString()}`)\n\n    return $iframe\n  }\n\n  private getDarkMode() {\n    return this.opts.getConf().get().darkMode === 'auto'\n      ? window.matchMedia('(prefers-color-scheme: dark)').matches\n      : this.opts.getConf().get().darkMode\n  }\n\n  private iframeLoad($iframe: HTMLIFrameElement, src: string) {\n    $iframe.src = src\n\n    // 加载动画\n    Ui.showLoading(this.$iframeWrap)\n    $iframe.onload = () => {\n      Ui.hideLoading(this.$iframeWrap)\n    }\n  }\n}\n","export default \"<div class=\\\"atk-sidebar-layer\\\">\\n  <div class=\\\"atk-sidebar-inner\\\">\\n    <div class=\\\"atk-sidebar-header\\\">\\n      <div class=\\\"atk-sidebar-close\\\">\\n        <i class=\\\"atk-icon atk-icon-close-slim\\\"></i>\\n      </div>\\n    </div>\\n    <div class=\\\"atk-sidebar-iframe-wrap\\\"></div>\\n  </div>\\n</div>\\n\"","import type { ArtalkPlugin } from '@/types'\nimport { SidebarLayer } from '@/layer/sidebar-layer'\n\nexport const SidebarService: ArtalkPlugin = (ctx) => {\n  ctx.provide(\n    'sidebar',\n    (events, data, editor, checkers, api, config, user, layers) => {\n      const sidebarLayer = new SidebarLayer({\n        onShow: () => {\n          setTimeout(() => {\n            data.updateNotifies([])\n          }, 0)\n\n          events.trigger('sidebar-show')\n        },\n        onHide: () => {\n          // prevent comment box from being swallowed\n          editor.resetState()\n\n          events.trigger('sidebar-hide')\n        },\n        getCheckers: () => checkers,\n        getApi: () => api,\n        getConf: () => config,\n        getUser: () => user,\n        getLayers: () => layers,\n      })\n\n      ctx.on('user-changed', () => {\n        sidebarLayer?.onUserChanged()\n      })\n\n      return sidebarLayer\n    },\n    ['events', 'data', 'editor', 'checkers', 'api', 'config', 'user', 'layers'] as const,\n  )\n}\n","import { Markdown } from './markdown'\nimport { EditorKit } from './editor-kit'\nimport { ListPlugins } from './list'\nimport { Notifies } from './notifies'\nimport { PvCountWidget } from './stat'\nimport { VersionCheck } from './version-check'\nimport { AdminOnlyElem } from './admin-only-elem'\nimport { DarkMode } from './dark-mode'\nimport { PageVoteWidget } from './page-vote'\nimport { Services } from '@/services'\nimport type { ArtalkPlugin } from '@/types'\n\nexport const DefaultPlugins: ArtalkPlugin[] = [\n  ...Services,\n  Markdown,\n  EditorKit,\n  AdminOnlyElem,\n  ...ListPlugins,\n  Notifies,\n  PvCountWidget,\n  VersionCheck,\n  DarkMode,\n  PageVoteWidget,\n]\n","import { ApiService } from './api'\nimport { UserService } from './user'\nimport { CheckersService } from './checkers'\nimport { EditorService } from './editor'\nimport { I18nService } from './i18n'\nimport { DataService } from './data'\nimport { LayersService } from './layer'\nimport { ListService } from './list'\nimport { SidebarService } from './sidebar'\nimport { ArtalkPlugin } from '@/types'\n\nexport const Services: Set<ArtalkPlugin> = new Set([\n  DataService,\n  ApiService,\n  I18nService,\n  UserService,\n  EditorService,\n  ListService,\n  CheckersService,\n  LayersService,\n  SidebarService,\n])\n","import { ArtalkPlugin } from '@/types'\nimport { DataManager } from '@/data'\n\nexport const DataService: ArtalkPlugin = (ctx) => {\n  ctx.provide('data', (events) => new DataManager(events), ['events'] as const)\n\n  ctx.on('mounted', () => {\n    // Load comment list immediately after mounting\n    if (ctx.getConf().fetchCommentsOnInit) {\n      ctx.getData().fetchComments({ offset: 0 })\n    }\n  })\n}\n","export interface ApiHandlerPayload {\n  need_captcha: { img_data?: string; iframe?: string }\n  need_login: object\n  need_auth_login: object\n}\n\ntype PayloadKey = keyof ApiHandlerPayload\n\nexport interface ApiHandler<T extends PayloadKey = PayloadKey> {\n  action: T\n  handler: (data: ApiHandlerPayload[T]) => Promise<void>\n}\n\nexport interface ApiHandlers {\n  add: <T extends PayloadKey>(\n    action: T,\n    handler: (data: ApiHandlerPayload[T]) => Promise<void>,\n  ) => void\n  remove: (action: PayloadKey) => void\n  get: () => ApiHandler[]\n}\n\nexport function createApiHandlers(): ApiHandlers {\n  const handlers: ApiHandler[] = []\n  return {\n    add: (action, handler) => {\n      handlers.push({ action, handler })\n    },\n    remove: (action) => {\n      const index = handlers.findIndex((h) => h.action === action)\n      if (index !== -1) handlers.splice(index, 1)\n    },\n    get: () => handlers,\n  }\n}\n","import * as I18n from '@/i18n'\nimport type { ArtalkPlugin } from '@/types'\n\nexport const I18nService: ArtalkPlugin = (ctx) => {\n  ctx.watchConf(['locale'], (conf) => {\n    I18n.setLocale(conf.locale)\n  })\n}\n","import type { ArtalkPlugin } from '@/types'\nimport { UserManager } from '@/lib/user'\n\nexport const UserService: ArtalkPlugin = (ctx) => {\n  ctx.provide(\n    'user',\n    () => {\n      return new UserManager({\n        onUserChanged: (data) => {\n          ctx.trigger('user-changed', data)\n        },\n      })\n    },\n    [] as const,\n  )\n}\n","import type { ArtalkPlugin } from '@/types'\nimport { Editor } from '@/editor/editor'\n\nexport const EditorService: ArtalkPlugin = (ctx) => {\n  ctx.provide(\n    'editor',\n    (events, config) => {\n      const editor = new Editor({\n        getEvents: () => events,\n        getConf: () => config,\n      })\n      ctx.getEl().appendChild(editor.getEl())\n      return editor\n    },\n    ['events', 'config'] as const,\n  )\n}\n","import type { ArtalkPlugin } from '@/types'\nimport { List } from '@/list/list'\n\nexport const ListService: ArtalkPlugin = (ctx) => {\n  ctx.provide(\n    'list',\n    (api, events, config, data, editor) => {\n      const list = new List({\n        getApi: () => api,\n        getEvents: () => events,\n        getConf: () => config,\n        getData: () => data,\n\n        replyComment: (c, $el) => editor.setReplyComment(c, $el),\n        editComment: (c, $el) => editor.setEditComment(c, $el),\n        resetEditorState: () => editor.resetState(),\n        onListGotoFirst: () => ctx.listGotoFirst(),\n      })\n      ctx.getEl().appendChild(list.getEl())\n      return list\n    },\n    ['api', 'events', 'config', 'data', 'editor'] as const,\n  )\n}\n","import type { ArtalkPlugin } from '@/types'\nimport { LayerManager } from '@/layer'\n\nexport const LayersService: ArtalkPlugin = (ctx) => {\n  ctx.provide('layers', () => {\n    const layerManager = new LayerManager()\n    document.body.appendChild(layerManager.getEl())\n    ctx.on('unmounted', () => {\n      layerManager?.destroy()\n    })\n    return layerManager\n  })\n}\n","import type { ArtalkPlugin } from '@/types'\nimport * as marked from '@/lib/marked'\n\nexport const Markdown: ArtalkPlugin = (ctx) => {\n  ctx.watchConf(['imgLazyLoad', 'markedOptions'], (conf) => {\n    marked.initMarked({\n      markedOptions: conf.markedOptions,\n      imgLazyLoad: conf.imgLazyLoad,\n    })\n  })\n\n  ctx.watchConf(['markedReplacers'], (conf) => {\n    conf.markedReplacers && marked.setReplacers(conf.markedReplacers)\n  })\n}\n","import type { ArtalkPlugin } from '@/types'\n\nexport const AdminOnlyElem: ArtalkPlugin = (ctx) => {\n  const user = ctx.inject('user')\n\n  const scanApply = () => {\n    applyAdminOnlyEls(\n      user.getData().is_admin,\n      getAdminOnlyEls({\n        $root: ctx.getEl(),\n      }),\n    )\n  }\n\n  ctx.on('list-loaded', () => {\n    scanApply()\n  })\n\n  ctx.on('user-changed', (user) => {\n    scanApply()\n  })\n}\n\nfunction getAdminOnlyEls(opts: { $root: HTMLElement }): HTMLElement[] {\n  const els: HTMLElement[] = []\n\n  // elements in $root\n  opts.$root\n    .querySelectorAll<HTMLElement>(`[atk-only-admin-show]`)\n    .forEach((item) => els.push(item))\n\n  // TODO: provide a Artalk.conf hook to set whitelist of admin-only elements,\n  // and move following code to that hook (move into @artalk/artalk-sidebar)\n\n  // elements in sidebar\n  const $sidebarEl = document.querySelector<HTMLElement>('.atk-sidebar')\n  if ($sidebarEl)\n    $sidebarEl\n      .querySelectorAll<HTMLElement>(`[atk-only-admin-show]`)\n      .forEach((item) => els.push(item))\n\n  return els\n}\n\nfunction applyAdminOnlyEls(isAdmin: boolean, els: HTMLElement[]) {\n  els.forEach(($item: HTMLElement) => {\n    if (isAdmin) $item.classList.remove('atk-hide')\n    else $item.classList.add('atk-hide')\n  })\n}\n","import type { ArtalkPlugin } from '@/types'\n\nexport const Notifies: ArtalkPlugin = (ctx) => {\n  ctx.on('list-fetch', (params) => {\n    if (params.offset !== 0) return\n\n    const user = ctx.getApi().getUserFields()\n    if (!user) return\n\n    // Fetch all unread notifies\n    ctx\n      .getApi()\n      .notifies.getNotifies(user)\n      .then((res) => {\n        ctx.getData().updateNotifies(res.data.notifies)\n      })\n  })\n}\n","import { handleConfFormServer } from './config'\nimport { DefaultPlugins } from './plugins'\nimport { mergeDeep } from './lib/merge-deep'\nimport { MountError } from './plugins/mount-error'\nimport type { ConfigPartial, ArtalkPlugin, Context } from '@/types'\n\n/**\n * Global Plugins for all Artalk instances\n */\nexport const GlobalPlugins: Set<ArtalkPlugin> = new Set([...DefaultPlugins])\n\n/**\n * Plugin options for plugin initialization\n */\nexport const PluginOptions: WeakMap<ArtalkPlugin, any> = new WeakMap()\n\nexport async function mount(localConf: ConfigPartial, ctx: Context) {\n  const loaded = new Set<ArtalkPlugin>()\n  const loadPlugins = (plugins: Set<ArtalkPlugin>) => {\n    plugins.forEach((plugin) => {\n      if (typeof plugin !== 'function') return\n      if (loaded.has(plugin)) return\n      plugin(ctx, PluginOptions.get(plugin))\n      loaded.add(plugin)\n    })\n  }\n\n  // Load local plugins\n  loadPlugins(GlobalPlugins)\n\n  // Get conf from server\n  const { data } = await ctx\n    .getApi()\n    .conf.conf()\n    .catch((err) => {\n      MountError(ctx, { err, onRetry: () => mount(localConf, ctx) })\n      throw err\n    })\n\n  // Merge remote and local config\n  let conf: ConfigPartial = {\n    ...localConf,\n    apiVersion: data.version?.version, // server version info\n  }\n\n  const remoteConf = handleConfFormServer(data.frontend_conf || {})\n  conf = conf.preferRemoteConf ? mergeDeep(conf, remoteConf) : mergeDeep(remoteConf, conf)\n\n  // Apply local + remote conf\n  ctx.updateConf(conf)\n\n  // Load remote plugins\n  conf.pluginURLs &&\n    (await loadNetworkPlugins(conf.pluginURLs, ctx.getConf().server)\n      .then((plugins) => {\n        loadPlugins(plugins)\n      })\n      .catch((err) => {\n        console.error('Failed to load plugin', err)\n      }))\n}\n\n/**\n * Dynamically load plugins from Network\n */\nasync function loadNetworkPlugins(scripts: string[], apiBase: string): Promise<Set<ArtalkPlugin>> {\n  const networkPlugins = new Set<ArtalkPlugin>()\n  if (!scripts || !Array.isArray(scripts)) return networkPlugins\n\n  const tasks: Promise<void>[] = []\n\n  scripts.forEach((url) => {\n    // check url valid\n    if (!/^(http|https):\\/\\//.test(url))\n      url = `${apiBase.replace(/\\/$/, '')}/${url.replace(/^\\//, '')}`\n\n    tasks.push(\n      new Promise<void>((resolve) => {\n        // check if loaded\n        if (document.querySelector(`script[src=\"${url}\"]`)) {\n          resolve()\n          return\n        }\n\n        // load script\n        const script = document.createElement('script')\n        script.src = url\n        document.head.appendChild(script)\n        script.onload = () => resolve()\n        script.onerror = (err) => {\n          console.error('[artalk] Failed to load plugin', err)\n          resolve()\n        }\n      }),\n    )\n  })\n\n  await Promise.all(tasks)\n\n  // Read ArtalkPlugins object from window\n  Object.values(window.ArtalkPlugins || {}).forEach((plugin) => {\n    if (typeof plugin === 'function') networkPlugins.add(plugin)\n  })\n\n  return networkPlugins\n}\n","import { showErrorDialog } from '@/components/error-dialog'\nimport type { ArtalkPlugin } from '@/types'\n\nexport interface MountErrorOptions {\n  err?: { data?: { err_no_site?: boolean }; msg: string }\n  onRetry?: () => void\n}\n\nexport const MountError: ArtalkPlugin<MountErrorOptions> = (ctx, opts = {}) => {\n  const list = ctx.inject('list')\n  const user = ctx.inject('user')\n  const conf = ctx.inject('config')\n\n  const err = opts.err\n  if (!err) throw new Error('MountError: `err` is required')\n\n  let sidebarOpenView = ''\n\n  // if response err_no_site, modify the sidebar open view to create site\n  if (err.data?.err_no_site) {\n    const viewLoadParam = {\n      create_name: conf.get().site,\n      create_urls: `${window.location.protocol}//${window.location.host}`,\n    }\n    sidebarOpenView = `sites|${JSON.stringify(viewLoadParam)}`\n  }\n\n  showErrorDialog({\n    $err: list.getEl(),\n    errMsg: err.msg || String(err),\n    errData: err.data,\n    retryFn: () => opts.onRetry?.(),\n    onOpenSidebar: user.getData().is_admin\n      ? () =>\n          ctx.showSidebar({\n            view: sidebarOpenView as any,\n          })\n      : undefined, // only show open sidebar button when user is admin\n  })\n}\n","import type { Config, EventManager } from '@/types'\n\nexport function watchConf<T extends (keyof Config)[]>({\n  keys,\n  effect,\n  getConf,\n  getEvents,\n}: {\n  keys: T\n  effect: (conf: Pick<Config, T[number]>) => void\n  getConf: () => Config\n  getEvents: () => EventManager\n}): void {\n  const deepEqual = (a: any, b: any) => JSON.stringify(a) === JSON.stringify(b)\n  const val = () => {\n    const conf = getConf()\n    const res: any = {}\n    keys.forEach((key) => {\n      res[key] = conf[key]\n    })\n    return res\n  }\n  let lastVal: any = null\n  const handler = () => {\n    const newVal = val()\n    const isDiff = lastVal == null || !deepEqual(lastVal, newVal)\n    // only trigger when specific keys changed\n    if (isDiff) {\n      lastVal = newVal\n      effect(newVal)\n    }\n  }\n  getEvents().on('mounted', handler)\n  getEvents().on('updated', handler)\n}\n","import './style/main.scss'\n\nimport Context from './context'\nimport { handelCustomConf, convertApiOptions, getRootEl } from './config'\nimport * as Stat from './plugins/stat'\nimport { Api } from './api'\nimport { GlobalPlugins, PluginOptions, mount } from './mount'\nimport { ConfigService } from './services/config'\nimport { EventsService } from './services/events'\nimport type {\n  ConfigPartial,\n  EventPayloadMap,\n  ArtalkPlugin,\n  Context as IContext,\n  EventHandler,\n} from '@/types'\n\n/**\n * Artalk\n *\n * @see https://artalk.js.org\n */\nexport default class Artalk {\n  public ctx: IContext\n\n  constructor(conf: ConfigPartial) {\n    // Init Root Element\n    const $root = getRootEl(conf)\n    $root.classList.add('artalk')\n    $root.innerHTML = ''\n    conf.darkMode == true && $root.classList.add('atk-dark-mode')\n\n    // Init Context\n    const ctx = (this.ctx = new Context($root))\n\n    // Init required services\n    ;(() => {\n      // Init event manager\n      EventsService(ctx)\n\n      // Init config service\n      ConfigService(ctx)\n    })()\n\n    // Apply local conf first\n    ctx.updateConf(conf)\n\n    // Trigger created event\n    ctx.trigger('created')\n\n    // Load plugins and remote config, then mount Artalk\n    const mountArtalk = async () => {\n      await mount(conf, ctx)\n\n      // Trigger mounted event\n      ctx.trigger('mounted')\n    }\n\n    if (import.meta.env.DEV && import.meta.env.VITEST) {\n      global.devMountArtalk = mountArtalk\n    } else {\n      mountArtalk()\n    }\n  }\n\n  /** Get the config of Artalk */\n  public getConf() {\n    return this.ctx.getConf()\n  }\n\n  /** Get the root element of Artalk */\n  public getEl() {\n    return this.ctx.getEl()\n  }\n\n  /** Update config of Artalk */\n  public update(conf: ConfigPartial) {\n    this.ctx.updateConf(conf)\n  }\n\n  /** Reload comment list of Artalk */\n  public reload() {\n    this.ctx.reload()\n  }\n\n  /** Destroy instance of Artalk */\n  public destroy() {\n    this.ctx.destroy()\n  }\n\n  /** Add an event listener */\n  public on<K extends keyof EventPayloadMap>(name: K, handler: EventHandler<EventPayloadMap[K]>) {\n    this.ctx.on(name, handler)\n  }\n\n  /** Remove an event listener */\n  public off<K extends keyof EventPayloadMap>(name: K, handler: EventHandler<EventPayloadMap[K]>) {\n    this.ctx.off(name, handler)\n  }\n\n  /** Trigger an event */\n  public trigger<K extends keyof EventPayloadMap>(name: K, payload?: EventPayloadMap[K]) {\n    this.ctx.trigger(name, payload)\n  }\n\n  /** Set dark mode */\n  public setDarkMode(darkMode: boolean) {\n    this.ctx.setDarkMode(darkMode)\n  }\n\n  // ===========================\n  //       Static Members\n  // ===========================\n\n  /** Init Artalk */\n  public static init(conf: ConfigPartial): Artalk {\n    return new Artalk(conf)\n  }\n\n  /** Use plugin, the plugin will be used when Artalk.init */\n  public static use<T = any>(plugin: ArtalkPlugin<T>, options?: T) {\n    GlobalPlugins.add(plugin)\n    PluginOptions.set(plugin, options)\n  }\n\n  /** Load count widget */\n  public static loadCountWidget(c: ConfigPartial) {\n    const conf = handelCustomConf(c, true)\n\n    Stat.initCountWidget({\n      getApi: () => new Api(convertApiOptions(conf)),\n      siteName: conf.site,\n      countEl: conf.countEl,\n      pvEl: conf.pvEl,\n      pageKeyAttr: conf.statPageKeyAttr,\n      pvAdd: false,\n    })\n  }\n\n  // ===========================\n  //         Deprecated\n  // ===========================\n  /** @deprecated Please use `getEl()` instead */\n  public get $root() {\n    console.warn('`$root` is deprecated, please use `getEl()` instead')\n    return this.getEl()\n  }\n\n  /** @description Please use `getConf()` instead */\n  public get conf() {\n    console.warn('`conf` is deprecated, please use `getConf()` instead')\n    return this.getConf()\n  }\n}\n","import type { ArtalkPlugin, EventPayloadMap } from '@/types'\nimport { EventManager } from '@/lib/event-manager'\n\nexport const EventsService: ArtalkPlugin = (ctx) => {\n  ctx.provide('events', () => new EventManager<EventPayloadMap>())\n}\n","import type { Config, ArtalkPlugin, ConfigManager } from '@/types'\nimport { mergeDeep } from '@/lib/merge-deep'\nimport { handelCustomConf } from '@/config'\nimport { watchConf } from '@/lib/watch-conf'\n\nexport const ConfigService: ArtalkPlugin = (ctx) => {\n  let conf: Config = handelCustomConf({}, true)\n\n  ctx.provide(\n    'config',\n    (events) => {\n      let mounted = false\n      events.on('mounted', () => (mounted = true))\n      const instance: ConfigManager = {\n        watchConf: (keys, effect) => {\n          watchConf({\n            keys,\n            effect,\n            getConf: () => conf,\n            getEvents: () => events,\n          })\n        },\n        get: () => conf,\n        update: (config) => {\n          conf = mergeDeep<Config>(conf, handelCustomConf(config, false))\n          mounted && events.trigger('updated', conf)\n        },\n      }\n      return instance\n    },\n    ['events'] as const,\n  )\n}\n","import Artalk from './artalk'\nimport type * as ArtalkType from './types'\nimport { Defaults } from './defaults'\n\nexport type * from './types'\nexport { ArtalkType, Defaults }\n\nexport default Artalk\n\n// Manually expose the static methods from the Artalk class.\n// Directly exporting static methods from a class is not supported,\n// and it's important to maintain consistency in the library's API.\n// To ensure compatibility across different environments, such as CommonJS and browser IIFE,\n// this approach allows us to use `Artalk.init()` instead of `Artalk.default.init()`.\nexport const init = Artalk.init\nexport const use = Artalk.use\nexport const loadCountWidget = Artalk.loadCountWidget\n"],"names":["createElement","htmlStr","div","document","innerHTML","trim","firstElementChild","htmlEncode","str","temp","innerText","getQueryParam","name","match","RegExp","exec","window","location","search","decodeURIComponent","replace","getOffset","el","relativeTo","getOffsetRecursive","element","rect","getBoundingClientRect","scrollLeft","pageXOffset","documentElement","scrollTop","pageYOffset","top","left","elOffset","relativeToOffset","padWithZeros","vNumber","width","numAsString","toString","length","timeAgo","date","$t","n","oldTime","getTime","diffValue","Date","days","Math","floor","leave1","hours","leave2","minutes","leave3","seconds","round","vDay","getDate","vMonth","getMonth","getFullYear","dateFormat","error","console","getCorrectUserAgent","__async","this","uaRaw","navigator","userAgent","userAgentData","getHighEntropyValues","uaData","uaGot","err","majorPlatformVersion","Number","platformVersion","split","platform","isValidURL","urlRaw","url","URL","_","protocol","getURLBasedOnApi","opts","baseURL","base","path","en","placeholder","noComment","send","signIn","signUp","save","nick","email","link","emoticon","preview","uploadImage","uploadFail","commentFail","restoredMsg","onlyAdminCanReply","uploadLoginMsg","counter","sortLatest","sortOldest","sortBest","sortAuthor","openComment","closeComment","listLoadFailMsg","listRetry","loadMore","admin","reply","voteUp","voteDown","voteFail","readMore","actionConfirm","collapse","collapsed","collapsedMsg","expand","approved","pending","pendingMsg","edit","editCancel","delete","deleteConfirm","pin","unpin","now","adminCheck","captchaCheck","confirm","cancel","msgCenter","ctrlCenter","userProfile","noAccountPrompt","haveAccountPrompt","forgetPassword","resetPassword","changePassword","confirmPassword","passwordMismatch","verificationCode","verifySend","verifyResend","waitSeconds","emailVerified","password","username","nextStep","skipVerify","logoutConfirm","accountMergeNotice","accountMergeSelectOne","accountMergeConfirm","dismiss","merge","client","server","loading","loadFail","editing","editFail","deleting","deleteFail","reqGot","reqAborted","updateMsg","currentVersion","ignore","open","openName","GLOBAL_LOCALES_KEY","internal","findLocaleSet","lang","p1","p2","toLowerCase","toUpperCase","LocaleConf","LocaleDict","t","key","args","token","Utils.htmlEncode","escapes","unescapes","rescaped","runescaped","escapeHtmlChar","unescapeHtmlChar","escapeHtml","text","String","unescapeHtml","html","options","she","encode","escape","decode","unescape","version","assignment_1","assignment","result","item","stack","Array","prototype","slice","call","arguments","shift","hasOwnProperty","Object","lowercase","string","asKey","accumulator","toMap_1","list","reduce","attributes","uris","require$$0","elements","voids","he","require$$1","require$$3","rstart","rend","rattrs","rtag","rtagend","require$$2","assign","parser","handler","chars","lastItem","createStack","last","parsePart","substr","index","indexOf","comment","substring","test","parseEdge","parseEndTag","parseStartTag","same","regex","tag","tagName","rest","unary","attrs","low","u","doubleQuotedValue","singleQuotedValue","unquotedValue","push","start","i","pos","end","sanitizer","buffer","context","o","ignoring","allowedTags","filter","out","keys","forEach","value","classesOk","allowedClasses","attrsOk","allowedAttributes","lkey","className","join","colon","questionmark","hash","allowedSchemes","some","matches","scheme","testUrl","unignore","transformText","depth","reset","defaults","a","iframe","img","insane","strict","configuration","insaneOptions","code","span","node","reg","class","style","sanitize","content","exports","createCommonjsModule","fn","module","index$1","line","source","block","defaultColors","toComment","cm","input","ref","colors","cache","re","m","word","color","factory","renderCode","hanabi","getRenderer","renderer","marked","Renderer","markedLinkRenderer","markedCodeRenderer","image","markedImageRenderer","orgLinkRenderer","isSameOriginLink","origin","e","getLinkOrigin","href","realLang","colorized","hljs","getLanguage","highlight","orgImageRenderer","imgLazyLoad","instance","replacers","markedOptions","gfm","breaks","async","getInstance","src","markedContent","_a","parse","alt","imgSrc","simpleMarked","dest","replacer","Context","constructor","_$root","__publicField","providers","Map","initializedDeps","inject","provider","get","Error","lifecycle","has","impl","deps","resolved","map","d","set","provide","createInjectionContainer","_deps","on","off","payload","trigger","getCommentNodes","getComments","getEl","destroy","firstChild","removeChild","getConf","updateConf","conf","update","watchConf","effect","getMarked","marked.getInstance","setDarkMode","darkMode","val","$root","I18n.t","getApi","getApiHandlers","getUser","getData","fetch","params","fetchComments","reload","offset","listGotoFirst","replyComment","commentData","$comment","setReplyComment","editComment","setEditComment","editorShowLoading","showLoading","editorHideLoading","hideLoading","editorShowNotify","msg","type","showNotify","editorResetState","resetState","showSidebar","show","hideSidebar","hide","checkAdmin","checkCaptcha","mergeDeep","objects","isObject","obj","prev","pVal","oVal","isArray","concat","Defaults","pageKey","pageTitle","site","sendBtn","editorTravel","flatMode","nestMax","nestSort","emoticons","pageVote","vote","uaBadge","listSort","countEl","pvEl","statPageKeyAttr","gravatar","mirror","pagination","pageSize","autoLoad","heightLimit","children","scrollable","imgUpload","reqTimeout","versionCheck","useBackendConf","preferRemoteConf","listUnreadHighlight","pvAdd","fetchCommentsOnInit","locale","apiVersion","pluginURLs","markedReplacers","handelCustomConf","customConf","full","pathname","title","language","matchMedia","convertApiOptions","user","handlers","siteName","timeout","getApiToken","userInfo","checkHasBasicUserInfo","initCountWidget","opt","loadStatCount","query","containers","loadCommentCount","cacheData","pvCount","pages","logPv","page_key","page_title","site_name","data","pv","incrementPvCount","loadPvCount","els","Set","selector","querySelectorAll","add","retrieveElements","pageKeys","pageKeyAttr","from","getAttribute","getPageKeys","res","stats","getStats","page_keys","__spreadValues","defaultPageKey","count","updateElementsText","HttpClient","apiConfig","fetchParams","credentials","headers","redirect","referrerPolicy","securityData","JSON","stringify","formData","property","append","Blob","FormData","toQueryString","cancelToken","abortControllers","abortController","signal","AbortController","abort","_b","body","secure","format","baseUrl","__objRest","secureParams","baseApiParams","securityWorker","requestParams","mergeRequestParams","queryString","payloadFormatter","contentFormatters","responseFormat","customFetch","__spreadProps","createAbortSignal","then","response","r","clone","ok","catch","encodeQueryParam","encodeURIComponent","addQueryParam","addArrayQueryParam","v","rawQuery","addQueryParams","params1","params2","super","loginByEmail","request","method","registerByEmail","sendVerifyEmail","checkDataMerge","applyDataMerge","flushCache","warmUpCache","getCaptcha","getCaptchaStatus","verifyCaptcha","createComment","getComment","id","updateComment","deleteComment","getSocialLoginProviders","getDomain","getNotifies","markAllNotifyRead","markNotifyRead","commentId","notifyKey","getPages","fetchAllPages","getPageFetchStatus","page","updatePage","deletePage","fetchPage","sendEmail","getSettings","applySettings","settings","getSettingsTemplate","getSites","createSite","updateSite","deleteSite","exportArtrans","importArtrans","uploadArtrans","upload","updateProfile","login","getUserStatus","createUser","updateUser","deleteUser","getUsers","getVersion","syncVotes","getVote","targetName","targetId","createVote","choice","Fetch","init","apiToken","Headers","Authorization","resp","json","retry","promise","action","Promise","resolve","FetchException","message","createError","status","Api","ApiV2","_opts","getUserFields","EditorPlugin","kit","useBtn","$btn","Utils.createElement","usePanel","$panel","useContentTransformer","func","contentTransformer","usePanelShow","useEvents","aPlug","usePanelHide","useEditorStateEffect","stateName","effectFn","editorStateEffectWhen","editorStateEffect","LocalStorageKey","SubmitAddPreset","reqAdd","useApi","comments","getSubmitAddParams","useUser","useConf","useEditor","getContentFinal","rid","ua","Utils.getCorrectUserAgent","postSubmitAdd","commentNew","useData","insertComment","Submit","defaultPreset","onEditorSubmit","do","useMounted","useUnmounted","registerCustom","c","customs","focus","custom","find","activeCond","nComment","pre","req","post","Mover","move","afterEl","isMoved","editorEl","useUI","$el","after","$travelPlace","replaceWith","classList","back","useArtalkRootEl","querySelector","remove","parentElem","$loading","transparentBg","background","appendChild","display","$spinner","setTimeout","isConnected","setLoading","scrollIntoView","elem","enableAnim","containerRect","clientHeight","scrollY","innerHeight","height","scrollOptions","behavior","scroll","playFadeInAnim","onAnimEnded","removeEventListener","addEventListener","playFadeAnim","setError","errorTextEl","HTMLElement","Emoticons","raw","transEmoticonImageText","loadEmoticonsData","isImgLoaded","initEmoticonsList","changeListHeight","parentElement","isListLoaded","loadingTask","Ui.showLoading","handleData","Ui.hideLoading","includes","Ui.setError","pushGrp","grp","remoteLoad","all","grpData","isOwOFormat","convertOwO","solveNullKey","solveSameKey","items","tmp","values","container","owoData","entries","grpName","nGrp","iconStr","icon","$grpWrap","$grp","setAttribute","$item","imgEl","onclick","insertContent","$grpSwitcher","openGrp","_c","AllowImgExts","Upload","initDragImg","$imgUploadInput","accept","$input","onchange","files","file","uploadImg","click","uploadFromFileList","onDragover","evt","stopPropagation","preventDefault","onDrop","dataTransfer","onPaste","clipboardData","$textarea","fileExt","insertPrefix","uploadPlaceholderTxt","customUploaderFn","imgUploader","public_url","imgURL","Utils.isValidURL","Utils.getURLBasedOnApi","setContent","Preview","isPlugPanelShow","updateContent","getContentMarked","EDITOR_PLUGS","onContentUpdated","localContent","localStorage","getItem","setItem","getContentRaw","$inputs","getHeaderInputEls","inputEventFns","changeEventFns","field","timer","abortFn","onInput","getState","fetchUserInfo","placeholders","logout","clearTimeout","api","CANCEL_TOKEN","abortRequest","onUserInfoFetched","finally","is_login","updateNotifies","notifies","is_admin","useCheckers","onSuccess","$link","onLinkChange","onLinkInputChange","onKeydown","adaptiveHeightByContent","keyCode","which","diff","offsetHeight","scrollHeight","onClick","submit","$submitBtn","setReply","cancelReply","submitPlug","useDeps","page_url","ui","$sendReplyBtn","$stateWrap","cancelEdit","saveData","$name","$email","$editCancelBtn","$header","updateSubmitBtnText","restoreSubmitBtnText","originalSubmitBtnText","onOpen","onClose","close","$textareaWrap","$bottom","prepend","PlugKit","plugins","getEditor","getOptions","getCheckers","getUI","getEvents","plug","getArtalkRootEl","EventManager","events","once","PluginManager","confLoaded","clear","confRefs","p","getEnabledPlugs","Plug","loadPluginUI","closePluginPanel","onSubmitted","getPlugins","openedPlug","$plugPanelWrap","$plugBtnWrap","loadPluginItem","openPluginPanel","plugPanel","getTransformedContent","rawContent","showErrorDialog","errEl","errMsg","retryFn","$retryBtn","onOpenSidebar","$openSidebar","$err","ListPlugins","ctx","_params","getLoading","limit","paramsModifier","listFetchParamsModifier","setListLastFetch","reqParams","flat_mode","loadComments","onError","notify","comment_id","getID","getRender","setUnread","setOpenAction","read_link","commentID","Utils.getQueryParam","editorPlugs","$closeCommentBtn","getPage","admin_only","adminPageEditSave","$count","getListLastFetch","$openSidebarBtn","syncByUser","$btnText","$unreadBadge","reloadUseParamsEditor","initDropdown","$dropdownOn","$dropdownWrap","dropdownList","curtActive","onItemClick","$dropdown","renderDropdown","sort_by","view_only_admin","removeDropdown","lastID","check","locker","isNaN","parseFloat","extractCommentID","hashChangeHandler","listLoadedHandler","getLayout","forceFlatMode","insert","reply_comment","isNoComment","$noComment","getCommentsWrapEl","$copyright","ARTALK_VERSION","setInterval","dateFormatter","Utils.timeAgo","clearInterval","errData","observer","clearObserver","disconnect","childNodes","$target","scrollEvtAt","scrollRelativeTo","IntersectionObserver","isIntersecting","threshold","root","observe","setupObserver","warn","$relative","Utils.getOffset","IgnoreVersionCheck","darkModeMedia","updateClassnames","$els","DarkModeClassName","upBtnEl","downBtnEl","upCountEl","downCountEl","activeClass","updateVoteStatus","state","up","down","isUp","isDown","toggle","voteBtnHandler","pageId","httpApi","votes","is_up","is_down","alert","LOCAL_USER_KEY","UserManager","localUser","isAdmin","onUserChanged","iframeBody","checker","$iframeWrap","$iframe","getOpts","getCaptchaIframeURL","onload","$closeBtn","hideInteractInput","stop","queryStatus","ms","isPass","captcha","is_pass","triggerSuccess","CaptchaChecker","inputVal","render.iframeBody","img_data","render.imgBody","formEl","AdminChecker","inputType","onReload","Dialog","contentEl","$actions","$content","setYes","btn","onBtnClick","setNo","currentTarget","wrapPromise","reject","cancelFn","onCancel","successFn","CheckerLauncher","beforeCheck","layer","getLayers","create","checkerStore","checkerCtx","btnTextOrg","onkeyup","dialog","btnEl","btnTextRestore","btnText","tf","onfocus","onMount","Sel","$notifyWrap","$bottomLeft","EditorStateManager","editor","stateCurt","stateUnmountFn","moveAfterEl","_d","_f","_e","Ui.scrollIntoView","plugin","_g","Editor","k","sel","render","setPlugins","selection","createRange","selectionStart","sStart","sEnd","selectionEnd","sT","switch","wrapElem","notifyElem","s","w","notifyRemove","timeoutFn","Ui.showNotify","next","beforeSubmit","DataManager","listLastFetch","findComment","clearComments","partialComments","pageData","Layer","setOnAfterHide","onAfterHide","setAllowMaskClose","allow","allowMaskClose","getAllowMaskClose","onShow","onHide","bodyOrgOverflow","bodyOrgPaddingRight","getScrollbarHelper","overflow","paddingRight","unlock","lock","barPaddingRight","parseInt","getComputedStyle","getPropertyValue","inner","outer","position","visibility","w1","offsetWidth","w2","clientWidth","Ui.getScrollBarWidth","LayerWrap","$wrap","$mask","createItem","createItemElement","hideWrap","showWrap","getMask","getWrap","l","LayerManager","wrap","createNestStrategy","import","srcData","sortBy","nodeList","rootNode","level","parent","loadChildren","parentNode","child","childNode","sortFunc","b","vote_up","sortLevels","nodes","sort","ListNest.makeNestCommentNodeList","nestSortBy","rootC","createCommentNode","$commentsWrap","parentC","replyD","childD","childC","putChild","checkHeightLimit","findCommentNode","getParents","heightLimitRemoveForChildren","insertMode","is_collapsed","is_allow_reply","visible","$listCommentsWrap","ListLayout","getStrategy","rules","max","imgCheck","maxHeight","_check","Utils.getHeight","contains","HEIGHT_LIMIT_SCROLL_CSS","applyScrollableHeightLimit","HEIGHT_LIMIT_CSS","$expandBtn","disposeHeightLimit","afterExpandBtnClick","applyHeightLimit","imgs","renderNick","$headerNick","$nickA","renderVerifyBadge","$headerBadgeWrap","badgeText","badge_name","badgeColor","badge_color","$badge","backgroundColor","is_verified","$verifiedBadge","is_pinned","$pinnedBadge","renderDate","$date","getDateFormatted","renderUABadge","ip_region","$uaWrap","$regionBadge","browser","os","getUserUA","$uaBrowser","$usOS","ActionBtn","getText","adminOnly","isMessaging","msgRecTimer","appendTo","dom","setClick","isLoading","confirmRestore","isConfirming","confirmText","confirmRecTimer","fireMsgRecTimer","clearMsgRecTimer","updateText","loadingText","setMsg","setWarn","setSuccess","duringTime","setMsgRecTimer","msgRecTimerFunc","renderVote","voteBtnUp","getActions","voteBtnDown","vote_down","renderReply","replyBtn","renderCollapse","collapseBtn","adminEdit","renderModerator","pendingBtn","is_pending","renderPin","pinnedBtn","renderEdit","editBtn","renderDel","delBtn","adminDelete","Renders","Avatar","$avatar","$avatarImg","avatarURLBuilder","getGravatarURL","$avatarA","Header","Content","collapsedInfoEl","$body","insertAdjacentElement","contentShowBtn","Ui.playFadeInAnim","ReplyAt","replyTo","$replyAt","goToReplyComment","ReplyTo","$replyTo","$nick","replyContent","Pending","pendingEl","Actions","Render","$main","$childrenWrap","contentMaxH","childrenMaxH","HeightLimit.check","getChildren","HeightLimit.disposeHeightLimit","playFadeAnimForBody","playFlashAnim","getChildrenWrap","setOpenable","setOpenURL","CommentActions","actionBtn","btnElem","modify","setData","onDelete","origHash","modifyHash","dispatchEvent","Event","CommentNode","nestCurt","actionInstance","renderInstance","CommentUI","newEl","onAfterRender","getParent","getNestCurt","getIsRoot","getChildrenWrapEl","$childComment","flattenParents","emailHash","email_encrypted","info","win","nav","osVersion","engine","device","engineMatch","Trident","Presto","WebKit","Gecko","browserMatch","Safari","Chrome","IE","Edge","Firefox","Chromium","Opera","Vivaldi","Yandex","Kindle","UC","QQBrowser","QQ","Baidu","Maxthon","Sogou","LBBROWSER","TheWorld","MIUI","Quark","Qiyu","Wechat","Taobao","Alipay","Weibo","Douban","Suning","iQiYi","osMatch","Windows","Linux","macOS","Android","Ubuntu","FreeBSD","Debian","BlackBerry","MeeGo","Symbian","iOS","WebOS","deviceMatch","Mobile","Tablet","showModalDialog","chrome","arr","browserLanguage","UADetect","ReadMoreBtn","origText","$text","hasMore","total","checkDisabled","showErr","ReadMorePaginator","readMoreAutoLoad","onReachedBottom","getHasMore","getIsClearComments","dispose","Pagination","oninput","onkeydown","keydown","$prevBtn","$nextBtn","maxPage","ceil","setInput","inputTimer","change","onChange","UpDownPaginator","PaginationComponent","resetEditorState","onListGotoFirst","getPageDataByLastData","roots_count","initListPaginatorFunc","paginator","getList","createPaginatorByConf","$paginator","List","initCrudEvents","commentNodes","SidebarLayer","refreshWhenShow","transform","initLayer","createIframe","view","iFrameSrc","getDarkMode","iframeLoad","authCheck","animTimer","time","urlParams","URLSearchParams","DefaultPlugins","findIndex","h","splice","createApiHandlers","config","apiHandlers","layers","checkers","layerManager","sidebarLayer","Marked","setOptions","initMarked","pluginManager","scanApply","$sidebarEl","getAdminOnlyEls","feVer","beVer","comp","pa","pb","na","nb","Utils.versionCompare","ignoreBtn","darkModeAutoHandler","sync","cleanup","_state","voteUpHandler","voteDownHandler","loadOptions","listFetchedHandler","currPageId","checkEls","fetchVoteStatus","handlerOptions","GlobalPlugins","PluginOptions","WeakMap","mount","localConf","loaded","loadPlugins","sidebarOpenView","err_no_site","viewLoadParam","create_name","create_urls","host","onRetry","MountError","remoteConf","ExcludedKeys","startsWith","handleConfFormServer","frontend_conf","scripts","apiBase","networkPlugins","tasks","script","head","onerror","ArtalkPlugins","loadNetworkPlugins","lastVal","newVal","Artalk","getRootEl","EventsService","mounted","ConfigService","use","loadCountWidget"],"mappings":"0xBAAgB,SAAAA,EAAmDC,EAAkB,IAC7E,MAAAC,EAAMC,SAASH,cAAc,OAEnC,OADIE,EAAAE,UAAYH,EAAQI,OAChBH,EAAII,mBAAqBJ,CACnC,CAOO,SAASK,EAAWC,GACnB,MAAAC,EAAON,SAASH,cAAc,OACpCS,EAAKC,UAAYF,EAEV,OADQC,EAAKL,SAEtB,CASO,SAASO,EAAcC,GACtB,MAAAC,EAAQC,OAAO,OAAOF,aAAgBG,KAAKC,OAAOC,SAASC,QAC1D,OAAAL,GAASM,mBAAmBN,EAAM,GAAGO,QAAQ,MAAO,KAC7D,CAEgB,SAAAC,EAAUC,EAAiBC,GACnC,MAAAC,EAAsBC,IACpB,MAAAC,EAAOD,EAAQE,wBACfC,EAAaZ,OAAOa,aAAe1B,SAAS2B,gBAAgBF,WAC5DG,EAAYf,OAAOgB,aAAe7B,SAAS2B,gBAAgBC,UAC1D,MAAA,CACLE,IAAKP,EAAKO,IAAMF,EAChBG,KAAMR,EAAKQ,KAAON,EAAA,EAIhBO,EAAWX,EAAmBF,GAChC,IAACC,EAAmB,OAAAY,EAElB,MAAAC,EAAmBZ,EAAmBD,GAErC,MAAA,CACLU,IAAKE,EAASF,IAAMG,EAAiBH,IACrCC,KAAMC,EAASD,KAAOE,EAAiBF,KAE3C,CAEgB,SAAAG,EAAaC,EAAiBC,GACxC,IAAAC,EAAcF,EAAQG,WACnB,KAAAD,EAAYE,OAASH,GAC1BC,EAAc,IAAIA,IAEb,OAAAA,CACT,CAYO,SAASG,EAAQC,EAAYC,EAAMC,GAAWA,GAC/C,IACI,MAAAC,EAAUH,EAAKI,UAEfC,GADW,IAAIC,MAAOF,UACCD,EAEvBI,EAAOC,KAAKC,MAAMJ,EAAa,OACrC,GAAa,IAATE,EAAY,CAER,MAAAG,EAASL,EAAa,MACtBM,EAAQH,KAAKC,MAAMC,EAAA,MACzB,GAAc,IAAVC,EAAa,CAET,MAAAC,EAASF,OACTG,EAAUL,KAAKC,MAAMG,EAAA,KAC3B,GAAgB,IAAZC,EAAe,CAEX,MAAAC,EAASF,MACTG,EAAUP,KAAKQ,MAAMF,EAAS,KACpC,OAAIC,EAAU,GAAWd,EAAG,OACrB,GAAGc,KAAWd,EAAG,YAC1B,CACA,MAAO,GAAGY,KAAWZ,EAAG,YAC1B,CACA,MAAO,GAAGU,KAASV,EAAG,UACxB,CACA,OAAIM,EAAO,EAAUN,EAAG,OAEpBM,EAAO,EACF,GAAGA,KAAQN,EAAG,UAvCpB,SAAoBD,GACzB,MAAMiB,EAAOxB,EAAaO,EAAKkB,UAAW,GACpCC,EAAS1B,EAAaO,EAAKoB,WAAa,EAAG,GAKjD,MAAO,GAJO3B,EAAaO,EAAKqB,cAAe,MAI5BF,KAAUF,GAC/B,CAkCWK,CAAWtB,SACXuB,GAEA,OADPC,QAAQD,MAAMA,GACP,KACT,CACF,CA4BA,SAAsBE,IAAsB,OAAAC,EAAAC,KAAA,MAAA,YAC1C,MAAMC,EAAQC,UAAUC,UACxB,IAAMD,UAAkBE,gBAAmBF,UAAkBE,cAAcC,qBAClE,OAAAJ,EAKT,MAAMK,EAAUJ,UAAkBE,cAClC,IAAIG,EAAa,KACb,IACFA,QAAcD,EAAOD,qBAAqB,CAAC,0BACpCG,GAEA,OADPX,QAAQD,MAAMY,GACPP,CACT,CACM,MAAAQ,EAAuBC,OAAOH,EAAMI,gBAAgBC,MAAM,KAAK,IAEjE,MAAoB,YAApBN,EAAOO,UACLJ,GAAwB,GAInBR,EAAMpD,QAAQ,kBAAmB,mBAGpB,UAApByD,EAAOO,UACLJ,GAAwB,GAKnBR,EAAMpD,QACX,kCACA,YAAY0D,EAAMI,gBAAgB9D,QAAQ,MAAO,QAKhDoD,CACT,GAAA,CAGO,SAASa,EAAWC,GAErB,IAAAC,EACA,IACIA,EAAA,IAAIC,IAAIF,SACPG,GACA,OAAA,CACT,CACA,MAAwB,UAAjBF,EAAIG,UAAyC,WAAjBH,EAAIG,QACzC,CAGO,SAASC,EAAiBC,GAC/B,OAI4BC,EAJPD,EAAKE,KAImBC,EAJbH,EAAKG,KAK9B,GAAGF,EAAQzE,QAAQ,MAAO,OAAO2E,EAAK3E,QAAQ,MAAO,MAD9C,IAAcyE,EAAiBE,CAH/C,CChMA,MAAMC,EAAK,CAETC,YAAa,kBACbC,UAAW,aACXC,KAAM,OACNC,OAAQ,UACRC,OAAQ,UACRC,KAAM,OACNC,KAAM,WACNC,MAAO,QACPC,KAAM,UACNC,SAAU,QACVC,QAAS,UACTC,YAAa,eACbC,WAAY,gBACZC,YAAa,oBACbC,YAAa,4BACbC,kBAAmB,uBACnBC,eAAgB,+CAGhBC,QAAS,mBACTC,WAAY,SACZC,WAAY,SACZC,SAAU,OACVC,WAAY,SACZC,YAAa,eACbC,aAAc,gBACdC,gBAAiB,0BACjBC,UAAW,QACXC,SAAU,YAGVC,MAAO,QACPC,MAAO,QACPC,OAAQ,KACRC,SAAU,OACVC,SAAU,cACVC,SAAU,YACVC,cAAe,UACfC,SAAU,WACVC,UAAW,YACXC,aAAc,kCACdC,OAAQ,SACRC,SAAU,WACVC,QAAS,UACTC,WAAY,sCACZC,KAAM,OACNC,WAAY,cACZC,OAAQ,SACRC,cAAe,UACfC,IAAK,MACLC,MAAO,QAGPpF,QAAS,cACTF,QAAS,cACTF,MAAO,YACPJ,KAAM,WACN6F,IAAK,WAGLC,WAAY,wBACZC,aAAc,iCACdC,QAAS,UACTC,OAAQ,SAGRC,UAAW,WACXC,WAAY,YAGZC,YAAa,UACbC,gBAAiB,yBACjBC,kBAAmB,2BACnBC,eAAgB,kBAChBC,cAAe,iBACfC,eAAgB,kBAChBC,gBAAiB,mBACjBC,iBAAkB,yBAClBC,iBAAkB,oBAClBC,WAAY,YACZC,aAAc,SACdC,YAAa,kBACbC,cAAe,0BACfC,SAAU,WACVC,SAAU,WACVC,SAAU,YACVC,WAAY,oBACZC,cAAe,0BACfC,mBAAoB,sDACpBC,sBAAuB,4DACvBC,oBAAqB,4DACrBC,QAAS,UACTC,MAAO,QAGPC,OAAQ,SACRC,OAAQ,SACRC,QAAS,UACTC,SAAU,cACVC,QAAS,UACTC,SAAU,cACVC,SAAU,WACVC,WAAY,gBACZC,OAAQ,cACRC,WAAY,+CACZC,UAAW,0DACXC,eAAgB,kBAChBC,OAAQ,SACRC,KAAM,OACNC,SAAU,eC7GCC,EAAqB,aCQrBC,EAAW,CACtB9F,KACA,QAASA,EACT,QCXiB,CAEjBC,YAAa,UACbC,UAAW,YACXC,KAAM,KACNC,OAAQ,KACRC,OAAQ,KACRC,KAAM,KACNC,KAAM,KACNC,MAAO,KACPC,KAAM,KACNC,SAAU,KACVC,QAAS,KACTC,YAAa,OACbC,WAAY,OACZC,YAAa,OACbC,YAAa,UACbC,kBAAmB,UACnBC,eAAgB,gBAGhBC,QAAS,cACTC,WAAY,KACZC,WAAY,KACZC,SAAU,KACVC,WAAY,KACZC,YAAa,OACbC,aAAc,OACdC,gBAAiB,aACjBC,UAAW,SACXC,SAAU,OAGVC,MAAO,MACPC,MAAO,KACPC,OAAQ,KACRC,SAAU,KACVC,SAAU,OACVC,SAAU,OACVC,cAAe,OACfC,SAAU,KACVC,UAAW,MACXC,aAAc,gBACdC,OAAQ,KACRC,SAAU,KACVC,QAAS,KACTC,WAAY,aACZC,KAAM,KACNC,WAAY,OACZC,OAAQ,KACRC,cAAe,OACfC,IAAK,KACLC,MAAO,OAGPpF,QAAS,KACTF,QAAS,MACTF,MAAO,MACPJ,KAAM,KACN6F,IAAK,KAGLC,WAAY,gBACZC,aAAc,WACdC,QAAS,KACTC,OAAQ,KAGRC,UAAW,OACXC,WAAY,OAGZC,YAAa,OACbC,gBAAiB,QACjBC,kBAAmB,QACnBC,eAAgB,OAChBC,cAAe,OACfC,eAAgB,OAChBC,gBAAiB,OACjBC,iBAAkB,aAClBC,iBAAkB,MAClBC,WAAY,QACZC,aAAc,OACdC,YAAa,gBACbC,cAAe,QACfC,SAAU,KACVC,SAAU,MACVC,SAAU,MACVC,WAAY,OACZC,cAAe,YACfC,mBAAoB,uBACpBC,sBAAuB,oBACvBC,oBAAqB,2BACrBC,QAAS,KACTC,MAAO,KAGPC,OAAQ,MACRC,OAAQ,MACRC,QAAS,MACTC,SAAU,OACVC,QAAS,MACTC,SAAU,OACVC,SAAU,MACVC,WAAY,OACZC,OAAQ,OACRC,WAAY,YACZC,UAAW,8BACXC,eAAgB,OAChBC,OAAQ,KACRC,KAAM,KACNC,SAAU,aD9FL,SAASG,EAAcC,GAQxB,OANJA,EAAOA,EAAK5K,QACV,8BACA,CAACqE,EAAGwG,EAAYC,IAAeD,EAAGE,eAAiBD,GAAM,IAAIE,gBAI3DN,EAASE,GACJF,EAASE,GAIdhL,OAAO6K,IAAuB7K,OAAO6K,GAAoBG,GACpDhL,OAAO6K,GAAoBG,GAK7BF,EAAS9F,EAClB,CAKA,IAAIqG,EAA4B,KAC5BC,EAAmBP,EAAcM,GAc9B,SAASE,EAAEC,EAAeC,EAAkC,IAC7D,IAAAjM,SAAM8L,WAAaE,KAAQA,EAGxB,OAFDhM,EAAAA,EAAIY,QAAQ,qBAAqB,CAACqE,EAAGiH,IAAUD,EAAKC,IAAU,KAE7DC,EAAiBnM,EAC1B,kPE9DA,IAAIoM,EAAU,CACZ,IAAK,QACL,IAAK,OACL,IAAK,OACL,IAAK,SACL,IAAK,SAEHC,EAAY,CACd,QAAS,IACT,OAAQ,IACR,OAAQ,IACR,SAAU,IACV,QAAS,KAEPC,EAAW,kCACXC,EAAa,WAEjB,SAASC,EAAgBnM,GACvB,OAAO+L,EAAQ/L,EACjB,CACA,SAASoM,EAAkBpM,GACzB,OAAOgM,EAAUhM,EACnB,CAEA,SAASqM,EAAYC,GACZ,OAAQ,MAARA,EAAe,GAAKC,OAAOD,GAAM/L,QAAQ2L,EAAYC,EAC9D,CAEA,SAASK,EAAcC,GACd,OAAQ,MAARA,EAAe,GAAKF,OAAOE,GAAMlM,QAAQ0L,EAAUG,EAC5D,CAEAC,EAAWK,QAAUF,EAAaE,QAAU,GAE5C,IAAAC,EAAiB,CACfC,OAAQP,EACRQ,OAAQR,EACRS,OAAQN,EACRO,SAAUP,EACVQ,QAAS,iBCpBX,IAAAC,EAnBA,SAASC,EAAYC,GAInB,IAHA,IACIC,EACAzB,EAFA0B,EAAQC,MAAMC,UAAUC,MAAMC,KAAKC,UAAW,GAG3CL,EAAMxL,QAEX,IAAK8J,KADLyB,EAAOC,EAAMM,QAEPP,EAAKQ,eAAejC,KAC8B,oBAAhDkC,OAAON,UAAU3L,SAAS6L,KAAKN,EAAOxB,IACjCwB,EAAAxB,GAAOuB,EAAWC,EAAOxB,GAAMyB,EAAKzB,IAEpCwB,EAAAxB,GAAOyB,EAAKzB,IAKpB,OAAAwB,CACT,ECjBAW,EAAiB,SAAoBC,GACnC,MAAyB,iBAAXA,EAAsBA,EAAOzC,cAAgByC,CAC7D,ECEA,SAASC,EAAOC,EAAab,GAEpB,OADPa,EAAYb,IAAQ,EACba,CACT,CAEA,IAAAC,EATA,SAAgBC,GACd,OAAOA,EAAKC,OAAOJ,EAAO,CAAE,EAC9B,ECCAK,EAAiB,CACfC,KAJUC,EACD,CAAC,aAAc,OAAQ,OAAQ,OAAQ,WAAY,MAAO,YCErEC,EAAiB,CACfC,MAJUF,EACA,CAAC,OAAQ,KAAM,MAAO,KAAM,MAAO,MAAO,QAAS,OAAQ,WAAY,OAAQ,UCDvFG,EAAKH,EACLT,EAAYa,EAEZH,EAAWI,EACXC,EAAS,6FACTC,EAAO,4BACPC,EAAS,0EACTC,EAAO,KACPC,EAAU,UA8Hd,ICtIIP,EAAKH,EACLT,EAAYa,EACZN,GAAaa,EACbV,GAAWI,EAsIf,ICxIIO,GAASR,EACTS,GFgBJ,SAAiB3C,EAAM4C,GAKrB,IAJA,IAEIC,EAFAjC,EATN,WACE,IAAIA,EAAQ,GAIL,OAHDA,EAAAkC,SAAW,WACR,OAAAlC,EAAMA,EAAMxL,OAAS,EAChC,EACSwL,CACT,CAGcmC,GACRC,EAAOhD,EAGJA,OAKP,SAASiD,IACCJ,GAAA,EAWV,WAC4B,YAAtB7C,EAAKkD,OAAO,EAAG,IAoBfC,EAAQnD,EAAKoD,QAAQ,YACZ,IACPR,EAAQS,SACVT,EAAQS,QAAQrD,EAAKsD,UAAU,EAAGH,IAE7BnD,EAAAA,EAAKsD,UAAUH,EAAQ,GACtBN,GAAA,GAxBCL,EAAQe,KAAKvD,GACtBwD,EAAUnB,EAAMoB,GACPlB,EAAKgB,KAAKvD,IACnBwD,EAAUpB,EAAQsB,GActB,IACMP,GAUN,WACE,IAAKN,EACH,OAEE,IAAAhD,EACAsD,EAAQnD,EAAKoD,QAAQ,KACrBD,GAAS,GACJtD,EAAAG,EAAKsD,UAAU,EAAGH,GAClBnD,EAAAA,EAAKsD,UAAUH,KAEftD,EAAAG,EACAA,EAAA,IAEL4C,EAAQC,OACVD,EAAQC,MAAMhD,EAEjB,GAtCA,IAjBC,IAAI8D,EAAO3D,IAASgD,EACbA,EAAAhD,EAEH2D,IACK3D,EAAA,GAEV,CAaQ,SAAAwD,EAAWI,EAAOjB,GACrB,IAAApP,EAAQyM,EAAKzM,MAAMqQ,GACnBrQ,IACFyM,EAAOA,EAAKsD,UAAU/P,EAAM,GAAG6B,QAC/B7B,EAAM,GAAGO,QAAQ8P,EAAOjB,GAChBE,GAAA,EAEX,CA+BD,SAASa,EAAeG,EAAKC,EAASC,EAAMC,GAC1C,IAAIC,EAAQ,CAAA,EACRC,EAAM7C,EAAUyC,GAChBK,EAAIpC,EAASC,MAAMkC,MAAUF,EAE5BD,EAAAjQ,QAAQwO,GASb,SAAuB/O,EAAOD,EAAM8Q,EAAmBC,EAAmBC,GAEtEL,EAAM3Q,QADkB,IAAtB8Q,QAAsD,IAAtBC,QAAkD,IAAlBC,OACpD,EAEArC,EAAG5B,OAAO+D,GAAqBC,GAAqBC,GAAiB,GAEtF,IAbIH,GACHvD,EAAM2D,KAAKL,GAETtB,EAAQ4B,OACF5B,EAAA4B,MAAMN,EAAKD,EAAOE,EAU7B,CAEQ,SAAAV,EAAaI,EAAKC,GACrB,IAAAW,EACAC,EAAM,EACNR,EAAM7C,EAAUyC,GACpB,GAAII,EACF,IAAKQ,EAAM9D,EAAMxL,OAAS,EAAGsP,GAAO,GAC9B9D,EAAM8D,KAASR,EADkBQ,KAMzC,GAAIA,GAAO,EAAG,CACZ,IAAKD,EAAI7D,EAAMxL,OAAS,EAAGqP,GAAKC,EAAKD,IAC/B7B,EAAQ+B,KACF/B,EAAA+B,IAAI/D,EAAM6D,IAGtB7D,EAAMxL,OAASsP,CAChB,CACF,IACH,EEjIIE,GDEJ,SAAoBC,EAAQ5E,GAEtB,IAAA6E,EACAC,EAAI9E,GAAW,GAIZ,WAAA,CACLuE,MASO,SAAOX,EAAKI,EAAOD,GACtB,IAAAE,EAAM7C,EAAUwC,GAEpB,GAAIiB,EAAQE,SACG,YAAb5G,EAAO8F,GAET,IAA+C,KAA1Ca,EAAEE,aAAe,IAAI7B,QAAQc,GACnB,YAAb9F,EAAO8F,GAEL,GAAAa,EAAEG,SAAWH,EAAEG,OAAO,CAAErB,IAAKK,EAAKD,UACvB,YAAb7F,EAAO8F,GAGTiB,EAAI,KACJA,EAAIjB,GACJ9C,OAAOgE,KAAKnB,GAAOoB,SAGnB,SAAgBnG,GACV,IAAAoG,EAAQrB,EAAM/E,GACdqG,GAAaR,EAAES,gBAAkB,CAAA,GAAItB,IAAQ,GAC7CuB,GAAWV,EAAEW,mBAAqB,CAAA,GAAIxB,IAAQ,GAE9CyB,EAAOtE,EAAUnC,IACR,UAATyG,IAAkD,IAA9BF,EAAQrC,QAAQuC,IAC9BL,EAAAA,EAAMzN,MAAM,KAAKqN,QAc3B,SAAuBU,GACrB,OAAOL,IAA8C,IAAjCA,EAAUnC,QAAQwC,EACvC,IAhB+CC,KAAK,KAAK9S,QAC1CqC,QAEoB,IAA1BqQ,EAAQrC,QAAQuC,MAA2C,IAA1B/D,GAAWC,KAAK8D,IAiC/D,SAAkB9F,GACZ2E,IAAAA,EAAQ3E,EAAK,GACb2E,GAAU,MAAVA,GAA2B,MAAVA,EACZ,OAAA,EAEL,IAAAsB,EAAQjG,EAAKuD,QAAQ,KACzB,IAAkB,IAAd0C,EACK,OAAA,EAEL,IAAAC,EAAelG,EAAKuD,QAAQ,KAC5B,IAAuB,IAAvB2C,GAAuBD,EAAQC,EAC1B,OAAA,EAEL,IAAAC,EAAOnG,EAAKuD,QAAQ,KACpB,OAAe,IAAf4C,GAAeF,EAAQE,GAGpBjB,EAAEkB,eAAeC,KAAKC,GAE7B,SAASA,EAASC,GAChB,OAAsC,IAA/BvG,EAAKuD,QAAQgD,EAAS,IAC9B,CACF,CAvDgFC,CAAQf,OAGnFH,EAAI,KACJA,EAAIjG,GACiB,iBAAVoG,IACTH,EAAI,MACAA,EAAAlD,EAAG9B,OAAOmF,IACdH,EAAI,MAMT,IA1BGA,EAAAnB,EAAQ,KAAO,IA2BpB,EAnDCW,IAqDF,SAAcd,GACR,IAAAK,EAAM7C,EAAUwC,IACiC,KAAtCkB,EAAEE,aAAe,IAAI7B,QAAQc,KAEjB,IAArBY,EAAQE,UACVG,EAAI,MACJA,EAAIjB,GACJiB,EAAI,MAKNmB,EAASpC,EAEZ,EAlECrB,MA4FF,SAAgBhD,IACW,IAArBiF,EAAQE,UACVG,EAAIJ,EAAEwB,cAAgBxB,EAAEwB,cAAc1G,GAAQA,EAEjD,GA7FD,SAASsF,EAAKG,GACZT,EAAON,KAAKe,EACb,CA6FD,SAASlH,EAAQyF,GACX9B,GAASC,MAAM6B,MAGM,IAArBiB,EAAQE,SACVF,EAAU,CAAEE,SAAUnB,EAAK2C,MAAO,GACzB1B,EAAQE,WAAanB,GACtBiB,EAAA0B,QAEX,CAED,SAASF,EAAUzC,GACbiB,EAAQE,WAAanB,KACjBiB,EAAQ0B,OAAS,MAI1B,CAED,SAASC,IACP3B,EAAU,CAAEE,UAAU,EAAOwB,MAAO,EACrC,CACH,ECnIIE,GCJW,CACbhB,kBAAmB,CACjBiB,EAAG,CAAC,OAAQ,OAAQ,SAAU,QAAS,cACvCC,OAAQ,CAAC,kBAAmB,cAAe,OAC3CC,IAAK,CAAC,MAAO,MAAO,QAAS,eAE/BrB,eAAgB,CAAE,EAClBS,eAAgB,CAAC,OAAQ,QAAS,UAClChB,YAAa,CACX,IAAK,OAAQ,UAAW,IAAK,aAAc,KAAM,UAAW,OAAQ,MAAO,UAAW,MAAO,KAC7F,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,IAAK,MAAO,MAAO,MAAO,KAAM,OAAQ,OAClF,KAAM,IAAK,MAAO,UAAW,OAAQ,SAAU,SAAU,MAAO,UAAW,MAAO,QAClF,QAAS,KAAM,KAAM,QAAS,KAAM,IAAK,MAE3CC,OAAQ,MDRV,SAAS4B,GAAQ9G,EAAMC,EAAS8G,GAC9B,IAAIlC,EAAS,GACTmC,GAA2B,IAAXD,EAAkB9G,EAAUyC,GAAO,CAAE,EAAEgE,GAAUzG,GACjE2C,EAAUgC,GAAUC,EAAQmC,GAIzB,OAFPrE,GAAO3C,EAAM4C,GAENiC,EAAOgB,KAAK,GACrB,CAEAiB,GAAOJ,SAAWA,cACDI,IEjBXG,GAAgB,CACpBzB,eAAgB,CAAC,EAKjBS,eAAgB,CACd,OACA,QACA,SACA,QAEFhB,YAAa,CACX,IACA,OACA,UACA,IACA,aACA,KACA,UACA,OACA,MACA,UACA,MACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,IACA,MACA,MACA,MACA,KACA,OACA,OACA,KACA,IACA,MACA,UACA,OACA,SACA,SACA,MACA,UACA,MACA,QACA,QACA,KACA,KACA,QACA,KACA,IACA,MAEFS,kBAAmB,CACjB,IAAK,CAAC,QAAS,aACfiB,EAAG,CAAC,OAAQ,OAAQ,SAAU,aAAc,OAC5CE,IAAK,CAAC,MAAO,MAAO,QAAS,eAAgB,aAAc,WAAY,QAAS,WAEhFK,KAAM,CAAC,SACPC,KAAM,CAAC,QAAS,UAElBjC,OAASkC,IAES,CACd,CAAC,OAAQ,0BACT,CAAC,OAAQ,eACT,CAAC,MAAO,eAEF/B,SAAQ,EAAExB,EAAKwD,MACjBD,EAAKvD,MAAQA,GAASuD,EAAKnD,MAAMqD,QAAWD,EAAe9D,KAAK6D,EAAKnD,MAAMqD,eACtEF,EAAKnD,MAAMqD,KACpB,IAKa,SAAbF,EAAKvD,KACHuD,EAAKnD,MAAMsD,QACZ,kCAAkChE,KAAK6D,EAAKnD,MAAMsD,eAE5CH,EAAKnD,MAAMsD,OAGb,IAIJ,SAASC,GAASC,GAGhBX,OAAAA,GAAOW,EAASR,GACzB,mCCjGkFS,QAGzE,WAEA,SAAAC,EAAqBC,EAAIC,GAC1BA,OAA0BD,EAA1BC,EAAS,CAAEH,QAAS,CAAA,GAAiBG,EAAOH,SAAUG,EAAOH,OACpE,CAEG,IAAAI,EAAUH,GAAqB,SAAUE,GAGzC,IAAAxE,EAAUwE,EAAOH,QAAU,WAC9B,OAAO,IAAIlU,OAAO,MAAQ6P,EAAQ0E,OAAOC,OAAS,QAAU3E,EAAQ4E,QAAQD,OAAS,IAAK,KAC3F,EAEA3E,EAAQ0E,KAAO,WACP,MAAA,sBACR,EAEA1E,EAAQ4E,MAAQ,WACR,MAAA,sBACR,CACA,IAEIC,EAAgB,CAAC,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,UAmC7I,SAASC,EAAUC,GACjB,MAAQ,kCAAsCA,EAAK,SACpD,CAEM,OArCK,SAAUC,EAAOC,QACd,IAARA,IAAiBA,EAAM,CAAA,GAC5B,IAAIC,EAASD,EAAIC,YAAwB,IAAXA,IAA6BA,EAAAL,GAE3D,IAAI/E,EAAQ,EACRqF,EAAQ,CAAA,EAIRC,EAAK,IAAIjV,OAAQ,IAHR,wFAGsBwU,OAAU,IAF3B,IAE8CA,OAAU,MAASF,IAAUE,OAAU,IAAM,OAC7G,OAAOK,EACNvU,QAAQ2U,GAAI,SAAUC,EAAGC,EAAMP,GAC9B,GAAIA,EACF,OAAOD,EAAUC,GAGnB,GAAa,MAATO,EACK,MAAA,OAEL,IAAAC,EACAJ,EAAMG,GACRC,EAAQJ,EAAMG,IAEdC,EAAQL,EAAOpF,GACfqF,EAAMG,GAAQC,GAGhB,IAAIzD,EAAM,wBAA2ByD,EAAQ,KAAQD,EAAO,UAErD,OADPxF,IAAUA,EAAQoF,EAAOnT,OAClB+P,CACX,GACA,CAQA,CAlEkF0D,ICC3E,SAASC,GAAW5B,GACzB,OAAO6B,GAAO7B,EAChB,CCIO,SAAS8B,GAAY/I,GACpB,MAAAgJ,EAAW,IAAIC,SAAOC,SAIrB,OAHPF,EAAS9P,KAAOiQ,GAAmBH,EAAUA,EAAS9P,MACtD8P,EAAS/B,KAAOmC,KAChBJ,EAASK,MAAQC,GAAoBN,EAAUA,EAASK,MAAOrJ,GACxDgJ,CACT,CAEA,MAAMG,GACJ,CAACH,EAAeO,IAAoDrK,IAC5D,MAOAsK,EAPgB,CAACtQ,IACjB,IACK,OAAA,IAAIjB,IAAIiB,GAAMuQ,MAAA,CACf,MAAAC,GACC,MAAA,EACT,GAEuBC,CAAczK,EAAK0K,QAAUnW,OAAOC,SAAS+V,OAEtE,OADaF,EAAgBxI,KAAKiI,EAAU9J,GAChCrL,QACV,OACA,sBAAuB2V,EAA0D,GAAvC,wCAAyC,EAInFJ,GACJ,IACA,EAAG3K,OAAMmB,WAED,MAAAiK,EAAYpL,GAAO,YACzB,IAAIqL,EAAYlK,EAShB,OARKnM,OAAesW,KACdF,GAAapW,OAAesW,KAAKC,YAAYH,KAC/CC,EAAarW,OAAesW,KAAKE,UAAUJ,EAAUjK,GAAMyF,OAG7DyE,EAAYjB,GAAWjJ,GAIvB,aAAaiK,mCACiBA,MAAaC,EAAUjW,QAAQ,SAAU,qBAAI,EAK3EyV,GACJ,CACEN,EACAkB,GACEC,iBAEHjL,IACC,MAAMa,EAAOmK,EAAiBnJ,KAAKiI,EAAU9J,GACzC,OAACiL,EACe,WAAhBA,IAAqD,IAAxBA,EACxBpK,EAAKlM,QAAQ,SAAU,yCACZ,aAAhBsW,EACKpK,EAAKlM,QAAQ,SAAU,0BAA0BA,QAAQ,OAAQ,aACnEkM,EALkBA,CAKlB,ECzDX,IAAIqK,GACAC,GAAwB,GAE5B,MAAMC,GAA+B,CACnCC,KAAK,EACLC,QAAQ,EACRC,OAAO,GAIF,SAASC,KACP,OAAAN,EACT,CAiCA,SAAwBnB,GAAO0B,SAC7B,IAAIC,EAAgB,OAAAC,EAAAH,WAAA,EAAAG,EAAeC,MAAMH,GACpCC,IAEHA,EAaJ,SAAsBD,GACpB,OACEA,EAEG9W,QACC,kCACA,CAACqE,EAAG+O,IAAS,cAAc4B,GAAW5B,oBAGvCpT,QAAQ,wBAAwB,CAACqE,EAAG6S,EAAKC,IAAW,aAAaA,WAAgBD,UACjFlX,QACC,uBACA,CAACqE,EAAG0H,EAAM1G,IAAS,YAAYA,sBAAyB0G,UAEzD/L,QAAQ,MAAO,OAEtB,CA7BoBoX,CAAaN,IAG3B,IAAAO,EAAO3D,GAASqD,GAOb,OAJGP,GAAAjF,SAAS+F,IACO,mBAAbA,IAAyBD,EAAOC,EAASD,GAAI,IAGnDA,CACT,CCrDA,MAAME,GAGJ,WAAAC,CAAoBC,GAFZC,EAAAvU,KAAA,QCkBH,WACC,MAAAwU,MAAgBC,IAChBC,MAAsBD,IAMtBE,EAA4C1M,IAC1C,MAAA2M,EAAWJ,EAAUK,IAAI5M,GAC/B,IAAK2M,EACH,MAAM,IAAIE,MAAM,kBAAkBjM,OAAOZ,MAG3C,GAA2B,cAAvB2M,EAASG,WAA6BL,EAAgBM,IAAI/M,GACrD,OAAAyM,EAAgBG,IAAI5M,GAGvB,MAAAgN,KAAEA,EAAMC,KAAAA,GAASN,EAEjBO,EAAWF,KADFC,EAAKE,KAAKC,GAAMV,EAAOU,MAK/B,OAFSX,EAAAY,IAAIrN,EAAKkN,GAElBA,CAAA,EAGF,MAAA,CAAEI,QAvB0C,CAACtN,EAAKgN,EAAMC,EAAM7T,EAAO,MAC1EmT,EAAUc,IAAIrN,EAAK,CAAEgN,OAAMC,KAAMA,GAAQ,GAAIH,UAAW1T,EAAK0T,WAAa,aAAa,EAsBvEJ,SACpB,CD9CkBa,IAkBhBjB,EAAAvU,KAAA,WAA+B,CAACiI,EAAKgN,EAAMC,EAAM7T,KAC/CrB,KAAKyV,MAAMF,QAAQtN,EAAKgN,EAAMC,EAAM7T,EAAI,IAG1CkT,EAAAvU,KAAA,UAA8BiI,GACrBjI,KAAKyV,MAAMd,OAAO1M,KAE3BsM,EAAAvU,KAAA,MAAMA,KAAK2U,QAKUJ,EAAAvU,KAAA,MAAA,CAAC3D,EAAMsP,KAC1B3L,KAAK2U,OAAO,UAAUe,GAAGrZ,EAAMsP,EAAO,IAGjB4I,EAAAvU,KAAA,OAAA,CAAC3D,EAAMsP,KAC5B3L,KAAK2U,OAAO,UAAUgB,IAAItZ,EAAMsP,EAAO,IAGV4I,EAAAvU,KAAA,WAAA,CAAC3D,EAAMuZ,KACpC5V,KAAK2U,OAAO,UAAUkB,QAAQxZ,EAAMuZ,EAAO,IAyF7CrB,EAAAvU,KAAA,iBAAiBA,KAAK8V,iBAKtBvB,EAAAvU,KAAA,qBAAqBA,KAAK+V,aAnIN/V,KAAAsU,OAAAA,CAAsB,CAE1C,KAAA0B,GACE,OAAOhW,KAAKsU,MACd,CAEA,OAAA2B,GAES,IADPjW,KAAK6V,QAAQ,aACN7V,KAAKsU,OAAO4B,YACjBlW,KAAKsU,OAAO6B,YAAYnW,KAAKsU,OAAO4B,WAExC,CAgCA,OAAAE,GACE,OAAOpW,KAAK2U,OAAO,UAAUE,KAC/B,CAEA,UAAAwB,CAAWC,GACTtW,KAAK2U,OAAO,UAAU4B,OAAOD,EAC/B,CAEA,SAAAE,CACErI,EACAsI,GAEAzW,KAAK2U,OAAO,UAAU6B,UAAUrI,EAAMsI,EACxC,CAEA,SAAAC,GACE,OAAOC,IACT,CAEA,WAAAC,CAAYC,GACL7W,KAAAqW,WAAW,CAAEQ,YACpB,CAEA,QAAIP,GACF,OAAOtW,KAAKoW,SACd,CACA,QAAIE,CAAKQ,GACPjX,QAAQD,MAAM,uDAChB,CACA,SAAImX,GACF,OAAO/W,KAAKgW,OACd,CACA,SAAIe,CAAMD,GACRjX,QAAQD,MAAM,0BAChB,CAKA,EAAAtB,CAAG2J,EAAoBC,EAAkC,IAChD8O,OAAAA,EAAO/O,EAAKC,EACrB,CAKA,MAAA+O,GACS,OAAAjX,KAAK2U,OAAO,MACrB,CAEA,cAAAuC,GACS,OAAAlX,KAAK2U,OAAO,cACrB,CAKA,OAAAwC,GACS,OAAAnX,KAAK2U,OAAO,OACrB,CAKA,OAAAyC,GACS,OAAApX,KAAK2U,OAAO,OACrB,CAEA,KAAA0C,CAAMC,GACCtX,KAAAoX,UAAUG,cAAcD,EAC/B,CAEA,MAAAE,GACExX,KAAKoX,UAAUG,cAAc,CAAEE,OAAQ,GACzC,CAKA,aAAAC,GACE1X,KAAK6V,QAAQ,kBACf,CAGA,eAAAC,GACE,OAAO9V,KAAK2U,OAAO,QAAQmB,iBAC7B,CAGA,WAAAC,GACS,OAAA/V,KAAKoX,UAAUrB,aACxB,CAKA,YAAA4B,CAAaC,EAA0BC,GACrC7X,KAAK2U,OAAO,UAAUmD,gBAAgBF,EAAaC,EACrD,CAEA,WAAAE,CAAYH,EAA0BC,GACpC7X,KAAK2U,OAAO,UAAUqD,eAAeJ,EAAaC,EACpD,CAEA,iBAAAI,GACOjY,KAAA2U,OAAO,UAAUuD,aACxB,CAEA,iBAAAC,GACOnY,KAAA2U,OAAO,UAAUyD,aACxB,CAEA,gBAAAC,CAAiBC,EAAKC,GACpBvY,KAAK2U,OAAO,UAAU6D,WAAWF,EAAKC,EACxC,CAEA,gBAAAE,GACOzY,KAAA2U,OAAO,UAAU+D,YACxB,CAKA,WAAAC,CAAY/C,GACV5V,KAAK2U,OAAO,WAAWiE,KAAKhD,EAC9B,CAEA,WAAAiD,GACO7Y,KAAA2U,OAAO,WAAWmE,MACzB,CAKA,UAAAC,CAAWnD,GACT,OAAO5V,KAAK2U,OAAO,YAAYoE,WAAWnD,EAC5C,CAEA,YAAAoD,CAAapD,GACX,OAAO5V,KAAK2U,OAAO,YAAYqE,aAAapD,EAC9C,EEpMK,SAASqD,MAAgBC,GACxB,MAAAC,EAAYC,GAAaA,GAAsB,iBAARA,GAAoBA,EAAI/E,cAAgBlK,OAErF,OAAO+O,EAAQxO,QAAO,CAAC2O,EAAMD,KAC3BjP,OAAOgE,KAAY,MAAPiL,EAAOA,EAAA,CAAE,GAAEhL,SAASnG,IAE9B,GAAY,cAARA,GAA+B,gBAARA,GAAiC,cAARA,EAClD,OAGI,MAAAqR,EAAOD,EAAKpR,GACZsR,EAAOH,EAAInR,GAEb2B,MAAM4P,QAAQF,IAAS1P,MAAM4P,QAAQD,GACvCF,EAAKpR,GAAOqR,EAAKG,UAAUF,GAClBJ,EAASG,IAASH,EAASI,GACpCF,EAAKpR,GAAOgR,GAAUK,EAAMC,GAE5BF,EAAKpR,GAAOsR,CACd,IAGKF,IACN,CAAE,EACP,CC7BO,MAAMK,GAA2D,CACtE3c,GAAI,GACJ4c,QAAS,GACTC,UAAW,GACXpT,OAAQ,GACRqT,KAAM,GAENnY,YAAa,GACbC,UAAW,GACXmY,QAAS,GACTjD,UAAU,EACVkD,cAAc,EAEdC,SAAU,OACVC,QAAS,EACTC,SAAU,WAEVC,UAEI,mEAEJC,UAAU,EAEVC,MAA4B,EAC5B7W,UAAU,EACV8W,SAA+B,EAC/BC,UAAU,EACVnY,SAA+B,EAC/BoY,QAAS,wBACTC,KAAM,mBACNC,gBAAiB,gBAEjBC,SAAU,CACRC,OAAQ,mCACRtD,OAAQ,uBAGVuD,WAAY,CACVC,SAAU,GACVpX,UAAU,EACVqX,UAAU,GAGZC,YAAa,CACXxK,QAAS,IACTyK,SAAU,IACVC,YAAY,GAGdC,WAAW,EACXhI,aAAa,EACbiI,WAAY,KACZC,cAAc,EACdC,gBAAgB,EAChBC,kBAAkB,EAClBC,qBAAqB,EACrBC,OAAO,EACPC,qBAAqB,EAErBC,OAAQ,KACRC,WAAY,GACZC,WAAY,GACZC,gBAAiB,GACjBxI,cAAe,CAAC,GClDF,SAAAyI,GAAiBC,EAA2BC,GAAO,GAEjE,MAAM3F,EAAsB2F,EAAOhD,GAAUS,GAAUsC,GAAcA,EAoB9D,MAjBc,KAAjB1F,EAAKqD,UAAgBrD,EAAKqD,QAAU,GAAGld,OAAOC,SAASwf,YAGpC,KAAnB5F,EAAKsD,cAAuBA,UAAY,GAAGhe,SAASugB,SAGpD7F,EAAK9P,SAAa8P,EAAA9P,OAAS8P,EAAK9P,OAAO3J,QAAQ,MAAO,IAAIA,QAAQ,YAAa,KAG/D,SAAhByZ,EAAKqF,SAAmBrF,EAAKqF,OAASzb,UAAUkc,UAG9B,SAAlB9F,EAAK0D,WAAqB1D,EAAK0D,SAAWvd,OAAO4f,WAAW,sBAAsBnN,SAG1D,iBAAjBoH,EAAK2D,SAAwBvZ,OAAO4V,EAAK2D,UAAY,IAAG3D,EAAK0D,UAAW,GAE5E1D,CACT,CAiEgB,SAAAgG,GACdhG,EACAiG,EACAC,GAEO,MAAA,CACLlb,QAAS,GAAGgV,EAAK9P,gBACjBiW,SAAUnG,EAAKuD,MAAQ,GACvBF,QAASrD,EAAKqD,SAAW,GACzBC,UAAWtD,EAAKsD,WAAa,GAC7B8C,QAASpG,EAAK8E,WACduB,YAAa,IAAM,MAAAJ,OAAA,EAAAA,EAAMnF,UAAUjP,MACnCyU,gBAAUL,WAAMM,yBACZ,CACExgB,WAAMkgB,WAAMnF,UAAU/a,KACtB4F,YAAOsa,WAAMnF,UAAUnV,YAEzB,EACJua,WAEJ,CCrFA,SAAsBM,GAAgBC,GAAmB,OAAAhd,EAAAC,KAAA,MAAA,kBA6BzD,SAAgC+c,GAAmB,OAAAhd,EAAAC,KAAA,MAAA,kBAC3Cgd,GAAc,CAAED,MAAKE,MAAO,eAAgBC,WAAY,CAACH,EAAIvC,QAAS,iBAC9E,GAAA,CA7BQ2C,CAAiBJ,GAGjB,MAAAK,QAOR,SAAgCL,GAAmB,OAAAhd,EAAAC,KAAA,MAAA,YACjD,IAAK+c,EAAItB,QAAUsB,EAAIpD,QAAgB,OAEvC,MAAM0D,SACEN,EAAI9F,SAASqG,MAAMC,MAAM,CAC7BC,SAAUT,EAAIpD,QACd8D,WAAYV,EAAInD,UAChB8D,UAAWX,EAAIN,YAEjBkB,KAAKC,GAEA,MAAA,CACL,CAACb,EAAIpD,SAAU0D,EAEnB,GAAA,CArB0BQ,CAAiBd,SA6B3C,SAA2BA,EAAmBxL,GAAoB,OAAAxR,EAAAC,KAAA,MAAA,kBAC1Dgd,GAAc,CAAED,MAAKE,MAAO,UAAWC,WAAY,CAACH,EAAItC,KAAM,aAAclJ,SACpF,GAAA,CA5BQuM,CAAYf,EAAKK,EACzB,GAAA,CA6BA,SAAeJ,GAAc9U,GAK1B,OAAAnI,EAAAC,KAAA,MAAA,YACK,MAAA+c,IAAEA,GAAQ7U,EACZ,IAAAqJ,EAAoBrJ,EAAKqJ,OAAS,GAGhC,MAAAwM,EAoBR,SAA0Bb,GAClB,MAAAa,MAAUC,IAIT,OAHP,IAAIA,IAAId,GAAY9O,SAAS6P,IAClBriB,SAAAsiB,iBAA8BD,GAAU7P,SAASrR,GAAOghB,EAAII,IAAIphB,IAAG,IAEvEghB,CACT,CA1BcK,CAAiBlW,EAAKgV,YAG5BmB,EA0BR,SACEN,EACAO,EACA3E,EACApI,GAEM,MAAA8M,EAAWzU,MAAM2U,KAAKR,GACzB3I,KAAKrY,GAAOA,EAAGyhB,aAAaF,IAAgB3E,IAC5C1L,QAAQhG,GAAQA,GAA6B,iBAAfsJ,EAAMtJ,KAEvC,MAAO,IAAI,IAAI+V,IAAIK,GACrB,CArCmBI,CAAYV,EAAKhB,EAAIuB,YAAavB,EAAIpD,QAASpI,GAG5D,GAAA8M,EAASlgB,OAAS,EAAG,CACjB,MAAAugB,SACE3B,EAAI9F,SAAS0H,MAAMC,SAAS1W,EAAK+U,MAAO,CAC5C4B,UAAWR,EAASzP,KAAK,KACzB8O,UAAWX,EAAIN,YAEjBkB,KAAKA,KACPpM,EAAQuN,OAAKvN,GAAUmN,EACzB,EA6BF,SAA4BX,EAAuBJ,EAAkBoB,GAC/DhB,EAAA3P,SAASrR,IACL,MAAA4c,EAAU5c,EAAGyhB,aAAa,iBAC1BQ,EAASrF,GAAWgE,EAAKhE,IAAcoF,GAAkBpB,EAAKoB,IAAoB,EACxFhiB,EAAGZ,UAAY,GAAGuE,OAAOse,IAAM,GAEnC,CAjCqBC,CAAAlB,EAAKxM,EAAOwL,EAAIpD,QACrC,GAAA,CC8hBO,MAAMuF,GAcX,WAAA7K,CAAY8K,EAAyC,IAb5B5K,EAAAvU,KAAA,UAAA,WACuBuU,EAAAvU,KAAA,eAAA,MACxCuU,EAAAvU,KAAA,kBACAuU,EAAAvU,KAAA,uBAAuByU,KACvBF,EAAAvU,KAAA,eAAc,IAAIof,IAA0C/H,SAAS+H,KAEtC7K,EAAAvU,KAAA,gBAAA,CACrCqf,YAAa,cACbC,QAAS,CAAC,EACVC,SAAU,SACVC,eAAgB,gBAOXjL,EAAAvU,KAAA,mBAAmB2d,IACxB3d,KAAKyf,aAAe9B,CAAA,IAkCgDpJ,EAAAvU,KAAA,oBAAA,CACpE,mBAAqBoR,GACT,OAAVA,GAAoC,iBAAVA,GAAuC,iBAAVA,EAEnDA,EADAsO,KAAKC,UAAUvO,GAErB,aAAqBA,GACT,OAAVA,GAAmC,iBAAVA,EAAqBsO,KAAKC,UAAUvO,GAASA,EACxE,sBAAyBA,GACvBjH,OAAOgE,KAAKiD,GAAS,CAAA,GAAI1G,QAAO,CAACkV,EAAU3X,KACnC,MAAA4X,EAAWzO,EAAMnJ,GAShB,OARE2X,EAAAE,OACP7X,EACA4X,aAAoBE,KAChBF,EACoB,iBAAbA,GAAsC,OAAbA,EAC9BH,KAAKC,UAAUE,GACf,GAAGA,KAEJD,CAAA,GACN,IAAII,UACT,oCAA2B5O,GAAepR,KAAKigB,cAAc7O,KAgBrDmD,EAAAvU,KAAA,qBAAqBkgB,IAC7B,GAAIlgB,KAAKmgB,iBAAiBnL,IAAIkL,GAAc,CAC1C,MAAME,EAAkBpgB,KAAKmgB,iBAAiBtL,IAAIqL,GAClD,OAAIE,EACKA,EAAgBC,YAElB,CACT,CAEM,MAAAD,EAAkB,IAAIE,gBAE5B,OADKtgB,KAAAmgB,iBAAiB7K,IAAI4K,EAAaE,GAChCA,EAAgBC,MAAA,IAGlB9L,EAAAvU,KAAA,gBAAgBkgB,IACrB,MAAME,EAAkBpgB,KAAKmgB,iBAAiBtL,IAAIqL,GAE9CE,IACFA,EAAgBG,QACXvgB,KAAAmgB,iBAAiB9b,OAAO6b,GAC/B,IAGK3L,EAAAvU,KAAA,WAAmC6T,GAUY9T,EAAAC,KAAA,MAAA,YATpD,IAAAwgB,EAAA3M,GAAA4M,KAAAA,EAAAC,OACAA,EAAAlf,KACAA,EAAA+W,KACAA,EAAA0E,MACAA,EAAA0D,OACAA,EAAAC,QACAA,EAAAV,YACAA,GARwCM,EASrClJ,+JAAAuJ,CATqCL,EASrC,CARH,OACA,SACA,OACA,OACA,QACA,SACA,UACA,gBAGA,MAAMM,GACgB,kBAAXJ,EAAuBA,EAAS1gB,KAAK+gB,cAAcL,SAC1D1gB,KAAKghB,uBACEhhB,KAAKghB,eAAehhB,KAAKyf,gBAClC,GACIwB,EAAgBjhB,KAAKkhB,mBAAmB5J,EAAQwJ,GAChDK,EAAclE,GAASjd,KAAKigB,cAAchD,GAC1CmE,EAAmBphB,KAAKqhB,kBAAkB9I,GAAQ,oBAClD+I,EAAiBX,GAAUM,EAAcN,OAE/C,OAAO3gB,KAAKuhB,YACV,GAAGX,GAAW5gB,KAAK4gB,SAAW,KAAKpf,IAAO2f,EAAc,IAAIA,IAAgB,KAC5EK,OACKP,GADL,CAEE3B,QAASR,EAAAA,EAAA,CAAA,EACHmC,EAAc3B,SAAW,CAAC,GAC1B/G,GAAiB,wBAATA,EAAgC,CAAE,eAAgBA,GAAS,CAAC,GAE1E8H,QAASH,EAAclgB,KAAKyhB,kBAAkBvB,GAAee,EAAcZ,SAAW,KACtFI,KAAM,MAAOA,EAAwC,KAAOW,EAAiBX,MAE/EiB,MAAYC,GAAa5hB,EAAAC,KAAA,MAAA,YACnB,MAAA4hB,EAAID,EAASE,QACnBD,EAAEjE,KAAO,KACTiE,EAAEhiB,MAAQ,KAEJ,MAAA+d,EAAQ2D,QAEJK,EAASL,KACZI,MAAM/D,IACDiE,EAAEE,GACJF,EAAEjE,KAAOA,EAETiE,EAAEhiB,MAAQ+d,EAELiE,KAERG,OAAOrP,IACNkP,EAAEhiB,MAAQ8S,EACHkP,KAZXA,EAmBA,GAJA1B,GACGlgB,KAAAmgB,iBAAiB9b,OAAO6b,IAG1ByB,EAASG,GAAU,MAAAnE,EACjB,OAAAA,CAAA,KACR,MA5JMxT,OAAAsB,OAAOzL,KAAMmf,EACtB,CAMU,gBAAA6C,CAAiB/Z,EAAaoG,GAE/B,MAAA,GADY4T,mBAAmBha,MACdga,mBAAoC,iBAAV5T,EAAqBA,EAAQ,GAAGA,MACpF,CAEU,aAAA6T,CAAcjF,EAAwBhV,GAC9C,OAAOjI,KAAKgiB,iBAAiB/Z,EAAKgV,EAAMhV,GAC1C,CAEU,kBAAAka,CAAmBlF,EAAwBhV,GAE5C,OADOgV,EAAMhV,GACPmN,KAAKgN,GAAWpiB,KAAKgiB,iBAAiB/Z,EAAKma,KAAIxT,KAAK,IACnE,CAEU,aAAAqR,CAAcoC,GAChB,MAAApF,EAAQoF,GAAY,GAE1B,OADalY,OAAOgE,KAAK8O,GAAOhP,QAAQhG,QAAQ,IAAuBgV,EAAMhV,KAE1EmN,KAAKnN,GACJ2B,MAAM4P,QAAQyD,EAAMhV,IAChBjI,KAAKmiB,mBAAmBlF,EAAOhV,GAC/BjI,KAAKkiB,cAAcjF,EAAOhV,KAE/B2G,KAAK,IACV,CAEU,cAAA0T,CAAeD,GACjB,MAAAlB,EAAcnhB,KAAKigB,cAAcoC,GAChC,OAAAlB,EAAc,IAAIA,IAAgB,EAC3C,CAyBU,kBAAAD,CAAmBqB,EAAwBC,GAC5C,OAAAhB,WACFxhB,KAAK+gB,eACLwB,GACCC,GAAW,CAAC,GAHX,CAILlD,QAASR,EAAAA,EAAAA,EAAA,CAAA,EACH9e,KAAK+gB,cAAczB,SAAW,CAAC,GAC/BiD,EAAQjD,SAAW,CAAC,GACnBkD,GAAWA,EAAQlD,SAAY,CAAC,IAG3C;;;;;;;;;UAiGK,cAAoDJ,GAApD,WAAA7K,GAAAoO,SAAAzY,WACEuK,EAAAvU,KAAA,OAAA,CAkBL0iB,aAAc,CAAC/E,EAAoCrG,EAAwB,CAAA,IACzEtX,KAAK2iB,QAKH7D,EAAA,CACAtd,KAAM,oBACNohB,OAAQ,OACRnC,KAAM9C,EACNpF,KAAM,mBACNoI,OAAQ,QACLrJ,IAoBPuL,gBAAiB,CAAClF,EAAuCrG,EAAwB,CAAA,IAC/EtX,KAAK2iB,QAKH7D,EAAA,CACAtd,KAAM,uBACNohB,OAAQ,OACRnC,KAAM9C,EACNpF,KAAM,mBACNoI,OAAQ,QACLrJ,IAuBPwL,gBAAiB,CAACnF,EAAmCrG,EAAwB,CAAA,IAC3EtX,KAAK2iB,QAOH7D,EAAA,CACAtd,KAAM,mBACNohB,OAAQ,OACRnC,KAAM9C,EACNpF,KAAM,mBACNoI,OAAQ,QACLrJ,IAqBPyL,eAAgB,CAACzL,EAAwB,KACvCtX,KAAK2iB,QAKH7D,EAAA,CACAtd,KAAM,cACNohB,OAAQ,MACRlC,QAAQ,EACRC,OAAQ,QACLrJ,IAqBP0L,eAAgB,CAACrF,EAAwCrG,EAAwB,CAAA,IAC/EtX,KAAK2iB,QAKH7D,EAAA,CACAtd,KAAM,cACNohB,OAAQ,OACRnC,KAAM9C,EACN+C,QAAQ,EACRnI,KAAM,mBACNoI,OAAQ,QACLrJ,MAGD/C,EAAAvU,KAAA,QAAA,CAsBNijB,WAAY,CAAC3L,EAAwB,KACnCtX,KAAK2iB,QAOH7D,EAAA,CACAtd,KAAM,eACNohB,OAAQ,OACRlC,QAAQ,EACRC,OAAQ,QACLrJ,IAwBP4L,YAAa,CAAC5L,EAAwB,KACpCtX,KAAK2iB,QAOH7D,EAAA,CACAtd,KAAM,iBACNohB,OAAQ,OACRlC,QAAQ,EACRC,OAAQ,QACLrJ,MAGC/C,EAAAvU,KAAA,UAAA,CAcRmjB,WAAY,CAAC7L,EAAwB,KACnCtX,KAAK2iB,QAKH7D,EAAA,CACAtd,KAAM,WACNohB,OAAQ,MACRjC,OAAQ,QACLrJ,IAYP8L,iBAAkB,CAAC9L,EAAwB,KACzCtX,KAAK2iB,QAA2C7D,EAAA,CAC9Ctd,KAAM,kBACNohB,OAAQ,MACRjC,OAAQ,QACLrJ,IAgBP+L,cAAe,CAAC1F,EAAkCrG,EAAwB,CAAA,IACxEtX,KAAK2iB,QAKH7D,EAAA,CACAtd,KAAM,kBACNohB,OAAQ,OACRnC,KAAM9C,EACNpF,KAAM,mBACNoI,OAAQ,QACLrJ,MAGE/C,EAAAvU,KAAA,WAAA,CAeT+V,YAAa,CACXkH,EA0BA3F,EAAwB,CAAA,IAExBtX,KAAK2iB,QAKH7D,EAAA,CACAtd,KAAM,YACNohB,OAAQ,MACR3F,QACAyD,QAAQ,EACRnI,KAAM,mBACNoI,OAAQ,QACLrJ,IAqBPgM,cAAe,CAAClX,EAAqCkL,EAAwB,CAAA,IAC3EtX,KAAK2iB,QAKH7D,EAAA,CACAtd,KAAM,YACNohB,OAAQ,OACRnC,KAAMrU,EACNsU,QAAQ,EACRnI,KAAM,mBACNoI,OAAQ,QACLrJ,IAoBPiM,WAAY,CAACC,EAAYlM,EAAwB,CAAA,IAC/CtX,KAAK2iB,QAKH7D,EAAA,CACAtd,KAAM,aAAagiB,IACnBZ,OAAQ,MACRrK,KAAM,mBACNoI,OAAQ,QACLrJ,IA6BPmM,cAAe,CAACD,EAAYpX,EAAqCkL,EAAwB,CAAC,IACxFtX,KAAK2iB,QAKH7D,EAAA,CACAtd,KAAM,aAAagiB,IACnBZ,OAAQ,MACRnC,KAAMrU,EACNsU,QAAQ,EACRnI,KAAM,mBACNoI,OAAQ,QACLrJ,IAyBPoM,cAAe,CAACF,EAAYlM,EAAwB,CAAA,IAClDtX,KAAK2iB,QAKH7D,EAAA,CACAtd,KAAM,aAAagiB,IACnBZ,OAAQ,SACRlC,QAAQ,EACRC,OAAQ,QACLrJ,MAGF/C,EAAAvU,KAAA,OAAA,CAULsW,KAAM,CAACgB,EAAwB,KAC7BtX,KAAK2iB,QAA6B7D,EAAA,CAChCtd,KAAM,QACNohB,OAAQ,MACRjC,OAAQ,QACLrJ,IAgBPqM,wBAAyB,CAACrM,EAAwB,KAChDtX,KAAK2iB,QAKH7D,EAAA,CACAtd,KAAM,uBACNohB,OAAQ,MACRjC,OAAQ,QACLrJ,IAYPsM,UAAW,CACT3G,EAIA3F,EAAwB,CAAA,IAExBtX,KAAK2iB,QAAwC7D,EAAA,CAC3Ctd,KAAM,eACNohB,OAAQ,MACR3F,QACA0D,OAAQ,QACLrJ,MAGE/C,EAAAvU,KAAA,WAAA,CAkBT6jB,YAAa,CACX5G,EAMA3F,EAAwB,CAAA,IAExBtX,KAAK2iB,QAKH7D,EAAA,CACAtd,KAAM,YACNohB,OAAQ,MACR3F,QACA1E,KAAM,mBACNoI,OAAQ,QACLrJ,IAoBPwM,kBAAmB,CAAC9a,EAAqCsO,EAAwB,CAAA,IAC/EtX,KAAK2iB,QAKH7D,EAAA,CACAtd,KAAM,iBACNohB,OAAQ,OACRnC,KAAMzX,EACNuP,KAAM,mBACNoI,OAAQ,QACLrJ,IAwBPyM,eAAgB,CAACC,EAAmBC,EAAmB3M,EAAwB,CAAC,IAC9EtX,KAAK2iB,QAKH7D,EAAA,CACAtd,KAAM,aAAawiB,KAAaC,IAChCrB,OAAQ,OACRjC,OAAQ,QACLrJ,MAGD/C,EAAAvU,KAAA,QAAA,CAeNkkB,SAAU,CACRjH,EAUA3F,EAAwB,CAAA,IAExBtX,KAAK2iB,QAKH7D,EAAA,CACAtd,KAAM,SACNohB,OAAQ,MACR3F,QACAyD,QAAQ,EACRnI,KAAM,mBACNoI,OAAQ,QACLrJ,IAqBP6M,cAAe,CAACnb,EAAoCsO,EAAwB,CAAA,IAC1EtX,KAAK2iB,QAKH7D,EAAA,CACAtd,KAAM,eACNohB,OAAQ,OACRnC,KAAMzX,EACN0X,QAAQ,EACRnI,KAAM,mBACNoI,OAAQ,QACLrJ,IAaP8M,mBAAoB,CAAC9M,EAAwB,KAC3CtX,KAAK2iB,QAA6C7D,EAAA,CAChDtd,KAAM,sBACNohB,OAAQ,MACRlC,QAAQ,EACRC,OAAQ,QACLrJ,IAYPiG,MAAO,CAAC8G,EAA2B/M,EAAwB,CAAA,IACzDtX,KAAK2iB,QAAoC7D,EAAA,CACvCtd,KAAM,YACNohB,OAAQ,OACRnC,KAAM4D,EACN9L,KAAM,mBACNoI,OAAQ,QACLrJ,IA6BPgN,WAAY,CAACd,EAAYa,EAA+B/M,EAAwB,CAAC,IAC/EtX,KAAK2iB,QAKH7D,EAAA,CACAtd,KAAM,UAAUgiB,IAChBZ,OAAQ,MACRnC,KAAM4D,EACN3D,QAAQ,EACRnI,KAAM,mBACNoI,OAAQ,QACLrJ,IAyBPiN,WAAY,CAACf,EAAYlM,EAAwB,CAAA,IAC/CtX,KAAK2iB,QAKH7D,EAAA,CACAtd,KAAM,UAAUgiB,IAChBZ,OAAQ,SACRlC,QAAQ,EACRC,OAAQ,QACLrJ,IAqBPkN,UAAW,CAAChB,EAAYlM,EAAwB,CAAA,IAC9CtX,KAAK2iB,QAKH7D,EAAA,CACAtd,KAAM,UAAUgiB,UAChBZ,OAAQ,OACRlC,QAAQ,EACRnI,KAAM,mBACNoI,OAAQ,QACLrJ,MAGG/C,EAAAvU,KAAA,YAAA,CAgBVykB,UAAW,CAACxiB,EAA+BqV,EAAwB,CAAA,IACjEtX,KAAK2iB,QAMH7D,EAAA,CACAtd,KAAM,cACNohB,OAAQ,OACRnC,KAAMxe,EACNye,QAAQ,EACRnI,KAAM,mBACNoI,OAAQ,QACLrJ,MAGE/C,EAAAvU,KAAA,WAAA,CAmBT0kB,YAAa,CAACpN,EAAwB,KACpCtX,KAAK2iB,QAKH7D,EAAA,CACAtd,KAAM,YACNohB,OAAQ,MACRlC,QAAQ,EACRC,OAAQ,QACLrJ,IAqBPqN,cAAe,CAACC,EAAqCtN,EAAwB,CAAA,IAC3EtX,KAAK2iB,QAKH7D,EAAA,CACAtd,KAAM,YACNohB,OAAQ,MACRnC,KAAMmE,EACNlE,QAAQ,EACRnI,KAAM,mBACNoI,OAAQ,QACLrJ,IAaPuN,oBAAqB,CAAClJ,EAAgBrE,EAAwB,CAAA,IAC5DtX,KAAK2iB,QAA6C7D,EAAA,CAChDtd,KAAM,sBAAsBma,IAC5BiH,OAAQ,MACRlC,QAAQ,EACRC,OAAQ,QACLrJ,MAGD/C,EAAAvU,KAAA,QAAA,CAWN8kB,SAAU,CAACxN,EAAwB,KACjCtX,KAAK2iB,QAAsC7D,EAAA,CACzCtd,KAAM,SACNohB,OAAQ,MACRlC,QAAQ,EACRC,OAAQ,QACLrJ,IAyBPyN,WAAY,CAAClL,EAA+BvC,EAAwB,CAAA,IAClEtX,KAAK2iB,QAKH7D,EAAA,CACAtd,KAAM,SACNohB,OAAQ,OACRnC,KAAM5G,EACN6G,QAAQ,EACRnI,KAAM,mBACNoI,OAAQ,QACLrJ,IAaP0N,WAAY,CAACxB,EAAY3J,EAA+BvC,EAAwB,CAAC,IAC/EtX,KAAK2iB,QAAwC7D,EAAA,CAC3Ctd,KAAM,UAAUgiB,IAChBZ,OAAQ,MACRnC,KAAM5G,EACN6G,QAAQ,EACRnI,KAAM,mBACNoI,OAAQ,QACLrJ,IAyBP2N,WAAY,CAACzB,EAAYlM,EAAwB,CAAA,IAC/CtX,KAAK2iB,QAKH7D,EAAA,CACAtd,KAAM,UAAUgiB,IAChBZ,OAAQ,SACRlC,QAAQ,EACRC,OAAQ,QACLrJ,MAGD/C,EAAAvU,KAAA,QAAA,CA0BN4e,SAAU,CACRrG,EAWA0E,EAQA3F,EAAwB,CAAC,IAEzBtX,KAAK2iB,QAKH7D,EAAA,CACAtd,KAAM,UAAU+W,IAChBqK,OAAQ,MACR3F,QACA1E,KAAM,mBACNoI,OAAQ,QACLrJ,MAGE/C,EAAAvU,KAAA,WAAA,CAeTklB,cAAe,CAAC5N,EAAwB,KACtCtX,KAAK2iB,QAKH7D,EAAA,CACAtd,KAAM,mBACNohB,OAAQ,MACRlC,QAAQ,EACRC,OAAQ,QACLrJ,IAaP6N,cAAe,CAACxH,EAAmCrG,EAAwB,CAAA,IACzEtX,KAAK2iB,QAAqB7D,EAAA,CACxBtd,KAAM,mBACNohB,OAAQ,OACRnC,KAAM9C,EACN+C,QAAQ,EACRnI,KAAM,oBACHjB,IAoBP8N,cAAe,CACbzH,EAOArG,EAAwB,CAAA,IAExBtX,KAAK2iB,QAOH7D,EAAA,CACAtd,KAAM,mBACNohB,OAAQ,OACRnC,KAAM9C,EACN+C,QAAQ,EACRnI,KAAM,sBACNoI,OAAQ,QACLrJ,MAGA/C,EAAAvU,KAAA,SAAA,CAuBPqlB,OAAQ,CACN1H,EAOArG,EAAwB,CAAA,IAExBtX,KAAK2iB,QAKH7D,EAAA,CACAtd,KAAM,UACNohB,OAAQ,OACRnC,KAAM9C,EACN+C,QAAQ,EACRnI,KAAM,sBACNoI,OAAQ,QACLrJ,MAGF/C,EAAAvU,KAAA,OAAA,CAeLmX,QAAS,CACP8F,EAMA3F,EAAwB,CAAA,IAExBtX,KAAK2iB,QAKH7D,EAAA,CACAtd,KAAM,QACNohB,OAAQ,MACR3F,QACAyD,QAAQ,EACRC,OAAQ,QACLrJ,IAqBPgO,cAAe,CAAC3H,EAAoCrG,EAAwB,CAAA,IAC1EtX,KAAK2iB,QAKH7D,EAAA,CACAtd,KAAM,QACNohB,OAAQ,OACRnC,KAAM9C,EACN+C,QAAQ,EACRnI,KAAM,mBACNoI,OAAQ,QACLrJ,IA4BPiO,MAAO,CAAChJ,EAA8BjF,EAAwB,CAAA,IAC5DtX,KAAK2iB,QAWH7D,EAAA,CACAtd,KAAM,qBACNohB,OAAQ,OACRnC,KAAMlE,EACNhE,KAAM,mBACNoI,OAAQ,QACLrJ,IAaPkO,cAAe,CACbvI,EAMA3F,EAAwB,CAAA,IAExBtX,KAAK2iB,QAAwC7D,EAAA,CAC3Ctd,KAAM,eACNohB,OAAQ,MACR3F,QACAyD,QAAQ,EACRC,OAAQ,QACLrJ,MAGD/C,EAAAvU,KAAA,QAAA,CAuBNylB,WAAY,CAAClJ,EAA+BjF,EAAwB,CAAA,IAClEtX,KAAK2iB,QAKH7D,EAAA,CACAtd,KAAM,SACNohB,OAAQ,OACRnC,KAAMlE,EACNmE,QAAQ,EACRnI,KAAM,mBACNoI,OAAQ,QACLrJ,IA6BPoO,WAAY,CAAClC,EAAYjH,EAA+BjF,EAAwB,CAAC,IAC/EtX,KAAK2iB,QAKH7D,EAAA,CACAtd,KAAM,UAAUgiB,IAChBZ,OAAQ,MACRnC,KAAMlE,EACNmE,QAAQ,EACRnI,KAAM,mBACNoI,OAAQ,QACLrJ,IAyBPqO,WAAY,CAACnC,EAAYlM,EAAwB,CAAA,IAC/CtX,KAAK2iB,QAKH7D,EAAA,CACAtd,KAAM,UAAUgiB,IAChBZ,OAAQ,SACRlC,QAAQ,EACRC,OAAQ,QACLrJ,IAiBPsO,SAAU,CACRrN,EACA0E,EAQA3F,EAAwB,CAAC,IAEzBtX,KAAK2iB,QAKH7D,EAAA,CACAtd,KAAM,UAAU+W,IAChBqK,OAAQ,MACR3F,QACAyD,QAAQ,EACRnI,KAAM,mBACNoI,OAAQ,QACLrJ,MAGC/C,EAAAvU,KAAA,UAAA,CAUR6lB,WAAY,CAACvO,EAAwB,KACnCtX,KAAK2iB,QAAmC7D,EAAA,CACtCtd,KAAM,WACNohB,OAAQ,MACRjC,OAAQ,QACLrJ,MAGD/C,EAAAvU,KAAA,QAAA,CAeN8lB,UAAW,CAACxO,EAAwB,KAClCtX,KAAK2iB,QAKH7D,EAAA,CACAtd,KAAM,cACNohB,OAAQ,OACRlC,QAAQ,EACRC,OAAQ,QACLrJ,IAwBPyO,QAAS,CAACC,EAAgCC,EAAkB3O,EAAwB,CAAC,IACnFtX,KAAK2iB,QAKH7D,EAAA,CACAtd,KAAM,UAAUwkB,KAAcC,IAC9BrD,OAAQ,MACRrK,KAAM,mBACNoI,OAAQ,QACLrJ,IAwBP4O,WAAY,CACVF,EACAC,EACAE,EACA9L,EACA/C,EAAwB,CAAA,IAExBtX,KAAK2iB,QAKH7D,EAAA,CACAtd,KAAM,UAAUwkB,KAAcC,KAAYE,IAC1CvD,OAAQ,OACRnC,KAAMpG,EACN9B,KAAM,mBACNoI,OAAQ,QACLrJ,KACJ,GChjFA,MAAM8O,GAAQ,CACnB/kB,EACA+P,EACAiV,IACGtmB,EAAA0Q,QAAA,MAAA,YACH,MAAM6V,EAAWjlB,EAAKsb,aAAetb,EAAKsb,cAEpC2C,EAAU,IAAIiH,QAAQzH,EAAA,CAC1B0H,cAAeF,EAAW,UAAUA,IAAa,IAC9C,MAAAD,OAAAA,EAAAA,EAAM/G,UAGNA,EAAQzK,IAAI,kBAAkByK,EAAQjb,OAAO,iBAG5C,MAAAoiB,QAAapP,MAAMjG,EAAOoQ,OAC3B6E,GAD2B,CAE9B/G,aAGE,IAACmH,EAAK3E,GAAI,CAEZ,MAAM4E,SAAmBD,EAAKC,OAAO3E,OAAM,WAAc,CAAA,EAEzD,IAAI4E,GAAQ,EAUZ,GATKtlB,EAAAmb,iBACInb,EAAKmb,SAAS3H,MAAMnK,QAAO,CAAOkc,EAASld,IAAS3J,EAAA0Q,QAAA,MAAA,kBACnDmW,GACoB,IAAtBF,EAAKhd,EAAKmd,gBACNnd,EAAKiC,QAAQ+a,GACXC,GAAA,EACV,KACCG,QAAQC,YAETJ,EAAO,OAAOP,GAAM/kB,EAAM+P,EAAOiV,GAC/B,MAYV,SAAqBpW,EAAc0N,GAC3B,MAAAnd,EAAM,IAAIwmB,GAKT,OAJPxmB,EAAIymB,QAAUtJ,EAAKrF,KAAOqF,EAAKsJ,SAAW,cAC1CzmB,EAAIyP,KAAOA,EACXzP,EAAImd,KAAOA,EACX9d,QAAQD,MAAMY,GACPA,CACT,CAnBU0mB,CAAYT,EAAKU,OAAQT,EACjC,CAEO,OAAAD,CACT,IAEO,MAAMO,WAAuBlS,MAA7B,WAAAT,GAAAoO,SAAAzY,WACUuK,EAAAvU,KAAA,OAAA,GACGuU,EAAAvU,KAAA,UAAA,eAClBuU,EAAAvU,KAAA,OAAA,ECxCK,MAAMonB,WAAYC,GAGvB,WAAAhT,CAAYhT,GACJohB,MAAA,CACJ7B,QAASvf,EAAKC,QACdigB,YAAa,CAACnQ,EAAOiV,IAASD,GAAM/kB,EAAM+P,EAAOiV,KAL7C9R,EAAAvU,KAAA,SAQNA,KAAKsnB,MAAQjmB,CACf,CAOA,aAAAkmB,GACQ,MAAAhL,EAAOvc,KAAKsnB,MAAM1K,SACxB,IAAW,MAANL,OAAM,EAAAA,EAAAlgB,QAAS,MAAAkgB,OAAA,EAAAA,EAAMta,OAC1B,MAAO,CAAE5F,KAAMkgB,EAAKlgB,KAAM4F,MAAOsa,EAAKta,MACxC,ECrBK,MAAMulB,GAOX,WAAAnT,CAAsBoT,GANtBlT,EAAAvU,KAAA,QACAuU,EAAAvU,KAAA,UAEAuU,EAAAvU,KAAA,yBAGsBA,KAAAynB,IAAAA,CAAe,CAGrC,MAAAC,CAAO3e,EAAe,eAEpB,OADA/I,KAAK2nB,KAAOC,EAAoB,8BAA8B7e,YACvD/I,KAAK2nB,IACd,CAGA,QAAAE,CAAS9e,EAAe,eAEtB,OADK/I,KAAA8nB,OAASF,EAAoB7e,GAC3B/I,KAAK8nB,MACd,CAGA,qBAAAC,CAAsBC,GACpBhoB,KAAKioB,mBAAqBD,CAC5B,CAGA,YAAAE,CAAaF,GACXhoB,KAAKynB,IAAIU,YAAYzS,GAAG,cAAe0S,IACjCA,IAAUpoB,YAElB,CAGA,YAAAqoB,CAAaL,GACXhoB,KAAKynB,IAAIU,YAAYzS,GAAG,cAAe0S,IACjCA,IAAUpoB,YAElB,CAGA,oBAAAsoB,CAAqBC,EAAwBC,GAC3CxoB,KAAKyoB,sBAAwBF,EAC7BvoB,KAAK0oB,kBAAoBF,CAC3B,EC/CF,MAAMG,GAAkB,gBCAxB,MAAqBC,GACnB,WAAAvU,CAAoBoT,GAAAznB,KAAAynB,IAAAA,CAAe,CAE7B,MAAAoB,GAAS,OAAA9oB,EAAAC,KAAA,MAAA,YAMN,aAJCA,KAAKynB,IAAIqB,SAASC,SAASzF,cAAcxE,EACzC,CAAA,QAAM9e,KAAKgpB,wBAEjBrL,IAEJ,GAAA,CAEM,kBAAAqL,GAAqB,OAAAjpB,EAAAC,KAAA,MAAA,YACnB,MAAA3D,KAAEA,QAAM4F,EAAOC,KAAAA,GAASlC,KAAKynB,IAAIwB,UAAU7R,UAC3Cd,EAAOtW,KAAKynB,IAAIyB,UAEf,MAAA,CACL1Y,QAASxQ,KAAKynB,IAAI0B,YAAYC,kBAC9B/sB,OACA4F,QACAC,OACAmnB,IAAK,EACL7L,SAAUlH,EAAKqD,QACf8D,WAAYnH,EAAKsD,UACjB8D,UAAWpH,EAAKuD,KAChByP,SAAUC,IAEd,GAAA,CAEA,aAAAC,CAAcC,GAEZzpB,KAAKynB,IAAIiC,UAAUC,cAAcF,EACnC,ECtBF,MAAqBG,WAAepC,GAIlC,WAAAnT,CAAYoT,GACVhF,MAAMgF,GAJAlT,EAAAvU,KAAA,UAA0B,IAC1BuU,EAAAvU,KAAA,iBAKNA,KAAK6pB,cAAgB,IAAIjB,GAAgB5oB,KAAKynB,KAExC,MAAAqC,EAAiB,IAAM9pB,KAAK+pB,KAE7B/pB,KAAAynB,IAAIuC,YAAW,KAElBhqB,KAAKynB,IAAIU,YAAYzS,GAAG,gBAAiBoU,EAAc,IAEpD9pB,KAAAynB,IAAIwC,cAAa,KACpBjqB,KAAKynB,IAAIU,YAAYxS,IAAI,gBAAiBmU,EAAc,GAE5D,CAEA,cAAAI,CAAeC,GACRnqB,KAAAoqB,QAAQ9c,KAAK6c,EACpB,CAEc,KAAK,OAAApqB,EAAAC,KAAA,MAAA,YACb,GAAkD,KAAlDA,KAAKynB,IAAI0B,YAAYC,kBAAkBttB,OAEzC,YADKkE,KAAAynB,IAAI0B,YAAYkB,QAIjB,MAAAC,EAAStqB,KAAKoqB,QAAQG,MAAMzc,GAAMA,EAAE0c,eAErCxqB,KAAAynB,IAAI0B,YAAYjR,cAEjB,IAIE,IAAAuS,GAFA,MAAAH,OAAA,EAAAA,EAAQI,MAAKJ,EAAOI,MAKID,GAAhB,MAARH,OAAQ,EAAAA,EAAAK,WAAsBL,EAAOK,YACnB3qB,KAAK6pB,cAAchB,UAG7B,MAARyB,OAAQ,EAAAA,EAAAM,MAAaN,EAAAM,KAAKH,GACzBzqB,KAAK6pB,cAAcL,cAAciB,SAC/BjqB,GAIP,OAFAX,QAAQD,MAAMY,QACdR,KAAKynB,IAAI0B,YAAY3Q,WAAW,GAAGla,EAAG,mBAAmBkC,EAAIymB,SAAWpe,OAAOrI,KAAQ,IACvF,CACA,QACKR,KAAAynB,IAAI0B,YAAY/Q,aACvB,CAEKpY,KAAAynB,IAAI0B,YAAY3Z,QACrBxP,KAAKynB,IAAIU,YAAYtS,QAAQ,mBAC/B,GAAA,ECrEF,MAAqBgV,WAAcrD,GAAnC,WAAAnT,GAAAoO,SAAAzY,WACoBuK,EAAAvU,KAAA,WAAA,EAAA,CAElB,IAAA8qB,CAAKC,GACH,GAAI/qB,KAAKgrB,QAAS,OAClBhrB,KAAKgrB,SAAU,EAEf,MAAMC,EAAWjrB,KAAKynB,IAAIyD,QAAQC,IAEzBF,EAAAG,MAAMxD,EAAoB,sDAE7B,MAAAyD,EAAezD,EAAoB,eACzCmD,EAAQK,MAAMC,GACdA,EAAaC,YAAYL,GAEhBA,EAAAM,UAAUpN,IAAI,eACd8M,EAAAM,UAAUpN,IAAI,mBACzB,CAEA,IAAAqN,SACOxrB,KAAKgrB,UACVhrB,KAAKgrB,SAAU,EACV,OAAAnX,EAAA7T,KAAAynB,IACFgE,kBACAC,cAAc,oCAFZ7X,EAGDyX,YAAYtrB,KAAKynB,IAAIyD,QAAQC,KACjCnrB,KAAKynB,IAAIyD,QAAQC,IAAII,UAAUI,OAAO,oBACxC,EC1Bc,SAAAzT,GAAY0T,EAAyBtV,GAE/C,IAAAuV,EAAWD,EAAWF,cAA2B,yBAChDG,IACQjE,EAAAA,EACT,+PAMQ,MAANtR,OAAM,EAAAA,EAAAwV,iBAAwBD,EAAAvb,MAAMyb,WAAa,eACrDH,EAAWI,YAAYH,IAEzBA,EAASvb,MAAM2b,QAAU,GAGnB,MAAAC,EAAWL,EAASH,cAA2B,wBACjDQ,IACFA,EAAS5b,MAAM2b,QAAU,OACzBxvB,OAAO0vB,YAAW,KACZD,EAASE,cAAsBF,EAAA5b,MAAM2b,QAAU,GAAA,GAClD,KAEP,CAGO,SAAS7T,GAAYwT,GACpB,MAAAC,EAAWD,EAAWF,cAA2B,yBACnDG,IAAmBA,EAAAvb,MAAM2b,QAAU,OACzC,CAGgB,SAAAI,GAAWvV,EAAc8U,GACnC9U,KAAiB8U,MACJA,EACnB,CAiBO,SAASU,GACdC,EACAC,GAAsB,EACtBxvB,GAEI,IAAAU,EAEJ,GAAIV,EAAY,CACR,MAAAyvB,EAAgBzvB,EAAWI,wBAG/BM,EAFkB6uB,EAAKnvB,wBAEXM,IACZ+uB,EAAc/uB,IACdV,EAAWQ,UACXR,EAAW0vB,aAAe,EAC1BH,EAAKG,aAAe,CAAA,KACjB,CACC,MAAAvvB,EAAOovB,EAAKnvB,wBAElBM,EADgBP,EAAKO,IAAMjB,OAAOkwB,SACjBlwB,OAAOmwB,YAAc,EAAIzvB,EAAK0vB,OAAS,EAC1D,CAEA,MAAMC,EAAiC,CACrCpvB,MACAC,KAAM,EAENovB,SAAU,WAGR/vB,EAAuBA,EAAAgwB,OAAOF,GAC7BrwB,OAAOuwB,OAAOF,EACrB,CAgDgB,SAAAG,GAAeV,EAAmBnB,IAZ3C,SAAsBmB,EAAmBnB,EAAoB7S,EAAqB,MACvFgU,EAAKhB,UAAUpN,IAAI,YAAY5F,KAE/B,MAAM2U,EAAc,KAClBX,EAAKhB,UAAUI,OAAO,YAAYpT,KAC7BgU,EAAAY,oBAAoB,eAAgBD,EAAW,EAGjDX,EAAAa,iBAAiB,eAAgBF,EACxC,CAIeG,CAAAd,EAAMnB,EAAO,KAC5B,CAQO,SAASkC,GACd1B,EACA7iB,EACAoT,EAAgB,qDAEZ,IAAAoQ,EAAOX,EAAWF,cAA2B,oBACjD,GAAa,OAAT3iB,EAEF,YADa,OAATwjB,GAAeA,EAAKZ,UAGrBY,IACI3E,EAAAA,EACL,gCAAgCzL,+CAElCyP,EAAWI,YAAYO,IAGnB,MAAAgB,EAAchB,EAAKb,cAA2B,mBACpD6B,EAAY1xB,UAAY,GACX,OAATkN,IAEAA,aAAgBykB,YAClBD,EAAYvB,YAAYjjB,GAExBwkB,EAAYpxB,UAAY4M,EAE5B,CC5JA,MAAqB0kB,WAAkBjG,GAOrC,WAAAnT,CAAYoT,GACVhF,MAAMgF,GAPAlT,EAAAvU,KAAA,YAA8B,IACMuU,EAAAvU,KAAA,cAAA,MAEpCuU,EAAAvU,KAAA,YACAuU,EAAAvU,KAAA,gBAwCeuU,EAAAvU,KAAA,gBAAA,GACDuU,EAAAvU,KAAA,eAAA,GApCfA,KAAAynB,IAAIuC,YAAW,KAClBhqB,KAAK6nB,SAAS,iDACT7nB,KAAA0nB,OACH,kBAAkBppB,EAAG,u7BAAW,IAG/B0B,KAAAynB,IAAIwC,cAAa,SAEtBjqB,KAAK+nB,uBAAuB2F,GAAQ1tB,KAAK2tB,uBAAuBD,KAChE1tB,KAAKkoB,cAAa,KACf,MAAanoB,EAAAC,KAAA,MAAA,kBACNA,KAAK4tB,oBAGN5tB,KAAK6tB,cACR7tB,KAAK8tB,oBACL9tB,KAAK6tB,aAAc,GAIrB1B,YAAW,KACTnsB,KAAK+tB,kBAAiB,GACrB,GAAE,KAZN,MAeH/tB,KAAKqoB,cAAa,KACXroB,KAAA8nB,OAAQkG,cAAe1d,MAAMuc,OAAS,EAAA,IAI7CpwB,OAAO0vB,YAAW,KAChBnsB,KAAK4tB,mBAAkB,GACtB,IACL,CAKa,iBAAAA,GAAoB,OAAA7tB,EAAAC,KAAA,MAAA,YAC3BA,KAAKiuB,eACgB,OAArBjuB,KAAKkuB,aAMTluB,KAAKkuB,iBAA2BnuB,EAAAC,KAAA,MAAA,YAC3BmuB,GAAYnuB,KAAK8nB,QACf9nB,KAAAma,gBAAkBna,KAAKouB,WAAWpuB,KAAKynB,IAAIyB,UAAU/O,WACvDkU,GAAYruB,KAAK8nB,QACpB9nB,KAAKkuB,YAAc,KACnBluB,KAAKiuB,cAAe,CAAA,aAEhBjuB,KAAKkuB,mBAZHluB,KAAKkuB,YAaf,GAAA,CAEc,UAAAE,CAAWzQ,GAA2B,OAAA5d,EAAAC,KAAA,MAAA,YAKlD,IAJK4J,MAAM4P,QAAQmE,IAAS,CAAC,SAAU,UAAU2Q,gBAAgB3Q,KAC/DA,EAAO,CAACA,KAGL/T,MAAM4P,QAAQmE,GAGjB,OAFA4Q,GAAYvuB,KAAK8nB,OAAS,IAAIxpB,EAAG,yDAC9B+vB,GAAYruB,KAAK8nB,QACb,GAGH,MAAA0G,EAAWC,IACI,iBAARA,IACPA,EAAIpyB,MAAQshB,EAAK4M,MAAMzc,GAAMA,EAAEzR,OAASoyB,EAAIpyB,QAChDshB,EAAKrQ,KAAKmhB,GAAG,EAITC,EAAoBrZ,GAAatV,EAAAC,KAAA,MAAA,kBAC/B8mB,QAAQ6H,IACZtZ,EAAED,KAAI,CAAOqZ,EAAKviB,IAAUnM,EAAAC,KAAA,MAAA,YAC1B,GAAmB,iBAARyuB,GAAqB7kB,MAAM4P,QAAQiV,IAEnC,GAAA7kB,MAAM4P,QAAQiV,SACjBC,EAAWD,QAAG,GACI,iBAARA,EAAkB,CAClC,MAAMG,QAAgB5uB,KAAK0uB,WAAWD,GAElC7kB,MAAM4P,QAAQoV,SAAgBF,EAAWE,GACjB,iBAAZA,GAAsBJ,EAAQI,EAChD,OAREJ,EAAQC,EAQV,MAEJ,IA4BK,aA1BDC,EAAW/Q,GAGZA,EAAAvP,SAAS1E,IACR,GAAA1J,KAAK6uB,YAAYnlB,GAAO,CAChB1J,KAAK8uB,WAAWplB,GACxB0E,SAASqgB,IACTD,EAAQC,EAAG,GAEJ,MAAA7kB,MAAM4P,QAAQ9P,IAClBA,EAAA0E,SAASqgB,IACZD,EAAQC,EAAG,GAEf,IAIF9Q,EAAOA,EAAK1P,QACTvE,GAA8B,iBAATA,IAAsBE,MAAM4P,QAAQ9P,MAAWA,KAAUA,EAAKrN,OAKtF2D,KAAK+uB,aAAapR,GAClB3d,KAAKgvB,aAAarR,GAEXA,CACT,GAAA,CAGc,UAAA+Q,CAAW1tB,GAA2B,OAAAjB,EAAAC,KAAA,MAAA,YAC9C,IAACgB,EAAK,MAAO,GAEb,IACI,MAAAylB,QAAapP,MAAMrW,GAElB,aADYylB,EAAKC,aAEjBlmB,GAIP,OAHG6tB,GAAYruB,KAAK8nB,QACZjoB,QAAAD,MAAM,2BAA4BY,GAC1C+tB,GAAYvuB,KAAK8nB,OAAS,IAAIxpB,EAAG,gBAAgBA,EAAG,gBAAgBuK,OAAOrI,MACpE,EACT,CACF,GAAA,CAGQ,YAAAuuB,CAAapR,GACdA,EAAAvP,SAASqgB,IACZA,EAAIQ,MAAM7gB,SAAQ,CAAC1E,EAAMwC,KAClBxC,EAAKzB,MAAUyB,EAAAzB,IAAM,GAAGwmB,EAAIpyB,QAAQ6P,EAAQ,IAAC,GACnD,GAEL,CAGQ,YAAA8iB,CAAarR,GACnB,MAAMuR,EAAiC,CAAA,EAClCvR,EAAAvP,SAASqgB,IACRA,EAAAQ,MAAM7gB,SAAS1E,IACZA,EAAKzB,KAAmC,KAA5BY,OAAOa,EAAKzB,KAAKnM,SAC7BozB,EAAIxlB,EAAKzB,KACTinB,EAAIxlB,EAAKzB,OADUinB,EAAAxlB,EAAKzB,KAAO,EAGhCinB,EAAIxlB,EAAKzB,KAAO,IAAQyB,EAAAzB,IAAM,GAAGyB,EAAKzB,OAAOinB,EAAIxlB,EAAKzB,QAAI,GAC/D,GAEL,CAGQ,WAAA4mB,CAAYlR,GACd,IACF,MACkB,iBAATA,KACLxT,OAAOglB,OAAOxR,GAAMxf,QACtByL,MAAM4P,QAAQrP,OAAOgE,KAAKhE,OAAOglB,OAAYxR,GAAM,GAAGyR,aACtDjlB,OAAOgE,KAAKhE,OAAOglB,OAAYxR,GAAM,GAAGyR,UAAU,IAAId,SAAS,OAAM,CAEjE,MAAA5b,GACC,OAAA,CACT,CACF,CAGQ,UAAAoc,CAAWO,GACjB,MAAMnb,EAAyB,GAiBxB,OAhBA/J,OAAAmlB,QAAQD,GAASjhB,SAAQ,EAAEmhB,EAASd,MACnC,MAAAe,EAAwB,CAAEnzB,KAAMkzB,EAAShX,KAAMkW,EAAIlW,KAAM0W,MAAO,IACtER,EAAIW,UAAUhhB,SAAQ,CAAC1E,EAAMwC,KAE3B,MAAMujB,EAAU/lB,EAAKgmB,KACjB,GAAA,aAAapjB,KAAKmjB,GAAU,CACxB,MAAAlF,EAAO,oBAAoB/tB,KAAKizB,GAClClF,GAAQA,EAAKpsB,OAAS,IAAQuL,EAAAgmB,KAAOnF,EAAK,GAChD,CACAiF,EAAKP,MAAM3hB,KAAK,CACdrF,IAAKyB,EAAKd,MAAQ,GAAG2mB,KAAWrjB,EAAQ,IACxC4K,IAAKpN,EAAKgmB,MACX,IAEHxb,EAAK5G,KAAKkiB,EAAI,IAETtb,CACT,CAGQ,iBAAA4Z,GAED9tB,KAAA2vB,SAAW/H,EAAoB,oCAC/B5nB,KAAA8nB,OAAQhI,OAAO9f,KAAK2vB,UAEzB3vB,KAAKma,UAAU/L,SAAQ,CAACqgB,EAAKviB,KACrB,MAAA0jB,EAAOhI,EAAoB,sDAC5B5nB,KAAA2vB,SAAS7P,OAAO8P,GACrBA,EAAKC,aAAa,aAAchnB,OAAOqD,IAClC0jB,EAAAC,aAAa,gBAAiBpB,EAAIpyB,MAClCuzB,EAAAC,aAAa,YAAapB,EAAIlW,MAC/BkW,EAAAQ,MAAM7gB,SAAS1E,IACX,MAAAomB,EAAQlI,EAAoB,kCAM9B,GALJgI,EAAK9P,OAAOgQ,GAENpmB,EAAKzB,MAAQ,IAAI1L,OAAO,KAAKkyB,EAAIpyB,qBAAqBiQ,KAAK5C,EAAKzB,MAC9D6nB,EAAAD,aAAa,QAASnmB,EAAKzB,KAElB,UAAbwmB,EAAIlW,KAAkB,CAClB,MAAAwX,EAAQn0B,SAASH,cAAc,OACrCs0B,EAAMpc,IAAMjK,EAAKoN,IACjBiZ,EAAMhc,IAAMrK,EAAKzB,IACjB6nB,EAAMhQ,OAAOiQ,EAAK,MAElBD,EAAM3zB,UAAYuN,EAAKoN,IAGzBgZ,EAAME,QAAU,KACG,UAAbvB,EAAIlW,KACNvY,KAAKynB,IAAI0B,YAAY8G,cAAc,KAAKvmB,EAAKzB,QAE7CjI,KAAKynB,IAAI0B,YAAY8G,cAAcvmB,EAAKoN,KAAO,GACjD,CAAA,GAEH,IAIC9W,KAAKma,UAAUhc,OAAS,IACrB6B,KAAAkwB,aAAetI,EAAoB,wCACnC5nB,KAAA8nB,OAAQhI,OAAO9f,KAAKkwB,cACzBlwB,KAAKma,UAAU/L,SAAQ,CAACqgB,EAAKviB,KACrB,MAAA4jB,EAAQlI,EAAoB,YAClCkI,EAAM3zB,UAAYsyB,EAAIpyB,KACtByzB,EAAMD,aAAa,aAAchnB,OAAOqD,IACxC4jB,EAAME,QAAU,IAAMhwB,KAAKmwB,QAAQjkB,GAC9BlM,KAAAkwB,aAAapQ,OAAOgQ,EAAK,KAK9B9vB,KAAKma,UAAUhc,OAAS,GAAG6B,KAAKmwB,QAAQ,EAC9C,CAGO,OAAAA,CAAQjkB,aACbtC,MAAM2U,KAAKve,KAAK2vB,SAAS1U,UAAU7M,SAAS1E,IAC1C,MAAM3M,EAAK2M,EACP3M,EAAGyhB,aAAa,gBAAkB3V,OAAOqD,GAC3CnP,EAAGuT,MAAM2b,QAAU,OAEnBlvB,EAAGuT,MAAM2b,QAAU,EACrB,IAGG,OAAApY,EAAA7T,KAAAkwB,eACDrc,EAAAqK,iBAAiB,eAClB9P,SAAS1E,GAASA,EAAK6hB,UAAUI,OAAO,YACtC,OAAAyE,EAAA,OAAA5P,EAAAxgB,KAAAkwB,uBAAcxE,cAAc,oBAAoBxf,SAAhDkkB,EAA4D7E,UAAUpN,IAAI,UAE/Ene,KAAK+tB,kBACP,CAEQ,gBAAAA,GAGR,CAGO,sBAAAJ,CAAuB/kB,GACxB,OAAC5I,KAAKma,WAAcvQ,MAAM4P,QAAQxZ,KAAKma,YAEtCna,KAAAma,UAAU/L,SAASqgB,IACL,UAAbA,EAAIlW,MACDpO,OAAAmlB,QAAQb,EAAIQ,OAAO7gB,SAAQ,EAAElC,EAAOxC,MACzCd,EAAOA,EACJhI,MAAM,KAAK8I,EAAKzB,QAChB2G,KAAK,aAAalF,EAAKoN,sBAAsBpN,EAAKzB,QAAO,GAC7D,IAGIW,GAXuDA,CAYhE,ECnTF,MAAMynB,GAAe,CAAC,MAAO,MAAO,OAAQ,MAAO,MAAO,MAAO,QAEjE,MAAqBC,WAAe9I,GAGlC,WAAAnT,CAAYoT,GACVhF,MAAMgF,GAHAlT,EAAAvU,KAAA,mBAKNA,KAAKynB,IAAIuC,YAAW,IAAMhqB,KAAKqmB,SAE/BrmB,KAAKuwB,aACP,CAEQ,IAAAlK,GACDrmB,KAAAwwB,gBAAkB50B,SAASH,cAAc,SAC9CuE,KAAKwwB,gBAAgBjY,KAAO,OACvBvY,KAAAwwB,gBAAgBlgB,MAAM2b,QAAU,OAChCjsB,KAAAwwB,gBAAgBC,OAASJ,GAAajb,KAAKtH,GAAM,IAAIA,MAAKc,KAAK,KAGpE,MAAM+Y,EAAO3nB,KAAK0nB,OAChB,kBAAkBppB,EAAG,+yBAElBqpB,EAAAyD,MAAMprB,KAAKwwB,iBAChB7I,EAAKqI,QAAU,KAEb,MAAMU,EAAS1wB,KAAKwwB,gBACpBE,EAAOC,SAAW,KACf,MAAa5wB,EAAAC,KAAA,MAAA,YAEZ,IAAK0wB,EAAOE,OAAiC,IAAxBF,EAAOE,MAAMzyB,OAAc,OAC1C,MAAA0yB,EAAOH,EAAOE,MAAM,GAC1B5wB,KAAK8wB,UAAUD,EAAI,KAJpB,IAOHH,EAAOK,OAAM,EAGV/wB,KAAKynB,IAAIyB,UAAU/N,WACjBnb,KAAA2nB,KAAMkI,aAAa,sBAAuB,GAEnD,CAEQ,WAAAU,GAEA,MAAAS,EAAsBJ,IAC1B,GAAKA,EAEL,IAAA,IAASpjB,EAAI,EAAGA,EAAIojB,EAAMzyB,OAAQqP,IAAK,CAC/B,MAAAqjB,EAAOD,EAAMpjB,GACnBxN,KAAK8wB,UAAUD,EACjB,GAMII,EAAcC,IAClBA,EAAIC,kBACJD,EAAIE,gBAAe,EAGfC,EAAUH,UACR,MAAAN,EAAQ,OAAA/c,EAAIqd,EAAAI,mBAAc,EAAAzd,EAAA+c,aAC5BA,WAAOzyB,UACT+yB,EAAIE,iBACJJ,EAAmBJ,GACrB,EAIIW,EAAWL,UACT,MAAAN,EAAQ,OAAA/c,EAAIqd,EAAAM,oBAAe,EAAA3d,EAAA+c,aAC7BA,WAAOzyB,UACT+yB,EAAIE,iBACJJ,EAAmBJ,GACrB,EAGG5wB,KAAAynB,IAAIuC,YAAW,KAClBhqB,KAAKynB,IAAIyD,QAAQuG,UAAUrE,iBAAiB,WAAY6D,GACxDjxB,KAAKynB,IAAIyD,QAAQuG,UAAUrE,iBAAiB,OAAQiE,GACpDrxB,KAAKynB,IAAIyD,QAAQuG,UAAUrE,iBAAiB,QAASmE,EAAO,IAEzDvxB,KAAAynB,IAAIwC,cAAa,KACpBjqB,KAAKynB,IAAIyD,QAAQuG,UAAUtE,oBAAoB,WAAY8D,GAC3DjxB,KAAKynB,IAAIyD,QAAQuG,UAAUtE,oBAAoB,OAAQkE,GACvDrxB,KAAKynB,IAAIyD,QAAQuG,UAAUtE,oBAAoB,QAASoE,EAAO,GAEnE,CAEM,SAAAT,CAAUD,GAAY,OAAA9wB,EAAAC,KAAA,MAAA,YAC1B,MAAM0xB,EAAU,SAASl1B,KAAKq0B,EAAKx0B,MACnC,IAAKq1B,IAAYrB,GAAa/B,SAASzlB,OAAO6oB,EAAQ,IAAI9pB,eAAgB,OAG1E,IAAK5H,KAAKynB,IAAIwB,UAAUpM,wBAEtB,YADA7c,KAAKynB,IAAI0B,YAAY3Q,WAAWla,EAAG,kBAAmB,KAKxD,IAAIqzB,EAAe,KAC6B,KAA5C3xB,KAAKynB,IAAIyD,QAAQuG,UAAUpjB,MAAMvS,SAA8B61B,EAAA,IAGnE,MAAMC,EAAuB,GAAGD,kBAA6Bd,EAAKx0B,WAI9D,IAAAoqB,EAHJzmB,KAAKynB,IAAI0B,YAAY8G,cAAc2B,GAI/B,IACF,MAAMC,EAAmB7xB,KAAKynB,IAAIyB,UAAU4I,YAM1CrL,EALGoL,EAKI,CAAEE,iBAAkBF,EAAiBhB,WAH9B7wB,KAAKynB,IAAIqB,SAASzD,OAAOA,OAAO,CAAEwL,UAASlT,WAKpDnd,GACPX,QAAQD,MAAMY,GACdR,KAAKynB,IAAI0B,YAAY3Q,WAAW,GAAGla,EAAG,kBAAkBkC,EAAIymB,UAAW,IACzE,CACA,GAAMR,GAAQA,EAAKsL,WAAY,CAC7B,IAAIC,EAASvL,EAAKsL,WAGbE,EAAiBD,KACpBA,EAASE,EAAuB,CAC9B3wB,KAAMvB,KAAKynB,IAAIyB,UAAU1iB,OACzBhF,KAAMwwB,KAILhyB,KAAAynB,IACF0B,YACAgJ,WACCnyB,KAAKynB,IACFyD,QACAuG,UAAUpjB,MAAMxR,QAAQ+0B,EAAsB,GAAGD,QAAmBK,MACzE,MAGFhyB,KAAKynB,IACF0B,YACAgJ,WAAWnyB,KAAKynB,IAAIyD,QAAQuG,UAAUpjB,MAAMxR,QAAQ+0B,EAAsB,IAEjF,GAAA,ECpJF,MAAqBQ,WAAgB5K,GAGnC,WAAAnT,CAAYoT,GACVhF,MAAMgF,GAHkBlT,EAAAvU,KAAA,mBAAA,GAKnBA,KAAAynB,IAAIuC,YAAW,KAClBhqB,KAAK6nB,SAAS,+CAGT7nB,KAAA0nB,OACH,kBAAkBppB,EAAG,iWAAU,IAG9B0B,KAAAynB,IAAIwC,cAAa,SAGtBjqB,KAAKynB,IAAIU,YAAYzS,GAAG,mBAAoBlF,IACrCxQ,KAAAqyB,iBAAmBryB,KAAKsyB,mBAG/BtyB,KAAKkoB,cAAa,KAChBloB,KAAKqyB,iBAAkB,EACvBryB,KAAKsyB,eAAc,IAErBtyB,KAAKqoB,cAAa,KAChBroB,KAAKqyB,iBAAkB,CAAA,GAE3B,CAEA,aAAAC,GACEtyB,KAAK8nB,OAAQjsB,UAAYmE,KAAKynB,IAAI0B,YAAYoJ,kBAChD,ECpBF,MAAMC,GAAwC,CRZ9C,cAA0ChL,GACxC,WAAAnT,CAAYoT,GACVhF,MAAMgF,GAEN,MAAMgL,EAAmB,KACvBzyB,KAAK+B,MAAK,EAGP/B,KAAAynB,IAAIuC,YAAW,KAElB,MAAM0I,EAAej2B,OAAOk2B,aAAaC,QAAQjK,KAAoB,GACzC,KAAxB+J,EAAa52B,SACfkE,KAAKynB,IAAI0B,YAAY3Q,WAAWla,EAAG,eAAgB,KACnD0B,KAAKynB,IAAI0B,YAAYgJ,WAAWO,IAIlC1yB,KAAKynB,IAAIU,YAAYzS,GAAG,kBAAmB+c,EAAgB,IAGxDzyB,KAAAynB,IAAIwC,cAAa,KACpBjqB,KAAKynB,IAAIU,YAAYxS,IAAI,kBAAmB8c,EAAgB,GAEhE,CAGO,IAAA1wB,GACEtF,OAAAk2B,aAAaE,QAAQlK,GAAiB3oB,KAAKynB,IAAI0B,YAAY2J,gBAAgBh3B,OACpF,GS/BF,cAAyC0rB,GACvC,WAAYuL,GACV,OAAO/yB,KAAKynB,IAAI0B,YAAY6J,mBAC9B,CAEA,WAAA3e,CAAYoT,GACVhF,MAAMgF,GAEN,MAAMwL,EAAgD,CAAA,EAChDC,EAAiD,CAAA,EAEjDrd,EACJ,CAACqb,EAAuCR,EAA0ByC,IAAkB,KAC7EnzB,KAAAynB,IAAIU,YAAYtS,QAAQqb,EAAK,CAAEiC,QAAOzC,UAAQ,EAGlD1wB,KAAAynB,IAAIuC,YAAW,KAEX7f,OAAAmlB,QAAQtvB,KAAK+yB,SAAS3kB,SAAQ,EAAEnG,EAAKyoB,MACnCA,EAAAtD,iBACL,QACC6F,EAAchrB,GAAO4N,EAAQ,eAAgB6a,EAAQzoB,IAEjDyoB,EAAAtD,iBACL,SACC8F,EAAejrB,GAAO4N,EAAQ,gBAAiB6a,EAAQzoB,GAAG,GAE9D,IAGEjI,KAAAynB,IAAIwC,cAAa,KAEb9f,OAAAmlB,QAAQtvB,KAAK+yB,SAAS3kB,SAAQ,EAAEnG,EAAKyoB,MAC1CA,EAAOvD,oBAAoB,QAAS8F,EAAchrB,IAClDyoB,EAAOvD,oBAAoB,SAAU+F,EAAejrB,GAAI,GACzD,GAEL,GCnCF,cAAwCuf,GACtC,WAAAnT,CAAYoT,GACVhF,MAAMgF,GAoCQlT,EAAAvU,KAAA,QAAA,CACdozB,MAAsB,KACtBC,QAA8B,OApC9B,MAAMC,EAAU,EAAG5C,SAAQyC,YACe,SAApCnzB,KAAKynB,IAAI0B,YAAYoK,aAGzBvzB,KAAKynB,IAAIwB,UAAU1S,OAAO,CAAE4c,CAACA,GAAQzC,EAAOriB,MAAMvS,SAGpC,SAAVq3B,GAA8B,UAAVA,QAAwBK,kBAG5CC,EAAe,CACnBp3B,KAAMiC,EAAG,QACT2D,MAAO3D,EAAG,SACV4D,KAAM5D,EAAG,SAGN0B,KAAAynB,IAAIuC,YAAW,KAClB7f,OAAOmlB,QAAQtvB,KAAKynB,IAAI0B,YAAY6J,qBAAqB5kB,SAAQ,EAAEnG,EAAKyoB,MAE/DA,EAAAhvB,YAAc+xB,EAAaxrB,GAG3ByoB,EAAAriB,MAAQrO,KAAKynB,IAAIwB,UAAU7R,UAAUnP,IAAQ,EAAA,IAItDjI,KAAKynB,IAAIU,YAAYzS,GAAG,eAAgB4d,EAAO,IAG5CtzB,KAAAynB,IAAIwC,cAAa,KACpBjqB,KAAKynB,IAAIU,YAAYxS,IAAI,eAAgB2d,EAAO,GAEpD,CAUQ,aAAAE,GACDxzB,KAAAynB,IAAIwB,UAAUyK,SAEf1zB,KAAKid,MAAMmW,cAAcO,aAAa3zB,KAAKid,MAAMmW,OACjDpzB,KAAKid,MAAMoW,SAASrzB,KAAKid,MAAMoW,UAEnCrzB,KAAKid,MAAMmW,MAAQ32B,OAAO0vB,YAAW,KACnCnsB,KAAKid,MAAMmW,MAAQ,KAEb,MAAAQ,EAAM5zB,KAAKynB,IAAIqB,SACf+K,EAAe,qBACrB7zB,KAAKid,MAAMoW,QAAU,IAAMO,EAAIE,aAAaD,GAE5CD,EAAIrX,KACDpF,QACC2H,EAAA,CAAA,EAAK8U,EAAIrM,iBACT,CACErH,YAAa2T,IAGhBnS,MAAMhD,GAAQ1e,KAAK+zB,kBAAkBrV,EAAIf,QACzCoE,OAAOvhB,IAAD,IACNwzB,SAAQ,KACPh0B,KAAKid,MAAMoW,QAAU,IAAA,GACtB,GACF,IACL,CAOQ,iBAAAU,CAAkBpW,SAEnBA,EAAKsW,eAAexM,IAAIwB,UAAUyK,SAGvC1zB,KAAKynB,IAAIiC,UAAUwK,eAAevW,EAAKwW,UAGnCn0B,KAAKynB,IAAIwB,UAAUpM,0BAA4Bc,EAAKsW,WAAY,OAAApgB,EAAA8J,EAAKpB,WAAL,EAAA1I,EAAWugB,WAExEp0B,KAAAynB,IAAI4M,cAActb,WAAW,CAChCub,UAAW,SAKX3W,EAAKpB,MAAQoB,EAAKpB,KAAKra,OACzBlC,KAAKynB,IAAIyD,QAAQqJ,MAAMlmB,MAAQsP,EAAKpB,KAAKra,KACpClC,KAAAynB,IAAIwB,UAAU1S,OAAO,CAAErU,KAAMyb,EAAKpB,KAAKra,OAEhD,GCrGF,cAAwCslB,GACtC,WAAAnT,CAAYoT,GACVhF,MAAMgF,GAEN,MAAM+M,EAAe,EAAGrB,YACR,SAAVA,GAAkBnzB,KAAKy0B,mBAAkB,EAI1Cz0B,KAAAynB,IAAIuC,YAAW,KAClBhqB,KAAKynB,IAAIU,YAAYzS,GAAG,gBAAiB8e,EAAY,IAGlDx0B,KAAAynB,IAAIwC,cAAa,KACpBjqB,KAAKynB,IAAIU,YAAYxS,IAAI,gBAAiB6e,EAAY,GAE1D,CAEQ,iBAAAC,GAEN,MAAMvyB,EAAOlC,KAAKynB,IAAIyD,QAAQqJ,MAAMlmB,MAAMvS,OACpCoG,IAAS,qBAAqBoK,KAAKpK,KACvClC,KAAKynB,IAAIyD,QAAQqJ,MAAMlmB,MAAQ,WAAWnM,IAC1ClC,KAAKynB,IAAIwB,UAAU1S,OAAO,CAAErU,KAAMlC,KAAKynB,IAAIyD,QAAQqJ,MAAMlmB,QAE7D,GCxBF,cAAsCmZ,GACpC,WAAAnT,CAAYoT,GACVhF,MAAMgF,GAEN,MAAMiN,EAAahiB,GAAqB1S,KAAK00B,UAAUhiB,GACjD4gB,EAAU,IAAMtzB,KAAKszB,UAEtBtzB,KAAAynB,IAAIuC,YAAW,KAEbhqB,KAAAynB,IAAIyD,QAAQuG,UAAU/vB,YAAc1B,KAAKynB,IAAIyB,UAAUxnB,aAAepD,EAAG,eAG9E0B,KAAKynB,IAAIyD,QAAQuG,UAAUrE,iBAAiB,UAAWsH,GACvD10B,KAAKynB,IAAIyD,QAAQuG,UAAUrE,iBAAiB,QAASkG,EAAO,IAGzDtzB,KAAAynB,IAAIwC,cAAa,KAEpBjqB,KAAKynB,IAAIyD,QAAQuG,UAAUtE,oBAAoB,UAAWuH,GAC1D10B,KAAKynB,IAAIyD,QAAQuG,UAAUtE,oBAAoB,QAASmG,EAAO,IAGjEtzB,KAAKynB,IAAIU,YAAYzS,GAAG,mBAAmB,KAEzCjZ,OAAO0vB,YAAW,KAChBnsB,KAAK20B,yBAAwB,GAC5B,GAAE,GAET,CAGQ,SAAAD,CAAUhiB,GAGA,KAFAA,EAAEkiB,SAAWliB,EAAEmiB,SAG7BniB,EAAE0e,iBACFpxB,KAAKynB,IAAI0B,YAAY8G,cAAc,MAEvC,CAEQ,OAAAqD,GACDtzB,KAAAynB,IAAIU,YAAYtS,QAAQ,kBAAmB7V,KAAKynB,IAAI0B,YAAY2J,gBACvE,CAGO,uBAAA6B,GACC,MAAAG,EAAO90B,KAAKynB,IAAIyD,QAAQuG,UAAUsD,aAAe/0B,KAAKynB,IAAIyD,QAAQuG,UAAU/E,aAClF1sB,KAAKynB,IAAIyD,QAAQuG,UAAUnhB,MAAMuc,OAAS,MAC1C7sB,KAAKynB,IAAIyD,QAAQuG,UAAUnhB,MAAMuc,OAAS,GAAG7sB,KAAKynB,IAAIyD,QAAQuG,UAAUuD,aAAeF,KACzF,GJ5BAlL,GKrBF,cAAuCpC,GACrC,WAAAnT,CAAYoT,GACVhF,MAAMgF,GAEN,MAAMwN,EAAU,KACTj1B,KAAAynB,IAAI0B,YAAY+L,QAAO,EAGzBl1B,KAAAynB,IAAIuC,YAAW,KAEbhqB,KAAAynB,IAAIyD,QAAQiK,WAAWh5B,UAAY6D,KAAKynB,IAAIyB,UAAUpP,SAAWxb,EAAG,QAGzE0B,KAAKynB,IAAIyD,QAAQiK,WAAW/H,iBAAiB,QAAS6H,EAAO,IAG1Dj1B,KAAAynB,IAAIwC,cAAa,KACpBjqB,KAAKynB,IAAIyD,QAAQiK,WAAWhI,oBAAoB,QAAS8H,EAAO,GAEpE,GLIApK,GMnBF,cAAwCrD,GAGtC,WAAAnT,CAAYoT,GACVhF,MAAMgF,GAHAlT,EAAAvU,KAAA,WAMDA,KAAAsoB,qBAAqB,SAAU1Q,IAClC5X,KAAKo1B,SAASxd,GAEP,KACL5X,KAAKq1B,aAAY,KAKrBr1B,KAAKynB,IAAIU,YAAYzS,GAAG,WAAW,KACjC,MAAM4f,EAAat1B,KAAKynB,IAAI8N,QAAQ3L,IACpC,IAAK0L,EAAkB,MAAAxgB,MAAM,8BAE7B,MAAM+U,EAAgB,IAAIjB,GAAgB5oB,KAAKynB,KAE/C6N,EAAWpL,eAAe,CACxBM,WAAY,MAAQxqB,KAAKoM,QACzBue,IAAK,IAAY5qB,EAAAC,KAAA,MAAA,YACf,IAAKA,KAAKoM,QAAe,MAAA,IAAI0I,MAAM,iCAY5B,aATC9U,KAAKynB,IAAIqB,SAASC,SAASzF,cAAc9B,EACzC1C,EAAA,CAAA,QAAM+K,EAAcb,sBADqB,CAE7CK,IAAKrpB,KAAKoM,QAAQoX,GAClBhG,SAAUxd,KAAKoM,QAAQoR,SACvBC,gBAAY,EACZC,UAAW1d,KAAKoM,QAAQsR,cAE1BC,IAGJ,IACAiN,KAAOH,IAEC,MAAAnU,EAAOtW,KAAKynB,IAAIyB,UAClBuB,EAASjN,WAAalH,EAAKqD,SAC7Bld,OAAO2K,KAAK,GAAGqjB,EAAS+K,wBAAwB/K,EAASjH,MAG3DqG,EAAcL,cAAciB,EAAQ,GAEvC,GAEL,CAEQ,QAAA2K,CAASxd,GACT,MAAA6d,EAAKz1B,KAAKynB,IAAIyD,QAChB,IAACuK,EAAGC,cAAe,CACrB,MAAM/N,EAAOC,EACX,2DAEKtpB,EAAG,iHAKVqpB,EAAK+D,cAA2B,aAAcvvB,UAAY,IAAIyb,EAAY5V,OACrE2lB,EAAAyF,iBAAiB,SAAS,KACxBptB,KAAAynB,IAAI0B,YAAYzQ,YAAW,IAE/B+c,EAAAE,WAAW7V,OAAO6H,GACrB8N,EAAGC,cAAgB/N,CACrB,CAEA3nB,KAAKoM,QAAUwL,EAEf6d,EAAGhE,UAAUpH,OACf,CAEQ,WAAAgL,GACF,IAACr1B,KAAKoM,QAAS,OAEb,MAAAqpB,EAAKz1B,KAAKynB,IAAIyD,QAChBuK,EAAGC,gBACLD,EAAGC,cAAc/J,SACjB8J,EAAGC,mBAAgB,GAErB11B,KAAKoM,aAAU,CACjB,GCtFF,cAAuCob,GAGrC,WAAAnT,CAAYoT,GACVhF,MAAMgF,GAHAlT,EAAAvU,KAAA,WAoGwBuU,EAAAvU,KAAA,wBAAA,QA9FzBA,KAAAsoB,qBAAqB,QAASlc,IACjCpM,KAAKmE,KAAKiI,GAEH,KACLpM,KAAK41B,YAAW,KAKf51B,KAAAynB,IAAIuC,YAAW,KAClB,MAAMsL,EAAat1B,KAAKynB,IAAI8N,QAAQ3L,IACpC,IAAK0L,EAAkB,MAAAxgB,MAAM,8BAE7BwgB,EAAWpL,eAAe,CACxBM,WAAY,MAAQxqB,KAAKoM,QACzBue,IAAK,IAAY5qB,EAAAC,KAAA,MAAA,YACf,MAAM61B,EAAW,CACfrlB,QAASxQ,KAAKynB,IAAI0B,YAAYC,kBAC9BpnB,KAAMhC,KAAKynB,IAAIyD,QAAQ4K,MAAMznB,MAC7BpM,MAAOjC,KAAKynB,IAAIyD,QAAQ6K,OAAO1nB,MAC/BnM,KAAMlC,KAAKynB,IAAIyD,QAAQqJ,MAAMlmB,OAEzBjC,EAAUpM,KAAKoM,QAKrB,aAJuBpM,KAAKynB,IAAIqB,SAASC,SAAStF,cAAcrX,EAAQoX,GAAI1E,EACvEA,EAAA,CAAA,EAAA1S,GACAypB,KAEWlY,IAClB,IACAiN,KAAOH,IACLzqB,KAAKynB,IAAIiC,UAAUjG,cAAcgH,EAAQ,GAE5C,GAEL,CAEQ,IAAAtmB,CAAKiI,GACL,MAAAqpB,EAAKz1B,KAAKynB,IAAIyD,QAChB,IAACuK,EAAGO,eAAgB,CACtB,MAAMrO,EAAOC,EACX,2DAEKtpB,EAAG,uFAKVqpB,EAAKqI,QAAU,KACRhwB,KAAAynB,IAAI0B,YAAYzQ,YAAW,EAE/B+c,EAAAE,WAAW7V,OAAO6H,GACrB8N,EAAGO,eAAiBrO,CACtB,CACA3nB,KAAKoM,QAAUA,EAEZqpB,EAAAQ,QAAQ3lB,MAAM2b,QAAU,OAExBwJ,EAAAK,MAAMznB,MAAQjC,EAAQpK,MAAQ,GAC9ByzB,EAAAM,OAAO1nB,MAAQjC,EAAQnK,OAAS,GAChCwzB,EAAAlB,MAAMlmB,MAAQjC,EAAQlK,MAAQ,GAEjClC,KAAKynB,IAAI0B,YAAYgJ,WAAW/lB,EAAQoE,SACxCilB,EAAGhE,UAAUpH,QAERrqB,KAAAk2B,oBAAoB53B,EAAG,QAC9B,CAEQ,UAAAs3B,GACF,IAAC51B,KAAKoM,QAAS,OAEb,MAAAqpB,EAAKz1B,KAAKynB,IAAIyD,QAEhBuK,EAAGO,iBACLP,EAAGO,eAAerK,SAClB8J,EAAGO,oBAAiB,GAGtBh2B,KAAKoM,aAAU,EAET,MAAA/P,KAAEA,QAAM4F,EAAOC,KAAAA,GAASlC,KAAKynB,IAAIwB,UAAU7R,UACjDqe,EAAGK,MAAMznB,MAAQhS,EACjBo5B,EAAGM,OAAO1nB,MAAQpM,EAClBwzB,EAAGlB,MAAMlmB,MAAQnM,EAEjBlC,KAAKynB,IAAI0B,YAAYgJ,WAAW,IAChCnyB,KAAKm2B,uBAEFV,EAAAQ,QAAQ3lB,MAAM2b,QAAU,EAC7B,CAQQ,mBAAAiK,CAAoBttB,GAC1B5I,KAAKo2B,sBAAwBp2B,KAAKynB,IAAIyD,QAAQiK,WAAWh5B,UACzD6D,KAAKynB,IAAIyD,QAAQiK,WAAWh5B,UAAYyM,CAC1C,CAEQ,oBAAAutB,GACNn2B,KAAKynB,IAAIyD,QAAQiK,WAAWh5B,UAAY6D,KAAKo2B,qBAC/C,GChHF,cAAsC5O,GACpC,WAAAnT,CAAYoT,GACVhF,MAAMgF,GAEA,MAAA4O,EAAS,IAAMr2B,KAAKoH,OACpBkvB,EAAU,IAAMt2B,KAAKu2B,QAEtBv2B,KAAAynB,IAAIuC,YAAW,KAClBhqB,KAAKynB,IAAIU,YAAYzS,GAAG,cAAe2gB,GACvCr2B,KAAKynB,IAAIU,YAAYzS,GAAG,eAAgB4gB,EAAO,IAE5Ct2B,KAAAynB,IAAIwC,cAAa,KACpBjqB,KAAKynB,IAAIU,YAAYxS,IAAI,cAAe0gB,GACxCr2B,KAAKynB,IAAIU,YAAYxS,IAAI,eAAgB2gB,EAAO,GAEpD,CAEQ,IAAAlvB,SACN,OAAAyM,EAAA7T,KAAKynB,IAAIyD,QAAQsL,cAAc9K,cAAc,yBAAwB7X,EAAA8X,SACrE3rB,KAAKynB,IAAIyD,QAAQuG,UAAUnhB,MAAM2b,QAAU,GAC3CjsB,KAAKynB,IAAIyD,QAAQuL,QAAQnmB,MAAM2b,QAAU,EAC3C,CAEQ,KAAAsK,GACDv2B,KAAKynB,IAAIyD,QAAQsL,cAAc9K,cAAc,wBAC3C1rB,KAAAynB,IACFyD,QACAsL,cAAcE,QACb9O,EAAoB,mCAAmCtpB,EAAG,+BAG3D0B,KAAKynB,IAAIwB,UAAU7R,UAAUgd,UAMhCp0B,KAAKynB,IAAIyD,QAAQuG,UAAUnhB,MAAM2b,QAAU,GAC3CjsB,KAAKynB,IAAIyD,QAAQuL,QAAQnmB,MAAM2b,QAAU,KANzCjsB,KAAKynB,IAAIyD,QAAQuG,UAAUnhB,MAAM2b,QAAU,OAC3CjsB,KAAKynB,IAAIU,YAAYtS,QAAQ,eAC7B7V,KAAKynB,IAAIyD,QAAQuL,QAAQnmB,MAAM2b,QAAU,OAM7C,GRZAwB,GACA6C,GACA8B,IS7BF,MAAqBuE,GACnB,WAAAtiB,CAAoBuiB,GAAA52B,KAAA42B,QAAAA,CAAyB,CAG7C,SAAAzN,GACS,OAAAnpB,KAAK42B,QAAQC,WACtB,CAGA,OAAA3N,GACE,OAAOlpB,KAAK42B,QAAQE,aAAa1gB,UAAUvB,KAC7C,CAGA,MAAAiU,GACE,OAAO9oB,KAAK42B,QAAQE,aAAa7f,QACnC,CAGA,OAAAyS,GACE,OAAO1pB,KAAK42B,QAAQE,aAAa1f,SACnC,CAGA,OAAA6R,GACE,OAAOjpB,KAAK42B,QAAQE,aAAa3f,SACnC,CAGA,WAAAkd,GACE,OAAOr0B,KAAK42B,QAAQE,aAAaC,aACnC,CAGA,KAAA7L,GACE,OAAOlrB,KAAK42B,QAAQC,YAAYG,OAClC,CAGA,SAAA7O,GACS,OAAAnoB,KAAK42B,QAAQK,WACtB,CAGA,UAAAjN,CAAWhC,GACThoB,KAAKmoB,YAAYzS,GAAG,UAAWsS,EACjC,CAGA,YAAAiC,CAAajC,GACXhoB,KAAKmoB,YAAYzS,GAAG,YAAasS,EACnC,CAGA,OAAAuN,CAAuC2B,GAC9B,OAAAl3B,KAAK42B,QAAQ/hB,IAAIqiB,EAC1B,CAGA,eAAAzL,GACE,OAAOzrB,KAAK42B,QAAQE,aAAaK,iBACnC,ECjEK,MAAMC,GAAN,WAAA/iB,GACGE,EAAAvU,KAAA,SAAqB,GAAA,CAKtB,EAAA0V,CAAsBrZ,EAASsP,EAA6BtK,EAAqB,CAAA,GACtFrB,KAAKq3B,OAAO/pB,KAAKwR,EAAA,CACfziB,OACAsP,WACGtK,GAEP,CAKO,GAAAsU,CAAuBtZ,EAASsP,GAChCA,IACL3L,KAAKq3B,OAASr3B,KAAKq3B,OAAOppB,QAAQijB,KAAUA,EAAI70B,OAASA,GAAQ60B,EAAIvlB,UAAYA,KACnF,CAKO,OAAAkK,CAA2BxZ,EAASuZ,GACzC5V,KAAKq3B,OACFvtB,MAAM,GACNmE,QAAQijB,GAAQA,EAAI70B,OAASA,GAA+B,mBAAhB60B,EAAIvlB,UAChDyC,SAAS8iB,IACJA,EAAIoG,MAAMt3B,KAAK2V,IAAItZ,EAAM60B,EAAIvlB,SACjCulB,EAAIvlB,QAAQiK,EAAQ,GAE1B,EC4BK,MAAM2hB,GAKX,WAAAljB,CAAmBhT,GAJXkT,EAAAvU,KAAA,UAA0B,IACQuU,EAAAvU,KAAA,aAAA,MAClCuU,EAAAvU,KAAA,SAAS,IAAIo3B,IAEFp3B,KAAAqB,KAAAA,EACjB,IAAIm2B,GAAa,EACjBx3B,KAAKqB,KACF+U,UACAI,UAAU,CAAC,YAAa,YAAa,UAAW,eAAgB,WAAYF,IAG3EkhB,GAAcx3B,KAAKi3B,YAAYphB,QAAQ,aAGvC7V,KAAKy3B,QXrCN,SACLnhB,GAIM,MAAAohB,MAAejjB,IAMrB,OALSijB,EAAApiB,IAAIgb,GAAQha,EAAK6E,WACjBuc,EAAApiB,IAAImY,GAAWnX,EAAK6D,WACpBud,EAAApiB,IAAI8c,GAAS9b,EAAKlU,SAClBs1B,EAAApiB,IAAIuV,GAAOvU,EAAKyD,cAElByY,GAAavkB,QAAQ0pB,IAAOD,EAAS1iB,IAAI2iB,MAAQD,EAAS7iB,IAAI8iB,IACvE,CW4BQC,CAAgBthB,GAAMlI,SAASypB,IAEvB,MAAApQ,EAAM,IAAIkP,GAAQ32B,MACxBA,KAAK42B,QAAQtpB,KAAK,IAAIuqB,EAAKpQ,GAAI,IAI5BznB,KAAAi3B,YAAYphB,QAAQ,WACZ2hB,GAAA,EAGbx3B,KAAK83B,cAAa,IAGtB93B,KAAKq3B,OAAO3hB,GAAG,eAAe,IAAM1V,KAAK+3B,qBACzC/3B,KAAKq3B,OAAO3hB,GAAG,oBAAoB,IAAMrU,EAAK22B,eAChD,CAEA,UAAAC,GACE,OAAOj4B,KAAK42B,OACd,CAEA,SAAAK,GACE,OAAOj3B,KAAKq3B,MACd,CAEA,SAAAR,GACS,OAAA72B,KAAKqB,KAAKw1B,WACnB,CAEA,UAAAC,GACE,OAAO92B,KAAKqB,IACd,CAEQ,KAAAo2B,GACNz3B,KAAK42B,QAAU,GACV52B,KAAAq3B,OAAS,IAAID,GACdp3B,KAAKk4B,YAAYl4B,KAAK+3B,kBAC5B,CAEQ,YAAAD,GAEN93B,KAAK62B,YAAYG,QAAQmB,eAAet8B,UAAY,GACpDmE,KAAK62B,YAAYG,QAAQmB,eAAe7nB,MAAM2b,QAAU,OACxDjsB,KAAK62B,YAAYG,QAAQoB,aAAav8B,UAAY,GAGlDmE,KAAK42B,QAAQxoB,SAAS8oB,GAASl3B,KAAKq4B,eAAenB,IACrD,CAGQ,cAAAmB,CAAenB,GACrB,MAAMvP,EAAOuP,EAAKvP,KAClB,IAAKA,EAAM,OACX3nB,KAAK62B,YAAYG,QAAQoB,aAAapM,YAAYrE,IAGjDA,EAAKqI,UACHrI,EAAKqI,QAAU,KAEdhwB,KAAKqB,KACFw1B,YACAG,QACAoB,aAAala,iBAAiB,WAC9B9P,SAAS1E,GAASA,EAAK6hB,UAAUI,OAAO,YAGvCuL,IAASl3B,KAAKk4B,YAEhBl4B,KAAKs4B,gBAAgBpB,GAGhBvP,EAAA4D,UAAUpN,IAAI,WAGnBne,KAAK+3B,kBACP,GAIJ,MAAMjQ,EAASoP,EAAKpP,OAChBA,IACFA,EAAOxX,MAAM2b,QAAU,OACvBjsB,KAAK62B,YAAYG,QAAQmB,eAAenM,YAAYlE,GAExD,CAEA,GAAAjT,CAAmCqiB,GACjC,OAAOl3B,KAAK42B,QAAQrM,MAAMoN,GAAMA,aAAaT,GAC/C,CAGA,eAAAoB,CAAgBpB,GACTl3B,KAAA42B,QAAQxoB,SAASga,IACpB,MAAMmQ,EAAYnQ,EAAMN,OACnByQ,IAEDnQ,IAAU8O,GACZqB,EAAUjoB,MAAM2b,QAAU,GACrBjsB,KAAAq3B,OAAOxhB,QAAQ,aAAcqhB,KAElCqB,EAAUjoB,MAAM2b,QAAU,OACrBjsB,KAAAq3B,OAAOxhB,QAAQ,aAAcqhB,IACpC,IAGFl3B,KAAK62B,YAAYG,QAAQmB,eAAe7nB,MAAM2b,QAAU,GACxDjsB,KAAKk4B,WAAahB,CACpB,CAGA,gBAAAa,GACO/3B,KAAKk4B,aAEVl4B,KAAK62B,YAAYG,QAAQmB,eAAe7nB,MAAM2b,QAAU,OACxDjsB,KAAKq3B,OAAOxhB,QAAQ,aAAc7V,KAAKk4B,YACvCl4B,KAAKk4B,WAAa,KACpB,CAGA,qBAAAM,CAAsBC,GACpB,IAAIhvB,EAASgvB,EAKN,OAJFz4B,KAAA42B,QAAQxoB,SAASga,IACfA,EAAMH,qBACFxe,EAAA2e,EAAMH,mBAAmBxe,GAAM,IAEnCA,CACT,EC9MW,kBCYN,SAASivB,GAAgBr3B,GACxB,MAAAs3B,EAAQ/Q,EAAoB,8DAIlC,GAHA+Q,EAAMjN,cAA2B,kBAAmBvvB,UAClD,GAAGmC,EAAG,uBAAuB+C,EAAKu3B,SAEhCv3B,EAAKw3B,QAAS,CAChB,MAAMC,EAAYlR,EAAoB,iCAAiCtpB,EAAG,uBAC1Ew6B,EAAU9I,QAAU,IAAM3uB,EAAKw3B,SAAWx3B,EAAKw3B,UAC/CF,EAAM3M,YAAY8M,EACpB,CAEA,GAAIz3B,EAAK03B,cAAe,CACtB,MAAMC,EAAepR,EACnB,8DAA8DtpB,EAAG,WAAY,CAAEjC,KAAMiC,EAAG,iCAE1Fq6B,EAAM3M,YAAYgN,GAClBA,EAAahJ,QAAU,IAAM3uB,EAAK03B,eAAiB13B,EAAK03B,eAC1D,CAEYzL,GAAAjsB,EAAK43B,KAAMN,EACzB,CC9Ba,MCcPO,GAA8B,CChBAC,IAC5B,MAAA7iB,EAAO6iB,EAAIxkB,OAAO,UAEpBwkB,EAAAzjB,GAAG,cAAe0jB,IACpB,GAAID,EAAI/hB,UAAUiiB,aAAc,OAC5BF,EAAA/hB,UAAUiV,YAAW,GAEzB,MAAM/U,EAA0BwH,EAAA,CAE9BrH,OAAQ,EACR6hB,MAAOhjB,EAAKzB,MAAMgG,WAAWC,SAC7Bd,SAAU1D,EAAKzB,MAAMmF,SACrBuf,eAAgBjjB,EAAKzB,MAAM2kB,yBACxBJ,GAIDD,EAAA/hB,UAAUqiB,iBAAiB,CAC7BniB,WAIF,MAAMoiB,EAAY,CAChBJ,MAAOhiB,EAAOgiB,MACd7hB,OAAQH,EAAOG,OACfkiB,UAAWriB,EAAO0C,SAClBwD,SAAUlH,EAAKzB,MAAM8E,QACrB+D,UAAWpH,EAAKzB,MAAMgF,MAIpBvC,EAAOiiB,gBAAuBjiB,EAAAiiB,eAAeG,GAI9CP,EAAAliB,SACA8R,SAAShT,YAAY+I,EAAAA,EAAA,CAAA,EACjB4a,GACAP,EAAIliB,SAASsQ,kBAEjB7F,MAAK,EAAG/D,WAKPwb,EAAI/hB,UAAUqiB,iBAAiB,CAAEniB,SAAQqG,SAGzCwb,EAAI/hB,UAAUwiB,aAAajc,EAAKoL,UAGhCoQ,EAAI/hB,UAAUkN,WAAW3G,EAAK0G,MAGvB/M,EAAAgd,WAAahd,EAAOgd,UAAU3W,GAErCwb,EAAItjB,QAAQ,eAAgB,CAAEyB,SAAQqG,QAAM,IAE7CoE,OAAOrP,IAEN,MAAM9S,EAAQ,CACZ0Y,IAAK5F,EAAE4F,KAAOzP,OAAO6J,GACrBiL,KAAMjL,EAAEiL,MASJ,MANCrG,EAAAuiB,SAAWviB,EAAOuiB,QAAQj6B,GAG7Bu5B,EAAAtjB,QAAQ,cAAejW,GAC3Bu5B,EAAItjB,QAAQ,eAAgB,CAAEyB,SAAQ1X,UAEhC8S,CAAA,IAEPshB,SAAQ,KACHmF,EAAA/hB,UAAUiV,YAAW,EAAK,GAC/B,GACJ,EC3EmC8M,IAC9B,MAAA1uB,EAAO0uB,EAAIxkB,OAAO,QAEpBwkB,EAAAzjB,GAAG,cAAeiiB,IACH,IAAbA,EAAElgB,QAEU4U,IAAA,EAAM5hB,EAAKuL,QAAO,IAIhCmjB,EAAAzjB,GAAG,gBAAgB,KACP2W,IAAA,EAAO5hB,EAAKuL,QAAO,GAClC,ECZkCmjB,IAC7B,MAAA7iB,EAAO6iB,EAAIxkB,OAAO,UAEpBwkB,EAAAzjB,GAAG,oBAAqBtJ,IAEtB,GAAAkK,EAAKzB,MAAM2G,oBAAqB,CAClC,MAAM2Y,EAAWgF,EAAI/hB,UAAUyM,cACzBiW,EAAS3F,EAAS5J,MAAMzc,GAAMA,EAAEisB,aAAe3tB,EAAQ4tB,UAEzDF,GAEM1tB,EAAA6tB,YAAYC,WAAU,GACtB9tB,EAAA6tB,YAAYE,eAAc,KACzB19B,OAAA2K,KAAK0yB,EAAOM,WAGnBjB,EAAI/hB,UAAU8c,eAAeC,EAASlmB,QAAQH,GAAMA,EAAEisB,aAAe3tB,EAAQ4tB,UAAQ,KAI/E5tB,EAAA6tB,YAAYC,WAAU,EAElC,KAGEf,EAAAzjB,GAAG,aAAc2kB,IACb,MAAApW,EAAYqW,EAAoB,kBAClCrW,GAGCkV,EAAAliB,SACAkd,SAASpQ,eAAesW,EAAWpW,GACnCvC,MAAK,KAEJyX,EAAI/hB,UAAU8c,eACZiF,EACG/hB,UACAyM,cACA5V,QAAQH,GAAMA,EAAEisB,aAAeM,IAAS,GAGnD,GACD,EC1CsClB,IACjC,MAAA1uB,EAAO0uB,EAAIxkB,OAAO,QAClB4lB,EAAcpB,EAAIxkB,OAAO,eAC3B,IAAA6lB,EAIArB,EAAAzjB,GAAG,WAAW,KAChB8kB,EAAmB/vB,EAChBuL,QACA0V,cAA2B,uCAGb8O,EAAApN,iBAAiB,SAAS,KACzC,MAAM/I,EAAO8U,EAAI/hB,UAAUqjB,UAC3B,IAAKpW,EAAY,MAAA,IAAIvP,MAAM,uBAEtBuP,EAAAqW,YAAcrW,EAAKqW,WA0B9B,SAA2BvB,EAAe9U,GACxC8U,EAAIlhB,oBACJkhB,EACGliB,SACAqG,MAAMgH,WAAWD,EAAKb,GAAIa,GAC1B3C,MAAK,EAAG/D,WACHwb,EAAA/hB,UAAUkN,WAAW3G,EAAI,IAE9BoE,OAAOvhB,IACN24B,EAAI9gB,iBAAiB,GAAG/Z,EAAG,gBAAgBkC,EAAIymB,SAAWpe,OAAOrI,KAAQ,IAAG,IAE7EwzB,SAAQ,KACPmF,EAAIhhB,mBAAkB,GAE5B,CAvCMwiB,CAAkBxB,EAAK9U,EAAI,GAC5B,IAIC8U,EAAAzjB,GAAG,eAAgB2O,KAEI,KAArB,MAAAA,OAAA,EAAAA,EAAMqW,aAEK,MAAAH,GAAAA,EAAAtD,YAAYphB,QAAQ,gBACZ2kB,IAAAA,EAAiBr+B,UAAYmC,EAAG,kBAGxC,MAAAi8B,GAAAA,EAAAtD,YAAYphB,QAAQ,eACZ2kB,IAAAA,EAAiBr+B,UAAYmC,EAAG,iBACvD,IAGE66B,EAAAzjB,GAAG,eAAgBqT,IAErBoQ,EAAI1gB,kBAAiB,GACtB,ECtCiC0gB,IAC5B,MAAA1uB,EAAO0uB,EAAIxkB,OAAO,QAcpBwkB,EAAAzjB,GAAG,eAAe,KAZI,cACxB,MAAMklB,EAASnwB,EAAKuL,QAAQ0V,cAAc,gCAC1C,IAAKkP,EAAQ,OAEb,MAAMhyB,EAAOR,EACX9J,EAAG,UAAW,CACZ0gB,MAAO,GAAGte,OAAO,OAAA8f,EAAA,OAAA3M,EAAAslB,EAAI/hB,UAAUyjB,yBAAoB,EAAAhnB,EAAA8J,WAAM,EAAA6C,EAAAxB,QAAU,OAGvE4b,EAAO/+B,UAAY+M,EAAK/L,QAAQ,QAAS,gDAA+C,QAOtFs8B,EAAAzjB,GAAG,oBAAoB,KAEzB,MAAM3J,EAAOotB,EAAI/hB,UAAUyjB,oBACjB,MAAN9uB,OAAM,EAAAA,EAAA4R,QAAW5R,EAAA4R,KAAKqB,OAAS,EAAA,IAGjCma,EAAAzjB,GAAG,mBAAmB,KAExB,MAAM3J,EAAOotB,EAAI/hB,UAAUyjB,oBACjB,MAAN9uB,OAAM,EAAAA,EAAA4R,QAAW5R,EAAA4R,KAAKqB,OAAS,EAAA,GACpC,EC9BsCma,IACjC,MAAA1uB,EAAO0uB,EAAIxkB,OAAO,QACxB,IAAImmB,EAAsC,KAE1C,MAAMC,EAAa,KACjB,IAAKD,EAAiB,OACtB,MAAMve,EAAO4c,EAAIxkB,OAAO,QAAQyC,UAGhC,GAAMmF,EAAKlgB,MAAUkgB,EAAKta,MAAO,CACf64B,EAAAvP,UAAUI,OAAO,YAG3B,MAAAqP,EAAWF,EAAgBpP,cAA2B,aACxDsP,IAAmBA,EAAA7+B,UAAaogB,EAAK6X,SAA6B91B,EAAG,cAArBA,EAAG,aAA8B,MAErEw8B,EAAAvP,UAAUpN,IAAI,WAChC,EAGFgb,EAAI3iB,UAAU,CAAC,WAAYF,IACzBwkB,EAAkBrwB,EAAKuL,QAAQ0V,cAA2B,gCACrDoP,IAELA,EAAgB9K,QAAU,KAExBmJ,EAAIxgB,aAAY,UAMhBwgB,EAAAzjB,GAAG,gBAAiB6G,UAEvB,ECnCuC4c,IAClC,MAAA1uB,EAAO0uB,EAAIxkB,OAAO,QACxB,IAAIsmB,EAAmC,KAanC9B,EAAAzjB,GAAG,WAAW,KAChBulB,EAAexwB,EAAKuL,QAAQ0V,cAA2B,oBAAmB,IAGxEyN,EAAAzjB,GAAG,oBAAqBye,IAfJ,IAACnV,IAgBPmV,EAASh2B,QAAU,EAf9B88B,IAEDjc,EAAQ,GACVic,EAAa9+B,UAAY,GAAGuE,OAAOse,GAAS,KAC5Cic,EAAa3qB,MAAM2b,QAAU,SAE7BgP,EAAa3qB,MAAM2b,QAAU,OASK,GACrC,ECnBoCkN,IAC/B,MAAA1uB,EAAO0uB,EAAIxkB,OAAO,QAClB2B,EAAO6iB,EAAIxkB,OAAO,UAElBumB,EAAyBlT,IAC7B1R,EAAKC,OAAO,CACVijB,wBAAyBxR,IAE3BmR,EAAI3hB,QAAO,EAGP2jB,EAAgBC,KAwDxB,SAAwB9kB,GAIhB,MAAA+kB,cAAEA,EAAeC,aAAAA,GAAiBhlB,EACpC,GAAA+kB,EAAc3P,cAAc,iBAAkB,OAGpC2P,EAAA9P,UAAUpN,IAAI,qBAGdkd,EAAAvb,OAAO8H,EAAoB,8CAGzC,IAAI2T,EAAa,EACjB,MAAMC,EAAc,CAAChuB,EAAWsiB,EAAoBzzB,EAAcwqB,SAInD0U,EAAA/tB,EACbiuB,EAAUvd,iBAAiB,WAAW9P,SAASsE,IAC3CA,EAAA6Y,UAAUI,OAAO,SAAQ,IAEvBmE,EAAAvE,UAAUpN,IAAI,UAGpBsd,EAAUnrB,MAAM2b,QAAU,OAC1BE,YAAW,KACTsP,EAAUnrB,MAAM2b,QAAU,EAAA,GACzB,GAAE,EAIDwP,EAAY7T,EAAoB,8CACzB0T,EAAAltB,SAAQ,CAAC1E,EAAM8D,KACpB,MAACnR,EAAMwqB,GAAUnd,EAEjBomB,EAAQlI,EAAoB,oDAC5B2M,EAAQzE,EAAMpE,cAA2B,QAC/C6I,EAAMp4B,UAAYE,EAClBk4B,EAAMvE,QAAU,KACFwL,EAAAhuB,EAAGsiB,EAAOzzB,EAAMwqB,EAAM,EAEpC4U,EAAU3b,OAAOgQ,GAEbtiB,IAAM+tB,GAAkBzL,EAAAvE,UAAUpN,IAAI,SAAQ,IAGpDkd,EAAcvb,OAAO2b,EACvB,CAxGmBC,CAAA,CACbL,cAAeD,EACfE,aAAc,CACZ,CACEh9B,EAAG,cACH,KACE48B,GAAuBvD,IACrBA,EAAEgE,QAAU,WAAA,GACb,GAGL,CACEr9B,EAAG,YACH,KACE48B,GAAuBvD,IACrBA,EAAEgE,QAAU,MAAA,GACb,GAGL,CACEr9B,EAAG,cACH,KACE48B,GAAuBvD,IACrBA,EAAEgE,QAAU,UAAA,GACb,GAGL,CACEr9B,EAAG,cACH,KACE48B,GAAuBvD,IACrBA,EAAEiE,iBAAkB,CAAA,GACrB,KAIR,EAGHzC,EAAI3iB,UAAU,CAAC,WAAY,WAAYF,IACrC,MAAMskB,EAASnwB,EAAKuL,QAAQ0V,cAA2B,sBAClDkP,IAGDtkB,EAAKiE,SACP4gB,EAAaP,GA8DnB,SAAwBtkB,WAChB,MAAA+kB,cAAEA,GAAkB/kB,EACZ+kB,EAAA9P,UAAUI,OAAO,qBACjB,OAAA9X,EAAAwnB,EAAA3P,cAAc,0BAAyB7X,EAAA8X,SACvC,OAAAnL,EAAA6a,EAAA3P,cAAc,mBAAkBlL,EAAAmL,QAChD,CAjEqBkQ,CAAA,CACbR,cAAeT,IAEnB,GACD,EChE0CzB,IAC3C,IAAI2C,EAAS,EACb,MAAMC,EAAQ,EAAGC,aACf,MAAM3B,EAqBV,WAIE,MAAM/9B,EAAQG,OAAOC,SAASqS,KAAKzS,MAAM,yBACzC,IAAI0nB,EACF1nB,GAASA,EAAM,KAAOoE,OAAOu7B,MAAMC,WAAW5/B,EAAM,KAAO4/B,WAAW5/B,EAAM,IAAM,KAG/E0nB,IACSA,EAAAtjB,OAAO45B,EAAoB,iBAGzC,OAAOtW,GAAa,IACtB,CAnCsBmY,GACb9B,IAED2B,GAAUF,IAAWzB,IAChByB,EAAAzB,EAELlB,EAAAtjB,QAAQ,YAAawkB,IAAS,EAG9B+B,EAAoB,IAAML,EAAM,CAAEC,QAAQ,IAC1CK,EAAoB,IAAMN,EAAM,CAAEC,QAAQ,IAC5C7C,EAAAzjB,GAAG,WAAW,KACTjZ,OAAA2wB,iBAAiB,aAAcgP,GAClCjD,EAAAzjB,GAAG,cAAe2mB,EAAiB,IAErClD,EAAAzjB,GAAG,aAAa,KACXjZ,OAAA0wB,oBAAoB,aAAciP,GACrCjD,EAAAxjB,IAAI,cAAe0mB,EAAiB,GACzC,EZtBqClD,IAChC,MAAA1uB,EAAO0uB,EAAIxkB,OAAO,QAEpBwkB,EAAAzjB,GAAG,aAAoB2kB,GAAct6B,EAAA0Q,QAAA,MAAA,YAEnC,IAAArE,EAAU+sB,EAAIrjB,kBAAkByU,MAAMJ,GAAMA,EAAE6P,UAAYK,IAC9D,IAAKjuB,EAAS,CAEN,MAAAuR,SAAcwb,EAAIliB,SAAS8R,SAASxF,WAAW8W,IAAY1c,KAC5DlT,EAAA6xB,UAAU,CAAEC,eAAe,IAAQC,OAAO7e,EAAKvR,QAASuR,EAAK8e,eACxDrwB,EAAA+sB,EAAIrjB,kBAAkByU,MAAMJ,GAAMA,EAAE6P,UAAYK,GAC5D,CACKjuB,GACLA,EAAQie,OAAM,KACf,EaZqC8O,IAChC,MAAA1uB,EAAO0uB,EAAIxkB,OAAO,QAClB2B,EAAO6iB,EAAIxkB,OAAO,UAEpBwkB,EAAAzjB,GAAG,eAAgBqT,IAEf,MAAA2T,EAAc3T,EAAS5qB,QAAU,EACvC,IAAIw+B,EAAalyB,EAAKmyB,oBAAoBlR,cAA2B,wBAEjEgR,EACGC,IACUA,EAAA/U,EAAoB,2CAGtB+U,EAAA9gC,UAAY0U,GAAS+F,EAAKzB,MAAMlT,WAAaw3B,EAAI76B,GAAG,cAC1DmM,EAAAmyB,oBAAoB5Q,YAAY2Q,IAG3B,MAAAA,GAAAA,EAAAhR,QACd,GACD,ECrBqCwN,IAChC,MAAA1uB,EAAO0uB,EAAIxkB,OAAO,QAEpBwkB,EAAAzjB,GAAG,WAAW,KAChB,MAAMmnB,EAAapyB,EAAKuL,QAAQ0V,cAA2B,kBACtDmR,IAEMA,EAAAhhC,UACT,6EACkCihC,iBAAc,GAEnD,ECVuC3D,IAClC,MAAA1uB,EAAO0uB,EAAIxkB,OAAO,QAClB2B,EAAO6iB,EAAIxkB,OAAO,UACxB,IAAIye,EAAuB,KAEvB+F,EAAAzjB,GAAG,WAAW,KACR0d,EAAA32B,OAAOsgC,aAAY,KACzBtyB,EACGuL,QACAkI,iBAA8B,2BAC9B9P,SAASrR,YACF,MAAAsB,EAAO,IAAIM,KAAK+B,OAAO3D,EAAGyhB,aAAa,2BAC1CzhB,EAAAZ,WAAY,OAAAqkB,GAAK3M,EAAAyC,EAAAzB,OAAMmoB,+BAAgB3+B,KAAS4+B,EAAc5+B,EAAM86B,EAAI76B,GAAE,GAC9E,GACF,IAAS,IAGV66B,EAAAzjB,GAAG,aAAa,KACT0d,GAAA32B,OAAOygC,cAAc9J,EAAK,GACpC,EbnBuC+F,IAClC,MAAA1uB,EAAO0uB,EAAIxkB,OAAO,QAEpBwkB,EAAAzjB,GAAG,cAAc,KAEP4X,GAAA7iB,EAAKuL,QAAS,KAAI,IAG5BmjB,EAAAzjB,GAAG,eAAgBlV,IACLk4B,GAAA,CACdO,KAAMxuB,EAAKuL,QACX4iB,OAAQp4B,EAAI8X,IACZ6kB,QAAS38B,EAAImd,KACbkb,QAAS,IAAMM,EAAI9hB,MAAM,CAAEI,OAAQ,KACpC,GACF,EcjBuC0hB,IAClC,MAAA1uB,EAAO0uB,EAAIxkB,OAAO,QAClB2B,EAAO6iB,EAAIxkB,OAAO,UACxB,IAAIyoB,EAAwC,KAEtC,MAwBAC,EAAgB,KACV,MAAAD,GAAAA,EAAAE,aACCF,EAAA,IAAA,EAGTjE,EAAAzjB,GAAG,eAAe,SAId,MAAAuF,EAAWxQ,EAAKmyB,oBAAoBW,WACpCC,EAAUviB,EAAS9c,OAAS,EAAK8c,EAASA,EAAS9c,OAAS,GAAqB,KAClFq/B,IAGC,yBAA0B/gC,OAtCZ,CAAC+gC,YACrB,MAAMC,GAAc,OAAAjd,GAAA3M,EAAAyC,EAAKzB,OAAM6oB,uBAAwB,EAAAld,EAAAzW,KAAA8J,KAAA,KAEvDupB,EAAW,IAAIO,sBACb,EAAErO,MACIA,EAAQsO,qBAKVzE,EAAItjB,QAAQ,qBACd,GAEF,CACEgoB,UAAW,GAIXC,KAAML,IAGVL,EAASW,QAAQP,EAAO,EAuBxBQ,CAAcR,GALZ39B,QAAQo+B,KAAK,0CAKM,IAGnB9E,EAAAzjB,GAAG,aAAa,WAEnB,ECpDqCyjB,IAChC,MAAA1uB,EAAO0uB,EAAIxkB,OAAO,QAClB2B,EAAO6iB,EAAIxkB,OAAO,UAElBhJ,EAAU,aACd,MAAMuyB,EAAY,OAAA1d,GAAA3M,EAAAyC,EAAKzB,OAAM6oB,uBAAX,EAAAld,EAAAzW,KAAA8J,IAChBqqB,GAAazhC,QAAQuwB,OAAO,CAC5BtvB,IAAKygC,EAAgB1zB,EAAKuL,QAASkoB,GAAWxgC,IAC9CC,KAAM,GACP,EAGCw7B,EAAAzjB,GAAG,WAAW,KACZyjB,EAAAzjB,GAAG,kBAAmB/J,EAAO,IAG/BwtB,EAAAzjB,GAAG,aAAa,KACdyjB,EAAAxjB,IAAI,kBAAmBhK,EAAO,GACnC,GCjBH,IAAIyyB,IAAqB,ECDzB,IAAIC,GAEJ,SAASC,GAAiBC,EAAqB1nB,GAC7C,MAAM2nB,EAAoB,gBAErBD,EAAAnwB,SAAS+c,IACRtU,EAAUsU,EAAII,UAAUpN,IAAIqgB,GAC3BrT,EAAII,UAAUI,OAAO6S,EAAiB,GAE/C,CAEa,MCMP/uB,GAA4B,CAChCgvB,QAAS,uBACTC,UAAW,yBACXC,UAAW,6BACXC,YAAa,+BACbC,YAAa,UAgGf,SAASC,GACPC,EACAC,EACAC,EACAC,EACAC,WAGIJ,EAAMJ,UACFI,EAAAJ,UAAUxiC,UAAY0M,OAAOm2B,GAC1BD,EAAMN,UACfM,EAAMN,QAAQtiC,UAAY,GAAGmC,EAAG,cAAc0gC,MAI5CD,EAAMH,YACFG,EAAAH,YAAYziC,UAAY0M,OAAOo2B,GAC5BF,EAAML,YACfK,EAAML,UAAUviC,UAAY,GAAGmC,EAAG,gBAAgB2gC,MAGhC,kBAATC,IACT,OAAArrB,EAAAkrB,EAAMN,UAAS5qB,EAAA0X,UAAU6T,OAAOL,EAAMF,aAAe,SAAUK,IAC3C,kBAAXC,IACT,OAAA3e,EAAAue,EAAML,YAAWle,EAAA+K,UAAU6T,OAAOL,EAAMF,aAAe,SAAUM,GACrE,CAQA,MAAME,GACJ,CAAClZ,EAAuBnd,IAA0CkoB,IAChEA,EAAIE,iBACJ,MAAM2N,MAAEA,EAAAO,OAAOA,EAAQC,QAAAA,GAAYv2B,IAC9Bs2B,GACLC,EAAQC,MACLtZ,WAAW,OAAQoZ,EAAQnZ,EAAQrH,EAC/B,CAAA,EAAAygB,EAAQhY,kBAEZ7F,MAAK,EAAG/D,WACUmhB,GAAAC,EAAOphB,EAAKqhB,GAAIrhB,EAAKshB,KAAMthB,EAAK8hB,MAAO9hB,EAAK+hB,QAAO,IAErE3d,OAAOvhB,IACC/D,OAAAkjC,MAAMrhC,EAAG,aACRuB,QAAAD,MAAM,mBAAoBY,EAAG,GACtC,ECtKM,MCFPo/B,GAAiB,aAMhB,MAAMC,GAGX,WAAAxrB,CAAoBhT,GAFZkT,EAAAvU,KAAA,QAEYA,KAAAqB,KAAAA,EAEZ,MAAAy+B,EAAYpgB,KAAK5L,MAAMrX,OAAOk2B,aAAaC,QAAQgN,KAAmB,MAG5E5/B,KAAK2d,KAAO,CACVthB,KAAMyjC,EAAUzjC,MAAQyjC,EAAU99B,MAAQ,GAC1CC,MAAO69B,EAAU79B,OAAS,GAC1BC,KAAM49B,EAAU59B,MAAQ,GACxBiG,MAAO23B,EAAU33B,OAAS,GAC1BisB,SAAU0L,EAAU1L,UAAY0L,EAAUC,UAAW,EAEzD,CAEA,OAAA3oB,GACE,OAAOpX,KAAK2d,IACd,CAGA,MAAApH,CAAO6C,EAA0B,IACxBjP,OAAAmlB,QAAQlW,GAAKhL,SAAQ,EAAEnG,EAAKoG,MAC5BrO,KAAA2d,KAAK1V,GAAOoG,CAAA,IAGnB5R,OAAOk2B,aAAaE,QAAQ+M,GAAgBlgB,KAAKC,UAAU3f,KAAK2d,OAChE3d,KAAKqB,KAAK2+B,eAAiBhgC,KAAKqB,KAAK2+B,cAAchgC,KAAK2d,KAC1D,CAOA,MAAA+V,GACE1zB,KAAKuW,OAAO,CACVpO,MAAO,GACPisB,UAAU,GAEd,CAGA,qBAAAvX,GACS,QAAE7c,KAAK2d,KAAKthB,QAAU2D,KAAK2d,KAAK1b,KACzC,ECzBK,SAASg+B,GAAWC,GACnB,MAAAC,EAAcvY,EAAoB,+CAClCwY,EAAUxY,EACd,0FAEFwY,EAAQ9vB,MAAM2b,QAAU,OACxBkC,GAAegS,EAAa,CAAErU,eAAe,IAC7CsU,EAAQzsB,IAAMusB,EAAQG,UAAUC,sBAChCF,EAAQG,OAAS,KACfH,EAAQ9vB,MAAM2b,QAAU,GACxBoC,GAAe8R,EAAW,EAE5BA,EAAYrgB,OAAOsgB,GAEnB,MAAMI,EAAY5Y,EAChB,4EAEFuY,EAAYrgB,OAAO0gB,GAEnBN,EAAQO,oBAGR,IAAIC,GAAO,EA6BJ,OAtBN,SAAgBC,IAAc,OAAA5gC,EAAAC,KAAA,MAAA,YANjB,IAAC4gC,EAQb,SARaA,EAOD,IANZ,IAAI9Z,SAASC,IACXtqB,OAAO0vB,YAAW,KAChBpF,EAAQ,KAAI,GACX6Z,EAAE,KAIHF,EAAM,OACV,IAAIG,GAAS,EACT,IAEFA,SADmBX,EAAQjpB,SAAS6pB,QAAQ1d,oBAC9BzF,KAAKojB,OAAA,CACb,MAAAruB,GACGmuB,GAAA,CACX,CACIA,EACFX,EAAQc,oBAGV,IAdD,GAiBDR,EAAUxQ,QAAU,KACX0Q,GAAA,EACPR,EAAQr7B,QAAO,EAGVs7B,CACT,CC9EA,MAAMc,GAA0B,CAC9Bte,QAAA,CAAQud,EAASgB,IACRhB,EAAQjpB,SAAS6pB,QAAQzd,cAAc,CAC5ChV,MAAO6yB,IAIXzgB,KAAKyf,GACCA,EAAQrrB,IAAI,UAAkBssB,GAAkBjB,GDLjD,SAAiBA,GAEtB,MAAM3T,EAAO3E,EACX,2CAA2CsY,EAAQrrB,IAAI,aAAe,OAAOvW,EAAG,0BAgB3E,OAZPiuB,EAAKb,cAA2B,oBAAqBsE,QAAU,KACvD,MAAAD,EAAQxD,EAAKb,cAAc,oBACjCwU,EACGjpB,SACA6pB,QAAQ3d,aACRzB,MAAMhD,IACLqR,EAAOF,aAAa,MAAOnR,EAAIf,KAAKyjB,SAAQ,IAE7Crf,OAAOvhB,IACEX,QAAAD,MAAM,+BAAgCY,EAAG,GAClD,EAEE+rB,CACT,CCdW8U,CAAenB,GAGxB,SAAA5L,CAAU4L,EAASviB,EAAMujB,EAAUI,GACzBpB,EAAA5qB,IAAI,MAAO4rB,EACrB,EAEA,OAAArH,CAAQqG,EAAS1/B,EAAK0gC,EAAUI,GACvBA,EAAA5V,cAA2B,oBAAqBqF,QAChDuQ,EAAA5V,cAAgC,sBAAuBrd,MAAQ,EACxE,GClBIkzB,GAA2C,CAC/CC,UAAW,WAEL,OAAA7e,CAAQud,EAASgB,GAAU,OAAAnhC,EAAAC,KAAA,MAAA,YAC/B,aACQkgC,EAAQjpB,SAASsF,KAAKgJ,MAAM,CAChClpB,KAAM6jC,EAAQ/oB,UAAUC,UAAU/a,KAClC4F,MAAOi+B,EAAQ/oB,UAAUC,UAAUnV,MACnC4D,SAAUq7B,KAEZvjB,IACJ,GAAA,EAEA8C,KAAKyf,GACItY,EAAoB,SAAStpB,EAAG,wBAGzC,SAAAg2B,CAAU4L,EAASxhB,EAAKwiB,EAAUI,GACxBpB,EAAA/oB,UAAUZ,OAAO,CACvB6d,UAAU,EACVjsB,MAAOuW,EAAIvW,QAEL+3B,EAAAG,UAAUoB,UACpB,EAEA,OAAA5H,CAAQqG,EAAS1/B,EAAK0gC,EAAUI,GAAS,GCrB3C,MAAqBI,GAKnB,WAAArtB,CAAYstB,GAJLptB,EAAAvU,KAAA,OACAuU,EAAAvU,KAAA,YACAuU,EAAAvU,KAAA,YAGLA,KAAKmrB,IAAMvD,EACT,6NASF5nB,KAAK4hC,SAAW5hC,KAAKmrB,IAAIO,cAA2B,6BAGpD1rB,KAAK6hC,SAAW7hC,KAAKmrB,IAAIO,cAAc,6BAClC1rB,KAAA6hC,SAAS7V,YAAY2V,EAC5B,CAGO,MAAAG,CAAOn2B,GACZ,MAAMo2B,EAAMna,EACV,iCAAiCtpB,EAAG,uBAK/B,OAHHyjC,EAAA/R,QAAUhwB,KAAKgiC,WAAWr2B,GACzB3L,KAAA4hC,SAAS5V,YAAY+V,GAEnB/hC,IACT,CAGO,KAAAiiC,CAAMt2B,GACX,MAAMo2B,EAAMna,EACV,gCAAgCtpB,EAAG,sBAK9B,OAHHyjC,EAAA/R,QAAUhwB,KAAKgiC,WAAWr2B,GACzB3L,KAAA4hC,SAAS5V,YAAY+V,GAEnB/hC,IACT,CAEQ,UAAAgiC,CAAWr2B,GACjB,OAAQulB,IACN,MAAM1f,EAAK7F,EAAQulB,EAAIgR,cAA8BliC,WAC1C,IAAPwR,IAA2B,IAAPA,GACtBxR,KAAKmrB,IAAIQ,QACX,CAEJ,ECjCF,SAASwW,GAAuDxxB,GAC9D,OAAQiF,GACN,IAAIkR,SAAc,CAACC,EAASqb,KAC1B,MAAMC,EAAWzsB,EAAQ0sB,SACzB1sB,EAAQ0sB,SAAW,KACjBD,GAAYA,IACLD,EAAA,IAAIttB,MAAM,6BAA4B,EAE/C,MAAMytB,EAAY3sB,EAAQ0e,UAC1B1e,EAAQ0e,UAAY,KAClBiO,GAAaA,SAGf5xB,EAAGiF,EAAO,GAEhB,CAKO,MAAM4sB,GACX,WAAAnuB,CAAoBhT,GAEqDkT,EAAAvU,KAAA,eAAAmiC,IAAaxK,IACpF33B,KAAK+7B,MAAMkF,GAAgBtJ,GAAIwB,IACzBA,EAAA7jB,IAAI,WAAYqiB,EAAEyJ,UAClBjI,EAAA7jB,IAAI,SAAUqiB,EAAEhoB,OAAM,GAC3B,KAG6D4E,EAAAvU,KAAA,aAAAmiC,IAAaxK,IACtE33B,KAAA+7B,MAAMwF,GAAc5J,EAAC,KAVR33B,KAAAqB,KAAAA,CAA+B,CAa5C,KAAA06B,CAAMmE,EAAkBtqB,EAAyB6sB,GAEtD,MAAMC,EAAQ1iC,KAAKqB,KAAKshC,YAAYC,OAAO,YAAW,IAAIjkC,MAAOF,aACjEikC,EAAM9pB,OAEN,MAAM2d,EAAQ,KACZmM,EAAMzsB,SAAQ,EAIV4sB,EAA6B,CAAA,EACnC,IAAIpC,GAAoB,EACxB,MAAMqC,EAAyB,CAC7BxtB,IAAK,CAACrN,EAAK6O,KACT+rB,EAAa56B,GAAO6O,CAAA,EAEtBjC,IAAM5M,GAAQ46B,EAAa56B,GAC3Bo4B,QAAS,IAAMrgC,KAAKqB,KACpB8V,QAAS,IAAMnX,KAAKqB,KAAK8V,UACzBF,OAAQ,IAAMjX,KAAKqB,KAAK4V,SACxBwpB,kBAAmB,KACGA,GAAA,CAAA,EAEtBO,eAAgB,SAEVd,EAAQ5L,WAAW4L,EAAQ5L,UAAUwO,EAAY,GAAI,GAAIxB,GACzD1rB,EAAQ0e,WAAW1e,EAAQ0e,WAAU,EAE3CzvB,OAAQ,SAEF+Q,EAAQ0sB,UAAU1sB,EAAQ0sB,UAAS,GAIvCG,KAAyBK,GAGvB,MAAAxB,EAAS1Z,IACf0Z,EAAOtV,YAAYkU,EAAQzf,KAAKqiB,IAGhC,MAAMpS,EAAS9I,EACb,2BAA2BsY,EAAQsB,WAAa,uDAc9C,IAAAuB,EAZJzB,EAAOtV,YAAY0E,GACnBvE,YAAW,IAAMuE,EAAOrG,SAAS,IAG1BqG,EAAAsS,QAAW9R,IACA,UAAZA,EAAIjpB,KAAmC,KAAhBipB,EAAI0D,UAE7B1D,EAAIE,iBACJsR,EAAM1sB,QAAQ0V,cAAiC,iCAAkCqF,QACnF,EAII,MAAAkS,EAAS,IAAIvB,GAAOJ,GAGnB2B,EAAAnB,QAAQoB,IACP,MAAAhC,EAAWxQ,EAAOriB,MAAMvS,OAGzBinC,IAAYA,EAAaG,EAAM/mC,WAC9B,MAIAgnC,EAAiB,KACrBD,EAAM/mC,UAAY4mC,GAAc,GAC1BG,EAAA3X,UAAUI,OAAO,QAAO,EA6BzB,OA1BPuX,EAAM/mC,UAAY,GAAGmC,EAAG,gBAGxB4hC,EACGvd,QAAQmgB,EAAY5B,GACpBxf,MAAM/D,QAIDuiB,EAAQ5L,WAAW4L,EAAQ5L,UAAUwO,EAAYnlB,EAAMujB,EAAUI,GACjE1rB,EAAQ0e,WAAW1e,EAAQ0e,WAAU,IAE1CvS,OAAOvhB,IArBS,IAAC4iC,IAuBLv6B,OAAOrI,EAAIymB,SAAWpe,OAAOrI,IAtB1C0iC,EAAM/mC,UAAYinC,EACZF,EAAA3X,UAAUpN,IAAI,SAuBd+hB,EAAQrG,SAASqG,EAAQrG,QAAQiJ,EAAYtiC,EAAK0gC,EAAUI,GAGhE,MAAM+B,EAAKlX,YAAW,IAAMgX,KAAkB,KAC9CzS,EAAO4S,QAAU,SAEf3P,aAAa0P,EAAE,CAAA,KAId,CAAA,IAITJ,EAAOhB,OAAM,SAEPrsB,EAAQ0sB,UAAU1sB,EAAQ0sB,YACvB,KAGL7B,IACF/P,EAAOpgB,MAAM2b,QAAU,OACvBgX,EAAO9X,IAAIO,cAA2B,6BAA8Bpb,MAAM2b,QAAU,QAItFyW,EAAM1sB,QAAQ8J,OAAOmjB,EAAO9X,KAGxBvV,EAAQ2tB,SAAiB3tB,EAAA2tB,QAAQN,EAAO9X,IAC9C,EClLW,MCAPqY,GAAM,CACVvN,QAAS,cACTH,MAAO,4BACPC,OAAQ,6BACRxB,MAAO,4BACPiC,cAAe,qBACf/E,UAAW,gBACXgF,QAAS,cACTtB,WAAY,gBACZsO,YAAa,mBACbC,YAAa,mBACb/N,WAAY,kBACZyC,aAAc,qBACdD,eAAgB,wBCZX,MAAMwL,GACX,WAAAtvB,CAAoBuvB,GAEarvB,EAAAvU,KAAA,YAAA,UACauU,EAAAvU,KAAA,iBAAA,MAH1BA,KAAA4jC,OAAAA,CAAiB,CAMrC,GAAA/uB,GACE,OAAO7U,KAAK6jC,SACd,CAQA,OAAO9E,EAAoBnpB,qBAWrB,GATA5V,KAAK8jC,iBACP9jC,KAAK8jC,iBACL9jC,KAAK8jC,eAAiB,KAGtB,OAAAtjB,EAAA,OAAA3M,EAAA7T,KAAK4jC,OAAO3L,mBAAc,EAAApkB,EAAAgB,IAAIgW,MAAQrK,EAAAgL,QAI1B,WAAVuT,GAAsBnpB,EAAS,CAEjC,IAAImuB,EAAcnuB,EAAQiC,SACrB7X,KAAK4jC,OAAO9M,aAAa1gB,UAAUvB,MAAMmF,WAC9B+pB,EAAAA,EAAYrY,cAA2B,gBACvD,OAAAsY,EAAA,OAAA5T,EAAApwB,KAAK4jC,OAAO3L,uBAAcpjB,IAAIgW,QAAQC,KAAKiZ,GAErC,MAAA7F,EAAY,OAAA+F,UAAKL,OAAO9M,aAAa1gB,UAAUvB,OAAM6oB,uBAAzC,EAAAuG,EAAAl6B,KAAAm6B,GAClBC,GAAkBnkC,KAAK4jC,OAAO5M,QAAQ7L,KAAK,EAAM+S,GAE3C,MAAAkG,EAAS,OAAAC,EAAKrkC,KAAA4jC,OACjB3L,mBACC,EAAAoM,EAAApM,aACD1N,MAAMoN,GAAMA,EAAElP,wBAA0BsW,IACvCqF,GAAUA,EAAO1b,oBACnB1oB,KAAK8jC,eAAiBM,EAAO1b,kBAAkB9S,EAAQxJ,SAE3D,CAGApM,KAAK6jC,UAAY9E,CACnB,ECzCK,MAAMuF,GAOX,WAAAjwB,CAAYhT,GANJkT,EAAAvU,KAAA,QACAuU,EAAAvU,KAAA,OACAuU,EAAAvU,KAAA,MACAuU,EAAAvU,KAAA,SACAuU,EAAAvU,KAAA,WAGNA,KAAKqB,KAAOA,EAGZrB,KAAKy1B,GFOF,WACC,MAAAtK,EAAMvD,EG/BC,qwBHgCP6N,EAAK,CAAEtK,OAIN,OAHAhhB,OAAAmlB,QAAQkU,IAAKp1B,SAAQ,EAAEm2B,EAAGC,MAC/B/O,EAAG8O,GAAKpZ,EAAIO,cAAc8Y,EAAG,IAExB/O,CACT,CEdcgP,GACLzkC,KAAAmrB,IAAMnrB,KAAKy1B,GAAGtK,IAGdnrB,KAAA++B,MAAQ,IAAI4E,GAAmB3jC,KACtC,CAEA,UAAA82B,GACE,OAAO92B,KAAKqB,IACd,CAEA,KAAA2U,GACE,OAAOhW,KAAKmrB,GACd,CAEA,KAAA6L,GACE,OAAOh3B,KAAKy1B,EACd,CAEA,UAAAwC,GACE,OAAOj4B,KAAK42B,OACd,CAEA,UAAA8N,CAAW9N,GACT52B,KAAK42B,QAAUA,CACjB,CAEA,QAAArD,GACS,OAAAvzB,KAAK++B,MAAMlqB,KACpB,CAEA,iBAAAme,GACE,MAAO,CAAE32B,KAAM2D,KAAKy1B,GAAGK,MAAO7zB,MAAOjC,KAAKy1B,GAAGM,OAAQ7zB,KAAMlC,KAAKy1B,GAAGlB,MACrE,CAEA,eAAAnL,GACM,IAAA5Y,EAAUxQ,KAAK8yB,gBAGb,MAAA8D,EAAU52B,KAAKi4B,aAGd,OAFHrB,IAASpmB,EAAUomB,EAAQ4B,sBAAsBhoB,IAE9CA,CACT,CAEA,aAAAsiB,GACS,OAAA9yB,KAAKy1B,GAAGhE,UAAUpjB,OAAS,EACpC,CAEA,gBAAAkkB,GACS,OAAAtgB,GAAOjS,KAAKopB,kBACrB,CAEA,UAAA+I,CAAWrb,SACJ9W,KAAAy1B,GAAGhE,UAAUpjB,MAAQyI,EAG1B,OAAAjD,EAAA7T,KAAKi4B,eAAcpkB,EAAAojB,YAAYphB,QAAQ,kBAAmBiB,EAC5D,CAEA,aAAAmZ,CAAcnZ,GACZ,GAAKlb,SAAiB+oC,UACf3kC,KAAAy1B,GAAGhE,UAAUpH,QACCzuB,SAAA+oC,UAAUC,cAAch8B,KAAOkO,EAC7C9W,KAAAy1B,GAAGhE,UAAUpH,aAAM,GACfrqB,KAAKy1B,GAAGhE,UAAUoT,gBAAuD,IAArC7kC,KAAKy1B,GAAGhE,UAAUoT,eAAsB,CAC/E,MAAAC,EAAS9kC,KAAKy1B,GAAGhE,UAAUoT,eAC3BE,EAAO/kC,KAAKy1B,GAAGhE,UAAUuT,aACzBC,EAAKjlC,KAAKy1B,GAAGhE,UAAUj0B,UACxBwC,KAAAmyB,WACHnyB,KAAKy1B,GAAGhE,UAAUpjB,MAAMhC,UAAU,EAAGy4B,GACnChuB,EACA9W,KAAKy1B,GAAGhE,UAAUpjB,MAAMhC,UAAU04B,EAAM/kC,KAAKy1B,GAAGhE,UAAUpjB,MAAMlQ,SAE/D6B,KAAAy1B,GAAGhE,UAAUpH,QAClBrqB,KAAKy1B,GAAGhE,UAAUoT,eAAiBC,EAAShuB,EAAI3Y,OAChD6B,KAAKy1B,GAAGhE,UAAUuT,aAAeF,EAAShuB,EAAI3Y,OACzC6B,KAAAy1B,GAAGhE,UAAUj0B,UAAYynC,CAAA,MAEzBjlC,KAAAy1B,GAAGhE,UAAUpH,QACbrqB,KAAAy1B,GAAGhE,UAAUpjB,OAASyI,CAE/B,CAEA,KAAAuT,GACOrqB,KAAAy1B,GAAGhE,UAAUpH,OACpB,CAEA,KAAA7a,GACExP,KAAKmyB,WAAW,IAChBnyB,KAAK0Y,YACP,CAEA,UAAAA,GACO1Y,KAAA++B,MAAMmG,OAAO,SACpB,CAEA,eAAAptB,CAAgB1L,EAAsByL,GACpC7X,KAAK++B,MAAMmG,OAAO,QAAS,CAAE94B,UAASyL,YACxC,CAEA,cAAAG,CAAe5L,EAAsByL,GACnC7X,KAAK++B,MAAMmG,OAAO,OAAQ,CAAE94B,UAASyL,YACvC,CAEA,UAAAW,CAAWF,EAAaC,I/CrCV,SAAW4sB,EAAuB7sB,EAAaC,GACvD,MAGA6sB,EAAaxd,EACjB,gEAJa,CAAEyd,EAAG,UAAW3yB,EAAG,UAAW4yB,EAAG,UAAW93B,EAAG,WAIW+K,sDAEjD6sB,EAAW1Z,cAA2B,uBAC9C7vB,UAAYuM,EAAiBkQ,GAAKzb,QAAQ,KAAM,SAEhEsoC,EAASnZ,YAAYoZ,GAErB,MAAMG,EAAe,KACRH,EAAA7Z,UAAUpN,IAAI,gBACzBgO,YAAW,KACTiZ,EAAWzZ,QAAO,GACjB,IAAG,EAGJ,IAAA6Z,EAEUA,EAAA/oC,OAAO0vB,YAAW,WAnBhB,KAwBLiZ,EAAAhY,iBAAiB,SAAS,SAEnC3wB,OAAOk3B,aAAa6R,EAAS,GAEjC,C+CQIC,CAAczlC,KAAKy1B,GAAGgO,YAAanrB,EAAKC,EAC1C,CAEA,WAAAL,GACiBA,GAAAlY,KAAKy1B,GAAGtK,IACzB,CAEA,WAAA/S,GACiBA,GAAApY,KAAKy1B,GAAGtK,IACzB,CAEA,MAAA+J,GACE,MAAMwQ,EAAO,WACX,OAAA7xB,EAAA7T,KAAKi4B,eAAcpkB,EAAAojB,YAAYphB,QAAQ,iBACvC7V,KAAKqB,KAAK41B,YAAYphB,QAAQ,gBAAe,EAEzC8vB,EAAe3lC,KAAKqB,KAAK+U,UAAUvB,MAAM8wB,aAC3CA,EACFA,EAAa3lC,KAAM0lC,MAIvB,EE7IK,MAAME,GAgBX,WAAAvxB,CAAsBgjB,GAdK9iB,EAAAvU,KAAA,WAAA,GAGnBuU,EAAAvU,KAAA,iBAGAuU,EAAAvU,KAAA,WAA0B,IAG1BuU,EAAAvU,KAAA,WAAyB,IAGzBuU,EAAAvU,KAAA,QAEcA,KAAAq3B,OAAAA,CAAuB,CAE7C,UAAAgC,GACE,OAAOr5B,KAAKyG,OACd,CAEA,UAAA4lB,CAAWvV,GACT9W,KAAKyG,QAAUqQ,CACjB,CAEA,gBAAA+jB,GACE,OAAO76B,KAAK6lC,aACd,CAEA,gBAAApM,CAAiB3iB,GACf9W,KAAK6lC,cAAgB/uB,CACvB,CAKA,WAAAf,GACE,OAAO/V,KAAK+oB,QACd,CAEA,aAAAxR,CAAcD,GACPtX,KAAAq3B,OAAOxhB,QAAQ,aAAcyB,EACpC,CAEA,WAAAwuB,CAAYtiB,GACV,OAAOxjB,KAAK+oB,SAASwB,MAAMJ,GAAMA,EAAE3G,KAAOA,GAC5C,CAEA,aAAAuiB,GACE/lC,KAAK+oB,SAAW,GAChB/oB,KAAKq3B,OAAOxhB,QAAQ,cAAe7V,KAAK+oB,SAC1C,CAEA,YAAA6Q,CAAaoM,GACNhmC,KAAAq3B,OAAOxhB,QAAQ,YAAamwB,GAE5BhmC,KAAA+oB,SAASzb,QAAQ04B,GAEtBhmC,KAAKq3B,OAAOxhB,QAAQ,cAAe7V,KAAK+oB,SAC1C,CAEA,aAAAY,CAAcvd,GACPpM,KAAA+oB,SAASzb,KAAKlB,GAEdpM,KAAAq3B,OAAOxhB,QAAQ,mBAAoBzJ,GACxCpM,KAAKq3B,OAAOxhB,QAAQ,cAAe7V,KAAK+oB,SAC1C,CAEA,aAAAtF,CAAcrX,GACZpM,KAAK+oB,SAAW/oB,KAAK+oB,SAAS3T,KAAK+U,GAC7BA,EAAE3G,KAAOpX,EAAQoX,GAAWpX,EACzB+d,IAGJnqB,KAAAq3B,OAAOxhB,QAAQ,kBAAmBzJ,GACvCpM,KAAKq3B,OAAOxhB,QAAQ,cAAe7V,KAAK+oB,SAC1C,CAEA,aAAArF,CAAcF,GACN,MAAApX,EAAUpM,KAAK+oB,SAASwB,MAAMJ,GAAMA,EAAE3G,KAAOA,IACnD,IAAKpX,EAAS,MAAM,IAAI0I,MAAM,WAAW0O,eACpCxjB,KAAA+oB,SAAW/oB,KAAK+oB,SAAS9a,QAAQkc,GAAMA,EAAE3G,KAAOA,IAEhDxjB,KAAAq3B,OAAOxhB,QAAQ,kBAAmBzJ,GACvCpM,KAAKq3B,OAAOxhB,QAAQ,cAAe7V,KAAK+oB,SAC1C,CAKA,WAAAlF,GACE,OAAO7jB,KAAKm0B,QACd,CAEA,cAAAD,CAAeC,GACbn0B,KAAKm0B,SAAWA,EAEhBn0B,KAAKq3B,OAAOxhB,QAAQ,mBAAoB7V,KAAKm0B,SAC/C,CAKA,OAAAsG,GACE,OAAOz6B,KAAKqkB,IACd,CAEA,UAAAC,CAAW2hB,GACTjmC,KAAKqkB,KAAO4hB,EAEPjmC,KAAAq3B,OAAOxhB,QAAQ,cAAeowB,EACrC,ECnHK,MAAMC,GAIX,WAAA7xB,CACU8W,EACA9pB,GALekT,EAAAvU,KAAA,kBAAA,GACjBuU,EAAAvU,KAAA,eAGEA,KAAAmrB,IAAAA,EACAnrB,KAAAqB,KAAAA,CACP,CAEH,cAAA8kC,CAAene,GACbhoB,KAAKomC,YAAcpe,CACrB,CAEA,iBAAAqe,CAAkBC,GAChBtmC,KAAKumC,eAAiBD,CACxB,CAEA,iBAAAE,GACE,OAAOxmC,KAAKumC,cACd,CAEA,KAAAvwB,GACE,OAAOhW,KAAKmrB,GACd,CAEA,IAAAvS,GACE5Y,KAAKqB,KAAKolC,SACLzmC,KAAAmrB,IAAI7a,MAAM2b,QAAU,EAC3B,CAEA,IAAAnT,GACE9Y,KAAKqB,KAAKqlC,SACL1mC,KAAAmrB,IAAI7a,MAAM2b,QAAU,OACpBjsB,KAAAomC,aAAepmC,KAAKomC,aAC3B,CAEA,OAAAnwB,GACEjW,KAAKqB,KAAKqlC,SACV1mC,KAAKmrB,IAAIQ,SACJ3rB,KAAAomC,aAAepmC,KAAKomC,aAC3B,EC7CF,IAAIO,GACAC,GAEG,SAASC,KACP,MAAA,CACL,IAAAxgB,GACoBsgB,GAAA/qC,SAAS6kB,KAAKnQ,MAAMw2B,SAChBF,GAAAhrC,SAAS6kB,KAAKnQ,MAAMy2B,YAC5C,EAEA,MAAAC,GACWprC,SAAA6kB,KAAKnQ,MAAMw2B,SAAWH,GACtB/qC,SAAA6kB,KAAKnQ,MAAMy2B,aAAeH,EACrC,EAEA,IAAAK,GACWrrC,SAAA6kB,KAAKnQ,MAAMw2B,SAAW,SAC/B,MAAMI,EAAkBC,SACtB1qC,OAAO2qC,iBAAiBxrC,SAAS6kB,KAAM,MAAM4mB,iBAAiB,iBAC9D,IAEOzrC,SAAA6kB,KAAKnQ,MAAMy2B,aAAe,GnDuJlC,WACC,MAAAO,EAAQ1rC,SAASH,cAAc,KACrC6rC,EAAMh3B,MAAMtS,MAAQ,OACpBspC,EAAMh3B,MAAMuc,OAAS,QAEf,MAAA0a,EAAQ3rC,SAASH,cAAc,OACrC8rC,EAAMj3B,MAAMk3B,SAAW,WACvBD,EAAMj3B,MAAM5S,IAAM,MAClB6pC,EAAMj3B,MAAM3S,KAAO,MACnB4pC,EAAMj3B,MAAMm3B,WAAa,SACzBF,EAAMj3B,MAAMtS,MAAQ,QACpBupC,EAAMj3B,MAAMuc,OAAS,QACrB0a,EAAMj3B,MAAMw2B,SAAW,SACvBS,EAAMvb,YAAYsb,GAET1rC,SAAA6kB,KAAKuL,YAAYub,GAC1B,MAAMG,EAAKJ,EAAMK,YACjBJ,EAAMj3B,MAAMw2B,SAAW,SACvB,IAAIc,EAAKN,EAAMK,YAKf,OAJID,IAAOE,IAAIA,EAAKL,EAAMM,aAEjBjsC,SAAA6kB,KAAKtK,YAAYoxB,GAEnBG,EAAKE,CACd,CmD/K4CE,GAAyBZ,GAAmB,KACpF,EAEJ,CCtBO,MAAMa,GAKX,WAAA1zB,GAJQE,EAAAvU,KAAA,SACAuU,EAAAvU,KAAA,SACAuU,EAAAvU,KAAA,QAAiB,IAGvBA,KAAKgoC,MAAQpgB,EACX,+FAEF5nB,KAAKioC,MAAQjoC,KAAKgoC,MAAMtc,cAA2B,kBACrD,CAEA,UAAAwc,CAAW7rC,EAAcU,IAElBA,EAAAA,GAAMiD,KAAKmoC,kBAAkB9rC,IAC/BwzB,aAAa,kBAAmBxzB,GAC9B2D,KAAAgoC,MAAMhc,YAAYjvB,GAGjB,MAAA2lC,EAAQ,IAAIwD,GAAMnpC,EAAI,CAC1B2pC,OAAQ,IAAM1mC,KAAKooC,SAASrrC,GAC5B0pC,OAAQ,IAAMzmC,KAAKqoC,aAWd,OAPProC,KAAKsoC,UAAUlb,iBAAiB,SAAS,KACjCsV,EAAA8D,qBAAuB9D,EAAM5pB,MAAK,IAIrC9Y,KAAAivB,MAAM3hB,KAAKo1B,GAETA,CACT,CAEQ,iBAAAyF,CAAkB9rC,GAClB,MAAAU,EAAKnB,SAASH,cAAc,OAI3B,OAHJsB,EAAAwuB,UAAUpN,IAAI,kBACjBphB,EAAGuT,MAAM2b,QAAU,OACdjsB,KAAAgoC,MAAMhc,YAAYjvB,GAChBA,CACT,CAEA,OAAAwrC,GACE,OAAOvoC,KAAKgoC,KACd,CAEA,OAAAM,GACE,OAAOtoC,KAAKioC,KACd,CAEA,QAAAI,GACOroC,KAAAgoC,MAAM13B,MAAM2b,QAAU,QACtBjsB,KAAAioC,MAAM33B,MAAM2b,QAAU,QACtBjsB,KAAAioC,MAAM1c,UAAUpN,IAAI,eACzB0oB,KAAqBI,MACvB,CAEA,QAAAmB,CAASjd,GAGLnrB,KAAKivB,MACF7Z,KAAKozB,GAAMA,EAAExyB,UACb/H,QAAQyE,GAAMA,IAAMyY,GAAOzY,EAAE0Z,aAAmC,SAApB1Z,EAAEpC,MAAM2b,UAAoB9tB,OAAS,IAKjF6B,KAAAgoC,MAAM13B,MAAM2b,QAAU,OAC3B4a,KAAqBG,SACvB,ECtEK,MAAMyB,GAGX,WAAAp0B,GAFQE,EAAAvU,KAAA,OAAO,IAAI+nC,IAGjBlB,KAAqBxgB,MACvB,CAEA,KAAArQ,GACS,OAAAhW,KAAK0oC,KAAKH,SACnB,CAEA,MAAA3F,CAAOvmC,EAAcU,GACnB,OAAOiD,KAAK0oC,KAAKR,WAAW7rC,EAAMU,EACpC,CAEA,OAAAkZ,GACOjW,KAAA0oC,KAAKH,UAAU5c,QACtB,ECjBW,MAAAgd,GAA6CtnC,IAAU,CAClEunC,OAAS7f,KCQJ,SACL8f,EACAC,EAAqB,YACrB7uB,EAAU,GAEV,MAAM8uB,EAA0B,GAElBF,EAAQ56B,QAAQH,GAAgB,IAAVA,EAAEub,MAChCjb,SAAS0vB,IACb,MAAMkL,EAAwB,CAC5BxlB,GAAIsa,EAAKta,GACTpX,QAAS0xB,EACT7iB,SAAU,GACVguB,MAAO,GAGTD,EAASE,OAASF,EAClBD,EAASz7B,KAAK07B,GACZ,SAASG,EAAaC,GAChB,MAAAnuB,EAAW4tB,EAAQ56B,QAAQH,GAAMA,EAAEub,MAAQ+f,EAAW5lB,KACpC,IAApBvI,EAAS9c,SACTirC,EAAWH,OAAShvB,IAASmvB,EAAaA,EAAWF,QAChDjuB,EAAA7M,SAASi7B,IAChB,MAAMC,EAAyB,CAC7B9lB,GAAI6lB,EAAM7lB,GACVpX,QAASi9B,EACTpuB,SAAU,GACViuB,OAAQE,EACRH,MAAOG,EAAWH,MAAQ,GAGjBG,EAAAnuB,SAAS3N,KAAKg8B,GACzBH,EAAaG,EAAS,KAdxB,CAgBCN,EAAQ,IAIP,MAAAO,EAAW,CAAC75B,EAAgB85B,KAC5B,IAAApnB,EAAI1S,EAAE8T,GAAKgmB,EAAEhmB,GAKV,MAJQ,aAAXslB,EAA2B1mB,GAAC,IAAIzjB,KAAK+Q,EAAEtD,QAAQ/N,OAAS,IAAIM,KAAK6qC,EAAEp9B,QAAQ/N,MAC3D,cAAXyqC,EAA4B1mB,GAAC,IAAIzjB,KAAK6qC,EAAEp9B,QAAQ/N,OAAS,IAAIM,KAAK+Q,EAAEtD,QAAQ/N,MACjE,cAAXyqC,EAAwB1mB,EAAIymB,EAAQ18B,QAAQuD,EAAEtD,SAAWy8B,EAAQ18B,QAAQq9B,EAAEp9B,SAChE,iBAAX08B,IAA2B1mB,EAAIonB,EAAEp9B,QAAQq9B,QAAU/5B,EAAEtD,QAAQq9B,SAC/DrnB,CAAA,EAUF,OAPL,SAASsnB,EAAWC,GACdA,EAAAv7B,SAAS+B,IACbA,EAAK8K,SAAW9K,EAAK8K,SAAS2uB,KAAKL,GACnCG,EAAWv5B,EAAK8K,SAAQ,IAH1B,CAKC8tB,GAEIA,CACT,ED7DsBc,CAAiC9gB,EAAU1nB,EAAKyoC,WAAYzoC,EAAK4Y,SACzE7L,SAAS46B,UACjB,MAAMe,EAAQ1oC,EAAK2oC,kBAAkBhB,EAAS58B,SAG9C,OAAAyH,EAAAxS,EAAK4oC,gBAALp2B,EAAoBmY,YAAY+d,EAAM/zB,SAChC+zB,EAAA9P,YAAY5M,eAGZ,MAAA8b,EAAe,CAACe,EAAsBd,KAC/BA,EAAAnuB,SAAS7M,SAAS+B,IACrB,MAAAg6B,EAASphB,EAASwB,MAAMJ,GAAMA,EAAE3G,KAAOrT,EAAK/D,QAAQid,MACpD+gB,EAASj6B,EAAK/D,QACdi+B,EAAShpC,EAAK2oC,kBAAkBI,EAAQD,GAG9CD,EAAQI,SAASD,GAGjBlB,EAAakB,EAAQl6B,EAAI,GAC1B,EAEHg5B,EAAaY,EAAOf,GAGde,EAAA9P,YAAYsQ,qBACnB,EAEH/N,OAAQ,CAACpwB,EAASuL,WAEhB,MAAMxH,EAAO9O,EAAK2oC,kBAAkB59B,EAASuL,GAEzC,GAAgB,IAAhBvL,EAAQid,IAEV,OAAAxV,EAAAxS,EAAK4oC,gBAALp2B,EAAoB6iB,QAAQvmB,EAAK6F,aAC5B,CAEL,MAAMkzB,EAAS7nC,EAAKmpC,gBAAgBp+B,EAAQid,KACxC6f,IACFA,EAAOoB,SAASn6B,EAA0B,aAApB9O,EAAKyoC,WAA4B,SAAW,WAGlE35B,EAAKs6B,aAAar8B,SAASupB,IACvBA,EAAAsC,YAAYyQ,kCAGpB,CAEKv6B,EAAA8pB,YAAYsQ,mBAEjBp6B,EAAKmc,iBACAnc,EAAA8pB,YAAY5M,kBExCrB,SAAS1D,GACPtoB,EACAspC,EACAv+B,EACAuL,GAEIvL,EAAQw+B,eAAcx+B,EAAQy+B,gBAAiB,GACnD,MAAM16B,EAAO9O,EAAK2oC,kBAAkB59B,EAASuL,GAI7C,GAAIvL,EAAQ0+B,QAAS,CACb,MAAAjzB,EAAW1H,EAAK6F,QAChB+0B,EAAoB1pC,EAAK4oC,cACZ,WAAfU,IAA4C,MAAAI,GAAAA,EAAAjrB,OAAOjI,IACpC,YAAf8yB,IAA6C,MAAAI,GAAAA,EAAArU,QAAQ7e,IACpD1H,EAAA8pB,YAAY5M,cACnB,CAMO,OAFFld,EAAA8pB,YAAYsQ,mBAEVp6B,CACT,CClBO,MAAM66B,GACX,WAAA32B,CAAoBrL,GAAAhJ,KAAAgJ,QAAAA,CAAyB,CAErC,WAAAiiC,GACC,OAAAjrC,KAAKgJ,QAAQgR,UDzBkC3Y,EC0B/BrB,KAAKgJ,QD1BoC,CAClE4/B,OAAS7f,IACEA,EAAA3a,SAAShC,IAChB,MAAMuL,EACY,IAAhBvL,EAAQid,SAAY,EAAYN,EAASwB,MAAMJ,GAAMA,EAAE3G,KAAOpX,EAAQid,MAC1DM,GAAAtoB,EAAM,SAAU+K,EAASuL,EAAY,GACpD,EAEH6kB,OAAQ,CAACpwB,EAASuL,KACHgS,GAActoB,EAAM,UAAW+K,EAASuL,GAChD2U,gBAAe,ICiBhBqc,GAAmB3oC,KAAKgJ,SD3ByB,IAAC3H,CC4BxD,CAEA,MAAAunC,CAAO7f,GACA/oB,KAAAirC,cAAcrC,OAAO7f,EAC5B,CAEA,MAAAyT,CAAOpwB,EAAsBuL,GAC3B3X,KAAKirC,cAAczO,OAAOpwB,EAASuL,EACrC,ECfc,SAAAokB,GAAMzlB,EAAwB40B,GAC5CA,EAAM98B,SAAQ,EAAGrR,KAAIouC,MAAKC,eACxB,IAAKruC,EAAI,OAGLquC,IAAaruC,EAAAuT,MAAM+6B,UAAY,GAAGF,EAAM,OAE5C,IAAIlE,GAAO,EACX,MAAMqE,EAAS,KACb,GAAIrE,EAAM,OACNsE,G5F5BH,SAAmBxuC,GAExB,OADYm/B,WAAWkL,iBAAiBrqC,EAAI,MAAM8vB,OAAOhwB,QAAQ,KAAM,MACzD,CAChB,C4FyBU0uC,CAAgBxuC,IAAOouC,EAAK,OAO/B70B,EAAK4E,WAoEL,SAAoC6B,GACrC,IAACA,EAAIhgB,GAAI,OACb,GAAIggB,EAAIhgB,GAAGwuB,UAAUigB,SAASC,IAA0B,OACpD1uB,EAAAhgB,GAAGwuB,UAAUpN,IAAIstB,IACrB1uB,EAAIhgB,GAAGuT,MAAMuc,OAAS,GAAG9P,EAAIouB,OAC/B,CAvEUO,CAA2B,CAAE3uC,KAAIouC,QAsBpC,SAA0B/xB,GAK3B,IAACA,EAAIrc,GAAI,OACT,IAACqc,EAAI+xB,IAAK,OACd,GAAI/xB,EAAIrc,GAAGwuB,UAAUigB,SAASG,IAAmB,OAE7CvyB,EAAArc,GAAGwuB,UAAUpN,IAAIwtB,IACrBvyB,EAAIrc,GAAGuT,MAAMuc,OAAS,GAAGzT,EAAI+xB,QACzB/xB,EAAArc,GAAGuT,MAAMw2B,SAAW,SAGxB,MAAM8E,EAAahkB,EACjB,qCAAqCtpB,EAAG,sBAE/BstC,EAAA5b,QAAWtd,IACpBA,EAAEye,kBACF0a,GAAmBzyB,EAAIrc,IAEnBqc,EAAI0yB,qBAAyB1yB,EAAA0yB,oBAAoBp5B,EAAC,EAEpD0G,EAAArc,GAAG+iB,OAAO8rB,EAChB,CA/CUG,CAAiB,CAAEhvC,KAAIouC,MAAKW,oBANJ,WACnB7E,GAAA,EACP,OAAApzB,EAAAyC,EAAKw1B,sBAALj4B,EAAA9J,KAAAuM,EAAA,GAKwC,EAO5C,OAAI80B,EAAU,CAEN,MAAAY,EAAOjvC,EAAGmhB,iBAAmC,oBAC/B,IAAhB8tB,EAAK7tC,SAAcpB,EAAGuT,MAAM+6B,UAAY,IACvCW,EAAA59B,SAASwB,IACRA,EAAA2wB,OAAS,IAAM+K,MAEvB,IAEJ,CAGA,MAAMK,GAAmB,mBA8BlB,SAASE,GAAmB1gB,GAC5BA,GACAA,EAAII,UAAUigB,SAASG,MAExBxgB,EAAAI,UAAUI,OAAOggB,IACrB/hC,MAAM2U,KAAK4M,EAAIlQ,UAAU7M,SAASsE,IAC5BA,EAAE6Y,UAAUigB,SAAS,2BAA2B7f,YAEtDR,EAAI7a,MAAMuc,OAAS,GACnB1B,EAAI7a,MAAM+6B,UAAY,GACtBlgB,EAAI7a,MAAMw2B,SAAW,GACvB,CAGA,MAAM2E,GAA0B,0BCxFhC,SAASQ,GAAWrqB,GAGd,GAFJA,EAAEsqB,YAActqB,EAAEuJ,IAAIO,cAA2B,aAE7C9J,EAAEjE,KAAKzb,KAAM,CACf,MAAMiqC,EAASvkB,EACb,8DAEKukB,EAAAhwC,UAAYylB,EAAEjE,KAAK3b,KAC1BmqC,EAAOv5B,KAAOqf,EAAiBrQ,EAAEjE,KAAKzb,MAAQ0f,EAAEjE,KAAKzb,KAAO,WAAW0f,EAAEjE,KAAKzb,OAC5E0f,EAAAsqB,YAAYpsB,OAAOqsB,EAAM,MAEzBvqB,EAAAsqB,YAAY/vC,UAAYylB,EAAEjE,KAAK3b,IAErC,CAEA,SAASoqC,GAAkBjT,GACzBA,EAAIkT,iBAAmBlT,EAAIhO,IAAIO,cAA2B,mBAC1DyN,EAAIkT,iBAAiBxwC,UAAY,GAE3B,MAAAywC,EAAYnT,EAAIxb,KAAK4uB,WACrBC,EAAarT,EAAIxb,KAAK8uB,YAC5B,GAAIH,EAAW,CACP,MAAAI,EAAS9kB,EAAoB,mCACnC8kB,EAAOvwC,UAAYmwC,EAAUzvC,QAAQ,MAAOyB,EAAG,UACxCouC,EAAAp8B,MAAMq8B,gBAAkBH,GAAc,GACzCrT,EAAAkT,iBAAiBvsB,OAAO4sB,EAAM,MAAA,GACzBvT,EAAIxb,KAAKivB,YAAa,CAC/B,MAAMC,EAAiBjlB,EACrB,0CAA0CtpB,EAAG,6BAE3C66B,EAAAkT,iBAAiBvsB,OAAO+sB,EAC9B,CAEI,GAAA1T,EAAIxb,KAAKmvB,UAAW,CACtB,MAAMC,EAAenlB,EAAoB,kCAAkCtpB,EAAG,iBAC1E66B,EAAAkT,iBAAiBvsB,OAAOitB,EAC9B,CACF,CAEA,SAASC,GAAW7T,GAClB,MAAM8T,EAAQ9T,EAAIhO,IAAIO,cAA2B,aAC3CuhB,EAAA9wC,UAAYg9B,EAAI/sB,QAAQ8gC,mBACxBD,EAAApd,aAAa,wBAAyBhnB,QAAQ,IAAIlK,KAAKw6B,EAAIxb,KAAKtf,OACxE,CAEA,SAAS8uC,GAAchU,GACrB,IAAKA,EAAI93B,KAAKiZ,UAAY6e,EAAIxb,KAAKyvB,UAAW,OAE9C,IAAIC,EAAUlU,EAAIlD,QAAQvK,cAAc,eAQpC,GAPC2hB,IACOA,EAAAzlB,EAAoB,qCAC1BuR,EAAAlD,QAAQnW,OAAOutB,IAGrBA,EAAQxxC,UAAY,GAEhBs9B,EAAIxb,KAAKyvB,UAAW,CAChB,MAAAE,EAAe1lB,EAAoB,0CAC5B0lB,EAAAnxC,UAAYg9B,EAAIxb,KAAKyvB,UAClCC,EAAQvtB,OAAOwtB,EACjB,CAEI,GAAAnU,EAAI93B,KAAKiZ,QAAS,CACpB,MAAMizB,QAAEA,EAASC,GAAAA,GAAOrU,EAAI/sB,QAAQqhC,YACpC,GAAI5kC,OAAO0kC,GAASzxC,OAAQ,CACpB,MAAA4xC,EAAa9lB,EAAoB,2CACvC8lB,EAAWvxC,UAAYoxC,EACvBF,EAAQvtB,OAAO4tB,EACjB,CAEA,GAAI7kC,OAAO2kC,GAAI1xC,OAAQ,CACf,MAAA6xC,EAAQ/lB,EAAoB,sCAClC+lB,EAAMxxC,UAAYqxC,EAClBH,EAAQvtB,OAAO6tB,EACjB,CACF,CACF,CC1EA,MAAqBC,GAgBnB,WAAAv5B,CAAYhT,GAfJkT,EAAAvU,KAAA,QACDuU,EAAAvU,KAAA,OAEYuU,EAAAvU,KAAA,aAAA,GAEZuU,EAAAvU,KAAA,eACAuU,EAAAvU,KAAA,mBAKeuU,EAAAvU,KAAA,gBAAA,GACfuU,EAAAvU,KAAA,mBAIAA,KAAAmrB,IAAMvD,EAAoB,+CAE/B5nB,KAAKqB,KAAuB,iBAATA,EAAoB,CAAEuH,KAAMvH,GAASA,EACnDrB,KAAAmrB,IAAIhvB,UAAY6D,KAAK6tC,UAGtB7tC,KAAKqB,KAAKysC,gBAAgB3iB,IAAI0E,aAAa,sBAAuB,GACxE,CAhBA,eAAWke,GACF,QAAE/tC,KAAKguC,WAChB,CAiBO,QAAAC,CAASC,GAEP,OADHA,EAAApuB,OAAO9f,KAAKmrB,KACTnrB,IACT,CAGQ,OAAA6tC,GACC,MAA0B,iBAAnB7tC,KAAKqB,KAAKuH,KAAoB5I,KAAKqB,KAAKuH,KAAO5I,KAAKqB,KAAKuH,MACzE,CAGO,QAAAulC,CAASnmB,GACThoB,KAAAmrB,IAAI6E,QAAWtd,IAIlB,GAHAA,EAAEye,mBAGEnxB,KAAKouC,UAAT,CAKA,GAAIpuC,KAAKqB,KAAKuD,UAAY5E,KAAK+tC,YAAa,CAC1C,MAAMM,EAAiB,KACrBruC,KAAKsuC,cAAe,EACftuC,KAAAmrB,IAAII,UAAUI,OAAO,mBACrB3rB,KAAAmrB,IAAIhvB,UAAY6D,KAAK6tC,SAAQ,EAGhC,IAAC7tC,KAAKsuC,aAKR,OAJAtuC,KAAKsuC,cAAe,EACftuC,KAAAmrB,IAAII,UAAUpN,IAAI,mBACvBne,KAAKmrB,IAAIhvB,UAAY6D,KAAKqB,KAAKktC,aAAejwC,EAAG,sBACjD0B,KAAKwuC,gBAAkB/xC,OAAO0vB,YAAW,IAAMkiB,KAAkB,MAI/DruC,KAAKwuC,iBAAwB/xC,OAAAk3B,aAAa3zB,KAAKwuC,oBAErD,CAGA,GAAIxuC,KAAKguC,YAGP,OAFAhuC,KAAKyuC,uBACLzuC,KAAK0uC,sBAzBP,EAgCJ,CAGO,UAAAC,CAAW/lC,GACZA,IAAW5I,KAAAqB,KAAKuH,KAAOA,GAC3B5I,KAAKqsB,YAAW,GACXrsB,KAAAmrB,IAAIhvB,UAAY6D,KAAK6tC,SAC5B,CAGO,UAAAxhB,CAAWhe,EAAgBugC,GAC5B5uC,KAAKouC,YAAc//B,IACvBrO,KAAKouC,UAAY//B,EACbA,GACGrO,KAAAmrB,IAAII,UAAUpN,IAAI,mBACvBne,KAAKmrB,IAAIhvB,UAAYyyC,GAAe,GAAGtwC,EAAG,kBAErC0B,KAAAmrB,IAAII,UAAUI,OAAO,mBACrB3rB,KAAAmrB,IAAIhvB,UAAY6D,KAAK6tC,WAE9B,CAGO,QAAAvgB,CAAS1kB,GACT5I,KAAA6uC,OAAOjmC,EAAM,gBACpB,CAGO,OAAAkmC,CAAQlmC,GACR5I,KAAA6uC,OAAOjmC,EAAM,eACpB,CAGO,UAAAmmC,CAAWnmC,GACX5I,KAAA6uC,OAAOjmC,EAAM,kBACpB,CAGO,MAAAimC,CAAOjmC,EAAc+F,EAAoBqgC,EAAqB5jB,GACnEprB,KAAKqsB,YAAW,GACZ1d,GAAW3O,KAAKmrB,IAAII,UAAUpN,IAAIxP,GACtC3O,KAAKmrB,IAAIhvB,UAAYyM,EAGrB5I,KAAKivC,gBAAe,KACbjvC,KAAAmrB,IAAIhvB,UAAY6D,KAAK6tC,UACtBl/B,GAAW3O,KAAKmrB,IAAII,UAAUI,OAAOhd,GACrCyc,SACH4jB,GAAc,KACnB,CAGQ,cAAAC,CAAejnB,EAAkBgnB,GACvChvC,KAAKyuC,kBACLzuC,KAAK0uC,mBAEL1uC,KAAKkvC,gBAAkBlnB,EAClBhoB,KAAAguC,YAAcvxC,OAAO0vB,YAAW,SAEnCnsB,KAAK0uC,kBAAiB,GACrBM,EACL,CAGQ,eAAAP,GACFzuC,KAAKkvC,iBAAiBlvC,KAAKkvC,iBACjC,CAGQ,gBAAAR,GACF1uC,KAAKguC,aAAoBvxC,OAAAk3B,aAAa3zB,KAAKguC,aAC/ChuC,KAAKguC,iBAAc,EACnBhuC,KAAKkvC,qBAAkB,CACzB,ECnJF,SAASC,GAAWvtB,GACbA,EAAEvgB,KAAKgZ,OAGZuH,EAAEwtB,UAAY,IAAIxB,IAAU,IAAM,GAAGtvC,EAAG,cAAcsjB,EAAEjE,KAAK8rB,SAAW,OAAMwE,SAASrsB,EAAEggB,UACvFhgB,EAAAwtB,UAAUjB,UAAS,KACnBvsB,EAAExV,QAAQijC,aAAah1B,KAAK,KAAI,IAI9BuH,EAAEvgB,KAAKmC,WACToe,EAAE0tB,YAAc,IAAI1B,IAAU,IAAM,GAAGtvC,EAAG,gBAAgBsjB,EAAEjE,KAAK4xB,WAAa,OAAMtB,SAClFrsB,EAAEggB,UAEFhgB,EAAA0tB,YAAYnB,UAAS,KACrBvsB,EAAExV,QAAQijC,aAAah1B,KAAK,OAAM,KAGxC,CAGA,SAASm1B,GAAY5tB,GACf,IAACA,EAAEjE,KAAKktB,eAAgB,OACtB,MAAA4E,EAAW,IAAI7B,GAAU,CAC7BhlC,KAAMtK,EAAG,WAEFmxC,EAAAxB,SAASrsB,EAAEggB,UACpB6N,EAAStB,UAAS,KAChBvsB,EAAEvgB,KAAKsW,aAAaiK,EAAEjE,KAAMiE,EAAEuJ,IAAG,GAErC,CAGA,SAASukB,GAAe9tB,GAChB,MAAA+tB,EAAc,IAAI/B,GAAU,CAChChlC,KAAM,IAAOgZ,EAAEjE,KAAKitB,aAAetsC,EAAG,UAAYA,EAAG,YACrDwvC,WAAW,IAED6B,EAAA1B,SAASrsB,EAAEggB,UACvB+N,EAAYxB,UAAS,KACnBvsB,EAAExV,QAAQijC,aAAaO,UAAU,YAAaD,EAAW,GAE7D,CAGA,SAASE,GAAgBjuB,GACjB,MAAAkuB,EAAa,IAAIlC,GAAU,CAC/BhlC,KAAM,IAAOgZ,EAAEjE,KAAKoyB,WAAazxC,EAAG,WAAaA,EAAG,YACpDwvC,WAAW,IAEFgC,EAAA7B,SAASrsB,EAAEggB,UACtBkO,EAAW3B,UAAS,KAClBvsB,EAAExV,QAAQijC,aAAaO,UAAU,UAAWE,EAAU,GAE1D,CAGA,SAASE,GAAUpuB,GACX,MAAAquB,EAAY,IAAIrC,GAAU,CAC9BhlC,KAAM,IAAOgZ,EAAEjE,KAAKmvB,UAAYxuC,EAAG,SAAWA,EAAG,OACjDwvC,WAAW,IAEHmC,EAAAhC,SAASrsB,EAAEggB,UACrBqO,EAAU9B,UAAS,KACjBvsB,EAAExV,QAAQijC,aAAaO,UAAU,SAAUK,EAAS,GAExD,CAGA,SAASC,GAAWtuB,GACZ,MAAAuuB,EAAU,IAAIvC,GAAU,CAC5BhlC,KAAMtK,EAAG,QACTwvC,WAAW,IAELqC,EAAAlC,SAASrsB,EAAEggB,UACnBuO,EAAQhC,UAAS,KACfvsB,EAAEvgB,KAAK0W,YAAY6J,EAAEjE,KAAMiE,EAAEuJ,IAAG,GAEpC,CAGA,SAASilB,GAAUxuB,GACX,MAAAyuB,EAAS,IAAIzC,GAAU,CAC3BhlC,KAAMtK,EAAG,UACTsG,SAAS,EACT2pC,YAAajwC,EAAG,iBAChBwvC,WAAW,IAENuC,EAAApC,SAASrsB,EAAEggB,UAClByO,EAAOlC,UAAS,KACdvsB,EAAExV,QAAQijC,aAAaiB,YAAYD,EAAM,GAE7C,CC1GA,MAAME,GAAU,CAAAC,OCHhB,SAAqC5uB,GACnC,MAAM6uB,EAAU7uB,EAAEuJ,IAAIO,cAA2B,eAC3CglB,EAAa9oB,EAAsC,WAEnD+oB,EAAmB/uB,EAAEvgB,KAAKsvC,iBAG5B,GAFOD,EAAA/8B,IAAMg9B,EAAmBA,EAAiB/uB,EAAEjE,MAAQiE,EAAExV,QAAQwkC,iBAErEhvB,EAAEjE,KAAKzb,KAAM,CACf,MAAM2uC,EAAWjpB,EACf,8DAEFipB,EAASj+B,KAAOqf,EAAiBrQ,EAAEjE,KAAKzb,MAAQ0f,EAAEjE,KAAKzb,KAAO,WAAW0f,EAAEjE,KAAKzb,OAChF2uC,EAAS/wB,OAAO4wB,GAChBD,EAAQ3wB,OAAO+wB,EAAQ,MAEvBJ,EAAQ3wB,OAAO4wB,EAEnB,EDbEI,OHHF,SAAqClvB,GACnCzX,OAAOmlB,QAAQ,CACb2c,cACAG,qBACAY,cACAG,mBACC/+B,SAAQ,EAAE/R,EAAMooC,MACjBA,EAAO7iB,EAAC,GAEZ,EGLEmvB,QEHF,SAAsCnvB,GAChC,IAACA,EAAEjE,KAAKitB,aAGV,OAFAhpB,EAAEigB,SAAShmC,UAAY+lB,EAAExV,QAAQmmB,wBACjC3Q,EAAEigB,SAAStW,UAAUI,OAAO,WAAY,iBAK1C/J,EAAEigB,SAAStW,UAAUpN,IAAI,WAAY,sBAC/B,MAAA6yB,EAAkBppB,EAAoB,mEAEftpB,EAAG,4DACCA,EAAG,gCAElCsjB,EAAAqvB,MAAMC,sBAAsB,YAAaF,GAErC,MAAAG,EAAiBH,EAAgBtlB,cAA2B,iBACnDylB,EAAA/jB,iBAAiB,SAAU1a,IACxCA,EAAEye,kBAEEvP,EAAEigB,SAAStW,UAAUigB,SAAS,aAChC5pB,EAAEigB,SAAShmC,UAAY+lB,EAAExV,QAAQmmB,mBAC/B3Q,EAAAigB,SAAStW,UAAUI,OAAO,YACzBylB,GAAexvB,EAAEigB,UACLsP,EAAAh1C,UAAYmC,EAAG,cAE9BsjB,EAAEigB,SAAShmC,UAAY,GACrB+lB,EAAAigB,SAAStW,UAAUpN,IAAI,YACVgzB,EAAAh1C,UAAYmC,EAAG,UAChC,GAEJ,EF3BE+yC,QGNF,SAAsCzvB,GAChCA,EAAEvgB,KAAK2Y,UAA2B,IAAf4H,EAAEjE,KAAK0L,KACzBzH,EAAEvgB,KAAKiwC,UAEZ1vB,EAAE2vB,SAAW3pB,EACX,4GAEAhG,EAAA2vB,SAAS7lB,cAA2B,aAAcvvB,UAAY,GAAGylB,EAAEvgB,KAAKiwC,QAAQtvC,OAChF4f,EAAA2vB,SAASvhB,QAAU,KACjBpO,EAAAxV,QAAQijC,aAAamC,kBAAiB,EAG1C5vB,EAAEyqB,iBAAiB6E,sBAAsB,WAAYtvB,EAAE2vB,UACzD,EHNEE,QILF,SAAsC7vB,GAChC,IAACA,EAAEvgB,KAAK2Y,SAAU,OAClB,IAAC4H,EAAEvgB,KAAKiwC,QAAS,OAEnB1vB,EAAA8vB,SAAW9pB,EAAoB,iEAELtpB,EAAG,qGAK/B,MAAMqzC,EAAQ/vB,EAAE8vB,SAAShmB,cAA2B,aACpDimB,EAAMx1C,UAAY,IAAIylB,EAAEvgB,KAAKiwC,QAAQtvC,OACrC2vC,EAAM3hB,QAAU,KACZpO,EAAAxV,QAAQijC,aAAamC,kBAAiB,EAI1C,IAAII,EAAe3/B,GAAO2P,EAAEvgB,KAAKiwC,QAAQ9gC,SACrCoR,EAAEvgB,KAAKiwC,QAAQ1G,iBAA6B,IAAItsC,EAAG,iBACvDsjB,EAAE8vB,SAAShmB,cAA2B,gBAAiB7vB,UAAY+1C,EAGjEhwB,EAAAqvB,MAAMva,QAAQ9U,EAAE8vB,SACpB,EJlBEG,QKPF,SAAsCjwB,GAChC,IAACA,EAAEjE,KAAKoyB,WAAY,OAExB,MAAM+B,EAAYlqB,EAAoB,4BAA4BtpB,EAAG,uBACnEsjB,EAAAqvB,MAAMva,QAAQob,EAClB,ELGEC,QDRF,SAAsCnwB,GACpCzX,OAAOmlB,QAAQ,CACb6f,cACAK,eAEAE,kBACAG,mBACAG,aACAE,cACAE,eACChiC,SAAQ,EAAE/R,EAAMooC,MACjBA,EAAO7iB,EAAC,GAEZ,GOXA,MAAqBowB,GAyBZ,WAAA39B,CAAYjI,GAxBZmI,EAAAvU,KAAA,WASAuU,EAAAvU,KAAA,OACAuU,EAAAvU,KAAA,SACAuU,EAAAvU,KAAA,WACAuU,EAAAvU,KAAA,eACAuU,EAAAvU,KAAA,oBACAuU,EAAAvU,KAAA,SACAuU,EAAAvU,KAAA,YACAuU,EAAAvU,KAAA,iBACAuU,EAAAvU,KAAA,YACAuU,EAAAvU,KAAA,aACAuU,EAAAvU,KAAA,eAEAuU,EAAAvU,KAAA,YACAuU,EAAAvU,KAAA,YAGLA,KAAKoM,QAAUA,CACjB,CAxBA,QAAWuR,GACF,OAAA3d,KAAKoM,QAAQgL,SACtB,CACA,QAAW/V,GACF,OAAArB,KAAKoM,QAAQi0B,SACtB,CA8BO,MAAAoE,GN5BT,IAAoC7iB,EMgDhC,OAlBK5hB,KAAAmrB,IAAMvD,ECjDA,ygBDmDX5nB,KAAKiyC,MAAQjyC,KAAKmrB,IAAIO,cAAc,aACpC1rB,KAAKi2B,QAAUj2B,KAAKmrB,IAAIO,cAAc,eACtC1rB,KAAKixC,MAAQjxC,KAAKmrB,IAAIO,cAAc,aACpC1rB,KAAK6hC,SAAW7hC,KAAKixC,MAAMvlB,cAAc,gBACzC1rB,KAAK4hC,SAAW5hC,KAAKmrB,IAAIO,cAAc,gBAEvC1rB,KAAKmrB,IAAI0E,aAAa,KAAM,eAAe7vB,KAAK2d,KAAK6F,MNtCrB5B,EMyCpB5hB,KNxCPmK,OAAAmlB,QAAQihB,IAASniC,SAAQ,EAAE/R,EAAMooC,MACtCA,EAAO7iB,EAAC,IM0CJ5hB,KAAKkyC,eACFlyC,KAAAiyC,MAAMnyB,OAAO9f,KAAKkyC,eAGlBlyC,KAAKmrB,GACd,CAGO,gBAAAof,GACC,MAAAj0B,EAAOtW,KAAKqB,KAAK2Z,YACvB,IAAK1E,IAASA,EAAK9F,UAAY8F,EAAK2E,SAAU,OAE9C,MAAMk3B,EAAc77B,EAAK9F,QACnB4hC,EAAe97B,EAAK2E,SAEdo3B,GACV,CACEvG,oBAAqB,KAEb,MAAA7wB,EAAWjb,KAAKoM,QAAQkmC,cACN,IAApBr3B,EAAS9c,QACXo0C,GAA+Bt3B,EAAS,GAAGgf,YAAY4H,SAAQ,EAEnE3mB,WAAY5E,EAAK4E,YAEnB,CAEE,CAAEne,GAAIiD,KAAK6hC,SAAUsJ,IAAKgH,EAAa/G,UAAU,GACjD,CAAEruC,GAAIiD,KAAK0xC,SAAUvG,IAAKgH,EAAa/G,UAAU,GAEjD,CAAEruC,GAAIiD,KAAKkyC,cAAe/G,IAAKiH,EAAchH,UAAU,IAG7D,CAGO,4BAAAV,GACA1qC,KAAKkyC,eACEK,GAAmBvyC,KAAKkyC,cACtC,CAGA,YAAA7kB,GACE+jB,GAAkBpxC,KAAKoM,QAAQ6tB,YAAY9O,IAC7C,CAGA,mBAAAqnB,GACEpB,GAAkBpxC,KAAKoM,QAAQ6tB,YAAYgX,MAC7C,CAGA,aAAAwB,GAEOzyC,KAAAmrB,IAAII,UAAUI,OAAO,kBAC1BlvB,OAAO0vB,YAAW,KAEXnsB,KAAAmrB,IAAII,UAAUpN,IAAI,iBAAgB,GACtC,IACL,CAGO,eAAAu0B,GAML,OALK1yC,KAAKkyC,gBAEHlyC,KAAAkyC,cAAgBtqB,EAAoB,4CACpC5nB,KAAAiyC,MAAMnyB,OAAO9f,KAAKkyC,gBAElBlyC,KAAKkyC,aACd,CAGO,SAAAhY,CAAUpjB,GACXA,EAAK9W,KAAKmrB,IAAII,UAAUpN,IAAI,cACtBne,KAAAmrB,IAAII,UAAUI,OAAO,aACjC,CAGO,WAAAgnB,CAAY77B,GACbA,EAAK9W,KAAKmrB,IAAII,UAAUpN,IAAI,gBACtBne,KAAAmrB,IAAII,UAAUI,OAAO,eACjC,CAGO,UAAAinB,CAAW5xC,GAChBhB,KAAK2yC,aAAY,GACZ3yC,KAAAmrB,IAAI6E,QAAWkB,IAClBA,EAAIC,kBACJ10B,OAAO2K,KAAKpG,EAAG,CAEnB,CAGO,aAAAm5B,CAActT,GACnB7mB,KAAK2yC,aAAY,GACZ3yC,KAAAmrB,IAAI6E,QAAWkB,IAClBA,EAAIC,sBAGR,EE9JF,MAAqB0hB,GAaZ,WAAAx+B,CAAYjI,GAZXmI,EAAAvU,KAAA,WAaNA,KAAKoM,QAAUA,CACjB,CAZA,QAAYuR,GACH,OAAA3d,KAAKoM,QAAQgL,SACtB,CACA,QAAY/V,GACH,OAAArB,KAAKoM,QAAQi0B,SACtB,CACQ,MAAAppB,GACN,OAAOjX,KAAKoM,QAAQi0B,UAAUppB,QAChC,CAOO,IAAAoD,CAAK8L,GACJ,MAAA2sB,EACO,OAAX3sB,EAAkBnmB,KAAKoM,QAAQ6tB,YAAYmV,UAAYpvC,KAAKoM,QAAQ6tB,YAAYqV,YAE7EtvC,KAAAiX,SACFuoB,MAAMtZ,WAAW,UAAWlmB,KAAK2d,KAAK6F,GAAI2C,EAAQrH,EAC9C,CAAA,EAAA9e,KAAKiX,SAASsQ,kBAElB7F,MAAMhD,YACA1e,KAAA2d,KAAK8rB,QAAU/qB,EAAIf,KAAKqhB,GACxBh/B,KAAA2d,KAAK4xB,UAAY7wB,EAAIf,KAAKshB,KAC/B,OAAAprB,EAAA7T,KAAKoM,QAAQ6tB,YAAYmV,YAAWv7B,EAAA86B,aACpC,OAAAnuB,EAAAxgB,KAAKoM,QAAQ6tB,YAAYqV,cAAa9uB,EAAAmuB,YAAA,IAEvC5sB,OAAOvhB,IACK,MAAAsyC,GAAAA,EAAAxlB,SAAShvB,EAAG,aACvBuB,QAAQD,MAAMY,EAAG,GAEvB,CAGO,SAAAovC,CAAUr3B,EAA0Cw6B,GACzD,GAAIA,EAAQ3E,UAAW,OAEvB2E,EAAQ1mB,YAAW,EAAM,GAAG/tB,EAAG,iBAGzB,MAAA00C,EAASl0B,KAAK9e,KAAK2d,MACZ,cAATpF,EACKy6B,EAAApI,cAAgBoI,EAAOpI,aACZ,YAATryB,EACFy6B,EAAAjD,YAAciD,EAAOjD,WACV,WAATx3B,IACFy6B,EAAAlG,WAAakG,EAAOlG,WAG7B9sC,KAAKiX,SACF8R,SAAStF,cAAczjB,KAAK2d,KAAK6F,GAAI1E,EAAA,CAAA,EACjCk0B,IAEJtxB,MAAMhD,IACLq0B,EAAQ1mB,YAAW,GAGdrsB,KAAAoM,QAAQ6mC,QAAQv0B,EAAIf,KAAI,IAE9BoE,OAAOvhB,IACNX,QAAQD,MAAMY,GACNuyC,EAAAzlB,SAAShvB,EAAG,YAAW,GAErC,CAGO,WAAAgyC,CAAYyC,GACbA,EAAQ3E,YAEZ2E,EAAQ1mB,YAAW,EAAM,GAAG/tB,EAAG,kBAC1B0B,KAAAiX,SACF8R,SAASrF,cAAc1jB,KAAK2d,KAAK6F,IACjC9B,MAAK,KACJqxB,EAAQ1mB,YAAW,GACfrsB,KAAKqB,KAAK6xC,eAAe7xC,KAAK6xC,SAASlzC,KAAKoM,QAAO,IAExD2V,OAAOrP,IACN7S,QAAQD,MAAM8S,GACNqgC,EAAAzlB,SAAShvB,EAAG,cAAa,IAEvC,CAGO,gBAAAkzC,GACC,MAAA2B,EAAW12C,OAAOC,SAASqS,KAC3BqkC,EAAa,gBAAgBpzC,KAAK2d,KAAK0L,MAE7C5sB,OAAOC,SAASqS,KAAOqkC,EACnBA,IAAeD,GAAU12C,OAAO42C,cAAc,IAAIC,MAAM,cAC9D,EC9DF,MAAqBC,GAcnB,WAAAl/B,CAAYsJ,EAAmBtc,GAb/BkT,EAAAvU,KAAA,OAEQuU,EAAAvU,KAAA,kBACAuU,EAAAvU,KAAA,kBAEAuU,EAAAvU,KAAA,QACAuU,EAAAvU,KAAA,QAEAuU,EAAAvU,KAAA,UACAuU,EAAAvU,KAAA,WAA0B,IAE1BuU,EAAAvU,KAAA,YAGNA,KAAKqB,KAAOA,EACPrB,KAAA2d,KAAOmB,EAAK,CAAA,EAAAnB,GACjB3d,KAAK2d,KAAKtf,KAAO2B,KAAK2d,KAAKtf,KAAKxB,QAAQ,KAAM,KAE9CmD,KAAKkpC,OAAS,KACdlpC,KAAKwzC,SAAW,EAEXxzC,KAAAyzC,eAAiB,IAAIZ,GAAe7yC,MACpCA,KAAA0zC,eAAiB,IAAIC,GAAU3zC,KACtC,CAGO,MAAAykC,GACC,MAAAmP,EAAQ5zC,KAAK0zC,eAAejP,SAE9BzkC,KAAKmrB,KAAUnrB,KAAAmrB,IAAIG,YAAYsoB,GACnC5zC,KAAKmrB,IAAMyoB,EAMP5zC,KAAKqB,KAAKwyC,eAAe7zC,KAAKqB,KAAKwyC,eACzC,CAGO,UAAAxE,GACL,OAAOrvC,KAAKyzC,cACd,CAGO,SAAAxZ,GACL,OAAOj6B,KAAK0zC,cACd,CAGO,OAAAt8B,GACL,OAAOpX,KAAK2d,IACd,CAGO,OAAAs1B,CAAQt1B,GACb3d,KAAK2d,KAAOA,EAEZ3d,KAAKykC,SACAzkC,KAAAi6B,YAAYuY,qBACnB,CAGO,SAAAsB,GACL,OAAO9zC,KAAKkpC,MACd,CAGO,WAAAoJ,GACL,OAAOtyC,KAAKib,QACd,CAGO,WAAA84B,GACL,OAAO/zC,KAAKwzC,QACd,CAGO,SAAAQ,GACE,OAAkB,IAAlBh0C,KAAK2d,KAAK0L,GACnB,CAGO,KAAA2Q,GACL,OAAOh6B,KAAK2d,KAAK6F,EACnB,CAGO,QAAA8mB,CAAShB,EAAwBqB,EAAmC,UACzErB,EAAUJ,OAASlpC,KACTspC,EAAAkK,SAAWxzC,KAAKwzC,SAAW,EAChCxzC,KAAAib,SAAS3N,KAAKg8B,GAEb,MAAA4I,EAAgBlyC,KAAKi0C,oBACrBC,EAAgB5K,EAAUtzB,QACb,WAAf20B,EAAuCuH,EAAApyB,OAAOo0B,GAC1B,YAAfvJ,GAAwCuH,EAAAxb,QAAQwd,GAE/C5K,EAAArP,YAAY5M,eACZic,EAAArP,YAAYsQ,kBACxB,CAGO,iBAAA0J,GAEL,OAAIj0C,KAAKwzC,UAAYxzC,KAAKqB,KAAK4Y,QACtBja,KAAKkpC,OAAQ+K,oBAEfj0C,KAAKi6B,YAAYyY,iBAC1B,CAGO,UAAAjI,GACL,MAAM0J,EAAgC,GACtC,IAAIjL,EAASlpC,KAAKkpC,OAClB,KAAOA,GACLiL,EAAe7mC,KAAK47B,GACpBA,EAASA,EAAO4K,YAEX,OAAAK,CACT,CAQO,KAAAn+B,GACL,IAAKhW,KAAKmrB,IAAW,MAAA,IAAIrW,MAAM,oDAC/B,OAAO9U,KAAKmrB,GACd,CAOA,KAAAd,GACE,IAAKrqB,KAAKmrB,IAAW,MAAA,IAAIrW,MAAM,oDAG/B9U,KAAKyqC,aAAar8B,SAASupB,IACvBA,EAAAsC,YAAYyQ,kCAIhB1qC,KAAKssB,iBAGAtsB,KAAAi6B,YAAYwY,eACnB,CAEA,cAAAnmB,GACOtsB,KAAAmrB,KACHgZ,GAAkBnkC,KAAKmrB,KAAK,EAAOnrB,KAAKqB,KAAKq8B,kBAAoB19B,KAAKqB,KAAKq8B,mBAC/E,CAKA,MAAA/R,SACE,OAAA9X,EAAA7T,KAAKmrB,MAAKtX,EAAA8X,QACZ,CAGO,cAAAilB,GACL,MzG9FK,IADsBvvC,EyG+FC,CAC1BuZ,OAAQ5a,KAAKqB,KAAKsZ,SAASC,OAC3BtD,OAAQtX,KAAKqB,KAAKsZ,SAASrD,OAC3B88B,UAAWp0C,KAAK2d,KAAK02B,kBzGjGVz5B,OAAO/d,QAAQ,MAAO,OAAOwE,EAAK+yC,aAAa/yC,EAAKiW,OAAOza,QAAQ,MAAO,MADpF,IAAwBwE,CyGoG7B,CAGO,gBAAAkxB,GACE,OAAAtgB,GAAOjS,KAAK2d,KAAKnN,QAC1B,CAGO,gBAAA08B,WACL,MAAM7uC,EAAO,IAAIM,KAAKqB,KAAK2d,KAAKtf,MACzB,OAAA,OAAAmiB,UAAKnf,MAAK27B,+BAAgB3+B,KAAS4+B,EAAc5+B,EAAMC,EAChE,CAGO,SAAAmvC,GACL,MAAM6G,EChOV,SAAgBn0C,GACR,MAAAo0C,EAAO93C,QAAkB,GACzB+3C,EAAMt0C,WAAa,GAEnBgN,EAAIrE,OAAO1I,GAAaq0C,EAAIr0C,WAC5B+T,EAAO,CACXs5B,GAAI,GACJiH,UAAW,GACXC,OAAQ,GACRnH,QAAS,GACToH,OAAQ,GACRv4B,SAAU,GACV9S,QAAS,IAILsrC,EAAc,CAClBC,QAAS3nC,EAAEohB,SAAS,YAAcphB,EAAEohB,SAAS,WAC7CwmB,OAAQ5nC,EAAEohB,SAAS,UACnBymB,OAAQ7nC,EAAEohB,SAAS,eACnB0mB,MAAO9nC,EAAEohB,SAAS,WAId2mB,EAAe,CACnBC,OAAQhoC,EAAEohB,SAAS,UACnB6mB,OAAQjoC,EAAEohB,SAAS,WAAaphB,EAAEohB,SAAS,SAC3C8mB,GAAIloC,EAAEohB,SAAS,SAAWphB,EAAEohB,SAAS,WACrC+mB,KAAMnoC,EAAEohB,SAAS,SAAWphB,EAAEohB,SAAS,OACvCgnB,QAASpoC,EAAEohB,SAAS,YAAcphB,EAAEohB,SAAS,SAC7C,gBAAiBphB,EAAEohB,SAAS,SAC5BinB,SAAUroC,EAAEohB,SAAS,YACrBknB,MAAOtoC,EAAEohB,SAAS,UAAYphB,EAAEohB,SAAS,OACzCmnB,QAASvoC,EAAEohB,SAAS,WACpBonB,OAAQxoC,EAAEohB,SAAS,aACnBqnB,OAAQzoC,EAAEohB,SAAS,WAAaphB,EAAEohB,SAAS,SAC3C,IAAKphB,EAAEohB,SAAS,UAAYphB,EAAEohB,SAAS,SACvCsnB,GAAI1oC,EAAEohB,SAAS,OAASphB,EAAEohB,SAAS,aACnCunB,UAAW3oC,EAAEohB,SAAS,aACtBwnB,GAAI5oC,EAAEohB,SAAS,OACfynB,MAAO7oC,EAAEohB,SAAS,UAAYphB,EAAEohB,SAAS,eACzC0nB,QAAS9oC,EAAEohB,SAAS,WACpB2nB,MAAO/oC,EAAEohB,SAAS,WAAaphB,EAAEohB,SAAS,SAC1C4nB,UAAWhpC,EAAEohB,SAAS,aACtB,eAAgBphB,EAAEohB,SAAS,gBAC3B6nB,SAAUjpC,EAAEohB,SAAS,YACrB8nB,KAAMlpC,EAAEohB,SAAS,eACjB+nB,MAAOnpC,EAAEohB,SAAS,SAClBgoB,KAAMppC,EAAEohB,SAAS,QACjBioB,OAAQrpC,EAAEohB,SAAS,kBACnBkoB,OAAQtpC,EAAEohB,SAAS,aACnBmoB,OAAQvpC,EAAEohB,SAAS,aACnBooB,MAAOxpC,EAAEohB,SAAS,SAClBqoB,OAAQzpC,EAAEohB,SAAS,oBACnBsoB,OAAQ1pC,EAAEohB,SAAS,cACnBuoB,MAAO3pC,EAAEohB,SAAS,aAIdwoB,EAAU,CACdC,QAAS7pC,EAAEohB,SAAS,WACpB0oB,MAAO9pC,EAAEohB,SAAS,UAAYphB,EAAEohB,SAAS,OACzC2oB,MAAS/pC,EAAEohB,SAAS,aACpB4oB,QAAShqC,EAAEohB,SAAS,YAAcphB,EAAEohB,SAAS,OAC7C6oB,OAAQjqC,EAAEohB,SAAS,UACnB8oB,QAASlqC,EAAEohB,SAAS,WACpB+oB,OAAQnqC,EAAEohB,SAAS,UACnB,gBAAiBphB,EAAEohB,SAAS,aAAephB,EAAEohB,SAAS,iBACtDgpB,WAAYpqC,EAAEohB,SAAS,eAAiBphB,EAAEohB,SAAS,OACnDipB,MAAOrqC,EAAEohB,SAAS,SAClBkpB,QAAStqC,EAAEohB,SAAS,WACpBmpB,IAAKvqC,EAAEohB,SAAS,iBAChB,YAAaphB,EAAEohB,SAAS,QACxBopB,MAAOxqC,EAAEohB,SAAS,UAIdqpB,EAAc,CAClBC,OAAQ1qC,EAAEohB,SAAS,SAAWphB,EAAEohB,SAAS,QAAUphB,EAAEohB,SAAS,OAC9DupB,OAAQ3qC,EAAEohB,SAAS,WAAaphB,EAAEohB,SAAS,QAAUphB,EAAEohB,SAAS,YAI9DqpB,EAAYC,OACdD,EAAYC,QAAW1qC,EAAEohB,SAAS,QACzB2mB,EAAaE,QAAUjoC,EAAEohB,SAAS,QAE3C2mB,EAAaE,QAAS,EACtBF,EAAaI,MAAO,GACXd,EAAIuD,iBAAmBvD,EAAIwD,SACpC9C,EAAaE,QAAS,EACtBF,EAAa,MAAS,GAIxB/gC,EAAKygC,OAAS,KAGdzgC,EAAKkI,eACG,MACA47B,GADMxD,EAAYyD,iBAAmBzD,EAAIp4B,UACjCxb,MAAM,KAEb,OADHo3C,EAAI,KAAIA,EAAI,GAAKA,EAAI,GAAGnwC,eACrBmwC,EAAIppC,KAAK,SAIlB,MAAMG,EAAO,CACX2lC,OAAQE,EACRrH,QAAS0H,EACTzH,GAAIsJ,EACJnC,OAAQgD,GAEHxtC,OAAAmlB,QAAQvgB,GAAMX,SAAQ,EAAEmK,EAAMjc,MAC5B6N,OAAAmlB,QAAQhzB,GAAO8R,SAAQ,EAAE/R,EAAMoN,OACrB,IAAXA,IAAsByK,EAAAqE,GAAQlc,EAAA,GACnC,IAIH,MAAMo4C,EAAY,CAChBsC,QAAS,KACP,MAAM30B,EAAIlV,EAAErQ,QAAQ,6BAA8B,MAa3C,MAZQ,CACb,IAAO,KACP,IAAO,MACP,IAAO,IACP,IAAO,IACP,MAAO,QACP,IAAO,KACP,IAAO,KACP,MAAO,OACP,OAAQ,KACR,OAAQ,MAEIulB,IAAMA,CAAA,EAEtB80B,QAAS,IAAMhqC,EAAErQ,QAAQ,0BAA2B,MACpD46C,IAAK,IAAMvqC,EAAErQ,QAAQ,yBAA0B,MAAMA,QAAQ,KAAM,KACnEw6C,OAAQ,IAAMnqC,EAAErQ,QAAQ,yBAA0B,MAClD,gBAAiB,IAAMqQ,EAAErQ,QAAQ,sCAAuC,MACxEo6C,MAAS,IAAM/pC,EAAErQ,QAAQ,0BAA2B,MAAMA,QAAQ,KAAM,KACxE66C,MAAO,IAAMxqC,EAAErQ,QAAQ,yBAA0B,OAGnDqX,EAAKugC,UAAY,GACbA,EAAUvgC,EAAKs5B,MACjBt5B,EAAKugC,UAAYA,EAAUvgC,EAAKs5B,MAC5Bt5B,EAAKugC,YAAcvnC,IACrBgH,EAAKugC,UAAY,KAKrB,MAAMnrC,EAAU,CACd4rC,OAAQ,IAAMhoC,EAAErQ,QAAQ,0BAA2B,MACnDs4C,OAAQ,IAAMjoC,EAAErQ,QAAQ,yBAA0B,MAAMA,QAAQ,wBAAyB,MACzFu4C,GAAI,IAAMloC,EAAErQ,QAAQ,sBAAuB,MAAMA,QAAQ,oBAAqB,MAC9Ew4C,KAAM,IAAMnoC,EAAErQ,QAAQ,yCAA0C,MAChEy4C,QAAS,IAAMpoC,EAAErQ,QAAQ,0BAA2B,MAAMA,QAAQ,wBAAyB,MAC3F,gBAAiB,IAAMqQ,EAAErQ,QAAQ,wBAAyB,MAC1D04C,SAAU,IAAMroC,EAAErQ,QAAQ,2BAA4B,MACtD24C,MAAO,IAAMtoC,EAAErQ,QAAQ,wBAAyB,MAAMA,QAAQ,sBAAuB,MACrF44C,QAAS,IAAMvoC,EAAErQ,QAAQ,0BAA2B,MACpD64C,OAAQ,IAAMxoC,EAAErQ,QAAQ,4BAA6B,MACrD84C,OAAQ,IAAMzoC,EAAErQ,QAAQ,0BAA2B,MACnDm5C,QAAS,IAAM9oC,EAAErQ,QAAQ,0BAA2B,MACpDg5C,UAAW,IAAM3oC,EAAErQ,QAAQ,4BAA6B,MACxDi5C,GAAI,IAAM5oC,EAAErQ,QAAQ,qBAAsB,MAC1Ck5C,MAAO,IAAM7oC,EAAErQ,QAAQ,iCAAkC,MACzD+4C,GAAI,IAAM1oC,EAAErQ,QAAQ,6BAA8B,MAClDo5C,MAAO,IAAM/oC,EAAErQ,QAAQ,qBAAsB,MAAMA,QAAQ,qCAAsC,MACjG,eAAgB,IAAMqQ,EAAErQ,QAAQ,+BAAgC,MAChEs5C,SAAU,IAAMjpC,EAAErQ,QAAQ,0BAA2B,MACrDu5C,KAAM,IAAMlpC,EAAErQ,QAAQ,8BAA+B,MACrDw5C,MAAO,IAAMnpC,EAAErQ,QAAQ,wBAAyB,MAChDy5C,KAAM,IAAMppC,EAAErQ,QAAQ,uBAAwB,MAC9C05C,OAAQ,IAAMrpC,EAAErQ,QAAQ,iCAAkC,MAC1D25C,OAAQ,IAAMtpC,EAAErQ,QAAQ,6BAA8B,MACtD45C,OAAQ,IAAMvpC,EAAErQ,QAAQ,6BAA8B,MACtD65C,MAAO,IAAMxpC,EAAErQ,QAAQ,wBAAyB,MAChD85C,OAAQ,IAAMzpC,EAAErQ,QAAQ,mCAAoC,MAC5D+5C,OAAQ,IAAM1pC,EAAErQ,QAAQ,2BAA4B,MACpDg6C,MAAO,IAAM3pC,EAAErQ,QAAQ,+BAAgC,OAoClD,OAjCPqX,EAAK5K,QAAU,GACXA,EAAQ4K,EAAKq5B,WACfr5B,EAAK5K,QAAUA,EAAQ4K,EAAKq5B,WACxBr5B,EAAK5K,UAAY4D,IACnBgH,EAAK5K,QAAU,KAQf4K,EAAK5K,QAAQ6C,QAAQ,OAClB+H,EAAA5K,QAAU4K,EAAK5K,QAAQ+C,UAAU,EAAG6H,EAAK5K,QAAQ6C,QAAQ,OAIhD,QAAZ+H,EAAKs5B,IAAgBtgC,EAAEohB,SAAS,QAClCpa,EAAKs5B,GAAK,SACgB,SAAjBt5B,EAAKq5B,SAAuBrgC,EAAEohB,SAAS,OAEtB,SAAjBpa,EAAKq5B,QACdr5B,EAAKs5B,GAAK,UACgB,WAAjBt5B,EAAKq5B,SAAwB7sC,OAAOwT,EAAK5K,SAAW,IAEnC,UAAjB4K,EAAKq5B,SAAuB7sC,OAAOwT,EAAK5K,SAAW,IAElC,WAAjB4K,EAAKq5B,QAHdr5B,EAAKwgC,OAAS,aAKY,IAAjBxgC,EAAKq5B,UACdr5B,EAAKq5B,QAAU,cAVfr5B,EAAKwgC,OAAS,WAaTxgC,CACT,CDKiBgkC,CAASl4C,KAAK2d,KAAK2L,IACzB,MAAA,CACLikB,QAAS,GAAG+G,EAAK/G,WAAW+G,EAAKhrC,UACjCkkC,GAAI,GAAG8G,EAAK9G,MAAM8G,EAAKG,YAE3B,CAGO,OAAApU,GACL,OAAOrgC,KAAKqB,IACd,EE5NF,MAAqB82C,GAcZ,WAAA9jC,CAAYhT,GAbZkT,EAAAvU,KAAA,QACAuU,EAAAvU,KAAA,OACCuU,EAAAvU,KAAA,YACAuU,EAAAvU,KAAA,SACiBuU,EAAAvU,KAAA,SAAA,GACDuU,EAAAvU,KAAA,QAAA,GACGuU,EAAAvU,KAAA,WAAA,aAQzBA,KAAKqB,KAAOA,EACZrB,KAAKo4C,SAAWp4C,KAAKqB,KAAKuH,MAAQ5I,KAAKo4C,SAEvCp4C,KAAKmrB,IAAMvD,EACT,8MAG2B5nB,KAAKo4C,6CAKlCp4C,KAAK6rB,SAAW7rB,KAAKmrB,IAAIO,cAA2B,qBACpD1rB,KAAKq4C,MAAQr4C,KAAKmrB,IAAIO,cAA2B,aAE5C1rB,KAAAmrB,IAAI6E,QAAU,KACjBhwB,KAAK+wB,OAAM,CAEf,CAvBA,WAAIunB,GACF,OAAOt4C,KAAKu4C,MAAQv4C,KAAKyX,OAASzX,KAAKqB,KAAKyZ,QAC9C,CAuBA,KAAAiW,GACM/wB,KAAKs4C,SAAct4C,KAAAqB,KAAK4zB,QAAQj1B,KAAKyX,OAASzX,KAAKqB,KAAKyZ,UAC5D9a,KAAKw4C,eACP,CAGA,IAAA5/B,GACO5Y,KAAAmrB,IAAI7a,MAAM2b,QAAU,EAC3B,CAGA,IAAAnT,GACO9Y,KAAAmrB,IAAI7a,MAAM2b,QAAU,MAC3B,CAGA,UAAAI,CAAW+hB,GACTpuC,KAAK6rB,SAASvb,MAAM2b,QAAUmiB,EAAY,GAAK,OAC/CpuC,KAAKq4C,MAAM/nC,MAAM2b,QAAUmiB,EAAY,OAAS,EAClD,CAGA,OAAAqK,CAAQ7f,GACN54B,KAAKqsB,YAAW,GAEhBrsB,KAAKq4C,MAAMl8C,UAAYy8B,EAClB54B,KAAAmrB,IAAII,UAAUpN,IAAI,WACvB1hB,OAAO0vB,YAAW,KACXnsB,KAAAq4C,MAAMl8C,UAAY6D,KAAKo4C,SACvBp4C,KAAAmrB,IAAII,UAAUI,OAAO,UAAS,GAClC,IACL,CAGO,MAAApV,CAAOkB,EAAgB8gC,GAC5Bv4C,KAAKyX,OAASA,EACdzX,KAAKu4C,MAAQA,EAEbv4C,KAAKw4C,eACP,CAEO,aAAAA,GACDx4C,KAAKs4C,QAASt4C,KAAK4Y,YACbE,MACZ,ECtFF,MAAqB4/B,GAArB,WAAArkC,GACUE,EAAAvU,KAAA,YACuCuU,EAAAvU,KAAA,kBAAA,MACvCuU,EAAAvU,KAAA,MAAA,CAER,MAAA4iC,CAAO7lB,GAsBL,OArBA/c,KAAK+c,IAAMA,EAEN/c,KAAAoT,SAAW,IAAI+kC,GAAY,CAC9Br9B,SAAUiC,EAAIjC,SACdma,QAAgBnnB,GAAM/N,EAAAC,KAAA,MAAA,YAChB+c,EAAA3F,UAAUG,cAAc,CAC1BE,OAAQ3J,GAEZ,IACAlF,KAAMtK,EAAG,cAIPye,EAAI47B,mBACN34C,KAAK44C,gBAAkB,KAChB54C,KAAKoT,SAASklC,UAAWt4C,KAAK+c,IAAI3F,UAAUiiB,cACjDr5B,KAAKoT,SAAS2d,SAEhB/wB,KAAK+c,IAAIka,YAAYvhB,GAAG,oBAAqB1V,KAAK44C,kBAG7C54C,KAAKoT,SAAS+X,GACvB,CAEA,UAAAkB,CAAWvV,GACJ9W,KAAAoT,SAASiZ,WAAWvV,EAC3B,CAEA,MAAAP,CAAOkB,EAAgB8gC,GAChBv4C,KAAAoT,SAASmD,OAAOkB,EAAQ8gC,EAC/B,CAEA,OAAAE,CAAQngC,GACDtY,KAAAoT,SAASqlC,QAAQngC,EACxB,CAEA,IAAAotB,GACE1lC,KAAKoT,SAAS2d,OAChB,CAEA,UAAA8nB,GACE,OAAO74C,KAAKoT,SAASklC,OACvB,CAEA,kBAAAQ,CAAmBxhC,GACjB,OAAyB,IAAlBA,EAAOG,MAChB,CAEA,OAAAshC,GACO/4C,KAAA44C,iBAAmB54C,KAAK+c,IAAIka,YAAYthB,IAAI,oBAAqB3V,KAAK44C,iBACtE54C,KAAAoT,SAAS+X,IAAIQ,QACpB,ECrDF,MAAqBqtB,GAoBZ,WAAA3kC,CAAYkkC,EAAel3C,GAnB1BkT,EAAAvU,KAAA,QACDuU,EAAAvU,KAAA,SACAuU,EAAAvU,KAAA,OACAuU,EAAAvU,KAAA,UACAuU,EAAAvU,KAAA,cACAuU,EAAAvU,KAAA,YACAuU,EAAAvU,KAAA,YAEeuU,EAAAvU,KAAA,OAAA,GAYpBA,KAAKu4C,MAAQA,EACbv4C,KAAKqB,KAAOA,EAEZrB,KAAKmrB,IAAMvD,EACT,okCAYF5nB,KAAK0wB,OAAS1wB,KAAKmrB,IAAIO,cAAc,cACrC1rB,KAAK0wB,OAAOriB,MAAQ,GAAGrO,KAAKqkB,OAE5BrkB,KAAK0wB,OAAOuoB,QAAU,IAAMj5C,KAAKoR,QACjCpR,KAAK0wB,OAAOwoB,UAAaxmC,GAAM1S,KAAKm5C,QAAQzmC,GAE5C1S,KAAKo5C,SAAWp5C,KAAKmrB,IAAIO,cAAc,iBACvC1rB,KAAKq5C,SAAWr5C,KAAKmrB,IAAIO,cAAc,iBAEvC1rB,KAAKo5C,SAASppB,QAAU,IAAMhwB,KAAKqZ,OACnCrZ,KAAKq5C,SAASrpB,QAAU,IAAMhwB,KAAK0lC,OAEnC1lC,KAAKw4C,eACP,CAxCA,YAAI19B,GACF,OAAO9a,KAAKqB,KAAKyZ,QACnB,CACA,UAAIrD,GACK,OAAAzX,KAAK8a,UAAY9a,KAAKqkB,KAAO,EACtC,CACA,WAAIi1B,GACF,OAAOz6C,KAAK06C,KAAKv5C,KAAKu4C,MAAQv4C,KAAK8a,SACrC,CAkCO,MAAAvE,CAAOkB,EAAgB8gC,GAC5Bv4C,KAAKqkB,KAAOxlB,KAAK06C,KAAK9hC,EAASzX,KAAK8a,UAAY,EAChD9a,KAAKu4C,MAAQA,EAERv4C,KAAAw5C,SAASx5C,KAAKqkB,MACnBrkB,KAAKw4C,eACP,CAEO,QAAAgB,CAASn1B,GACTrkB,KAAA0wB,OAAOriB,MAAQ,GAAGgW,GACzB,CAEO,KAAAjT,CAAM3M,GAAe,GACnBhI,OAAAk3B,aAAa3zB,KAAKy5C,YAEzB,MAAMprC,EAAQrO,KAAK0wB,OAAOriB,MAAMvS,OAE1Bk3C,EAAS,KACb,GAAc,KAAV3kC,EAEF,YADKrO,KAAAw5C,SAASx5C,KAAKqkB,MAGjB,IAAAA,EAAO3jB,OAAO2N,GACd3N,OAAOu7B,MAAM5X,IAIbA,EAAO,EAHJrkB,KAAAw5C,SAASx5C,KAAKqkB,OAOjBA,EAAOrkB,KAAKs5C,UACTt5C,KAAAw5C,SAASx5C,KAAKs5C,SACnBj1B,EAAOrkB,KAAKs5C,SAEdt5C,KAAK05C,OAAOr1B,GAAI,EAIb5f,MAAUzE,KAAAy5C,WAAah9C,OAAO0vB,YAAW,IAAM6mB,KAAU,IAEhE,CAEO,IAAA35B,GACC,MAAAgL,EAAOrkB,KAAKqkB,KAAO,EACrBA,EAAO,GAGXrkB,KAAK05C,OAAOr1B,EACd,CAEO,IAAAqhB,GACC,MAAArhB,EAAOrkB,KAAKqkB,KAAO,EACrBA,EAAOrkB,KAAKs5C,SAGhBt5C,KAAK05C,OAAOr1B,EACd,CAEO,UAAAw0B,GACE,OAAA74C,KAAKqkB,KAAO,GAAKrkB,KAAKs5C,OAC/B,CAEO,MAAAI,CAAOr1B,GACZrkB,KAAKqkB,KAAOA,EACPrkB,KAAAqB,KAAKs4C,SAAS35C,KAAKyX,QACxBzX,KAAKw5C,SAASn1B,GACdrkB,KAAKw4C,eACP,CAEO,aAAAA,GACDx4C,KAAKqkB,KAAO,EAAIrkB,KAAKs5C,QAClBt5C,KAAAq5C,SAAS9tB,UAAUpN,IAAI,gBAEvBne,KAAAq5C,SAAS9tB,UAAUI,OAAO,gBAG7B3rB,KAAKqkB,KAAO,EAAI,EACbrkB,KAAAo5C,SAAS7tB,UAAUpN,IAAI,gBAEvBne,KAAAo5C,SAAS7tB,UAAUI,OAAO,eAEnC,CAEO,OAAAwtB,CAAQzmC,GACP,MAAAkiB,EAAUliB,EAAEkiB,SAAWliB,EAAEmiB,MAE/B,GAAgB,KAAZD,EAAgB,CAElB,MAAMvQ,EAAO3jB,OAAOV,KAAK0wB,OAAOriB,OAAS,EACrC,GAAAgW,EAAOrkB,KAAKs5C,QACd,OAEFt5C,KAAKw5C,SAASn1B,GACdrkB,KAAKoR,OAAM,MAAA,GACU,KAAZwjB,EAAgB,CAEzB,MAAMvQ,EAAO3jB,OAAOV,KAAK0wB,OAAOriB,OAAS,EACzC,GAAIgW,EAAO,EACT,OAEFrkB,KAAKw5C,SAASn1B,GACdrkB,KAAKoR,OAAM,MACU,KAAZwjB,GAET50B,KAAKoR,OAAM,EAEf,CAGA,UAAAib,CAAW+hB,GACLA,EAA0Bl2B,GAAAlY,KAAKmrB,KAC9BkD,GAAeruB,KAAKmrB,IAC3B,EC1KF,MAAqByuB,GAArB,WAAAvlC,GACUE,EAAAvU,KAAA,WAAA,CAER,MAAA4iC,CAAO7lB,GAeL,OAdA/c,KAAKoT,SAAW,IAAIymC,GAAoB98B,EAAIw7B,MAAO,CACjDz9B,SAAUiC,EAAIjC,SACd6+B,SAAiB7rC,GAAM/N,EAAAC,KAAA,MAAA,YACrB+c,EAAI+8B,mBAEA/8B,EAAA3F,UAAUG,cAAc,CAC1BE,OAAQ3J,EACRwmB,UAAW,WACT,OAAAzgB,EAAAkJ,EAAIg9B,kBAAJlmC,EAAA9J,KAAAgT,EAAA,GAGN,MAGK/c,KAAKoT,SAAS+X,GACvB,CAEA,UAAAkB,CAAWvV,GACJ9W,KAAAoT,SAASiZ,WAAWvV,EAC3B,CAEA,MAAAP,CAAOkB,EAAgB8gC,GAChBv4C,KAAAoT,SAASmD,OAAOkB,EAAQ8gC,EAC/B,CAEA,IAAA7S,GACE1lC,KAAKoT,SAASsyB,MAChB,CAEA,UAAAmT,GACS,OAAA74C,KAAKoT,SAASylC,YACvB,CAEA,kBAAAC,GACS,OAAA,CACT,CAEA,OAAAC,GACO/4C,KAAAoT,SAAS+X,IAAIQ,QACpB,ECrCF,SAASquB,GAAsBjuC,GAI7B,MAAM6V,EAAI,CAAEnK,OAAQ,EAAG8gC,MAAO,GAC1B,OAACxsC,GAEH6V,EAAAnK,OAAS1L,EAAKuL,OAAOG,OACnB1L,EAAK4R,OAAMiE,EAAE22B,MAAQxsC,EAAKuL,OAAO0C,SAAWjO,EAAK4R,KAAKqB,MAAQjT,EAAK4R,KAAKs8B,aAErEr4B,GALWA,CAMpB,CAMa,MAAAs4B,GAAyB74C,IACpC,IAAI84C,EAA8B,KAG7B94C,EAAA+U,UAAUI,UAAU,CAAC,aAAc,WAAYF,IAC5C,MAAA7L,EAAOpJ,EAAK+4C,UACZz8B,EAAOtc,EAAK+V,UAEd+iC,KAAqBpB,UAGzBoB,EAjCJ,SAA+B7jC,GAC7B,OAAIA,EAAKuE,WAAWnX,SAAiB,IAAIg1C,GAClC,IAAIkB,EACb,CA8BgBS,CAAsB/jC,GAGlC,MAAMmB,OAAEA,EAAQ8gC,MAAAA,GAAUyB,GAAsBr8B,EAAKkd,oBAC/Cyf,EAAaH,EAAUvX,OAAO9jB,EAAA,CAClChE,SAAUxE,EAAKuE,WAAWC,SAC1By9B,QAEAI,iBAAkBriC,EAAKuE,WAAWE,UAE/B1Z,IAIAoJ,EAAAmyB,oBAAoBxR,MAAMkvB,GAGpB,MAAAH,GAAAA,EAAA5jC,OAAOkB,EAAQ8gC,EAAA,IAI5Bl3C,EAAK41B,YAAYvhB,GAAG,eAAgBqT,IAE5B,MAAAtR,OAAEA,QAAQ8gC,GAAUyB,GAAsB34C,EAAK+V,UAAUyjB,oBACpD,MAAAsf,GAAAA,EAAA5jC,OAAOkB,EAAQ8gC,EAAA,IAI5Bl3C,EAAK41B,YAAYvhB,GAAG,cAAe4B,IAE7BjW,EAAK+V,UAAUrB,cAAc5X,OAAS,IAAgB,MAAXg8C,OAAW,EAAAA,EAAArB,mBAAmBxhC,KACtEjW,EAAA+V,UAAU2uB,eACjB,IAIF1kC,EAAK41B,YAAYvhB,GAAG,eAAe,WACtB,OAAA7B,EAAA,MAAAsmC,OAAA,EAAAA,EAAA1B,UAAUn6C,EAAAA,KAAAA,EAAAA,EAAG,YAAU,IAIpC+C,EAAK41B,YAAYvhB,GAAG,cAAe4B,IACjC,MAAA6iC,GAAAA,EAAW9tB,YAAW,EAAA,IAExBhrB,EAAK41B,YAAYvhB,GAAG,gBAAgB,EAAG4B,aACrC,MAAA6iC,GAAAA,EAAW9tB,YAAW,EAAA,GACvB,ECjEI,MAAMkuB,GAiBX,WAAAlmC,CAAYhT,GAhBJkT,EAAAvU,KAAA,QACAuU,EAAAvU,KAAA,OAKAuU,EAAAvU,KAAA,iBAKAuU,EAAAvU,KAAA,eAA8B,IAMpCA,KAAKqB,KAAOA,EAGPrB,KAAAmrB,IAAMvD,EC1CA,upBD2CX5nB,KAAKiqC,cAAgBjqC,KAAKmrB,IAAIO,cAAc,2BAGtBwuB,GAAAp7B,EAAA,CACpBs7B,QAAS,IAAMp6C,MACZqB,IAILrB,KAAKw6C,gBACP,CA7BA,KAAAxkC,GACE,OAAOhW,KAAKmrB,GACd,CAGA,iBAAAyR,GACE,OAAO58B,KAAKiqC,aACd,CAGA,eAAAn0B,GACE,OAAO9V,KAAKy6C,YACd,CAmBA,SAAAne,EAAUC,cAAEA,GAA+C,IACzD,OAAO,IAAIyO,GAAW,CACpBf,cAAejqC,KAAKiqC,cACpBH,WAAY9pC,KAAKqB,KAAK+U,UAAUvB,MAAMqF,SACtCD,QAASja,KAAKqB,KAAK+U,UAAUvB,MAAMoF,QACnCD,SAC2B,kBAAlBuiB,EACHA,EACCv8B,KAAKqB,KAAK+U,UAAUvB,MAAMmF,SAEjCgwB,kBAAmB,CAAC30B,EAAGuM,KACf,MAAAzR,EEpDE,SACd9O,EACA+K,EACAuL,GAEA,MAAMrB,EAAOjV,EAAK+U,UAAUvB,MAEtBzB,EAAW,IAAImgC,GAAYnnC,EAAS,CACxCynC,cAAe,KACbxyC,EAAK41B,YAAYphB,QAAQ,mBAAoBzC,EAAQ,EAEvD8/B,SAAW/oB,IACT9oB,EAAK+V,UAAUsM,cAAcyG,EAAE6P,QAAO,EAGxCsX,QAAS35B,EAGTqC,SACiC,kBAAxB,MAAA3Y,OAAA,EAAAA,EAAMk7B,eAA8B,MAAAl7B,OAAA,EAAAA,EAAMk7B,cAAiBjmB,EAAK0D,SACzEW,SAAUrE,EAAKqE,SACfV,QAAS3D,EAAK2D,QACde,YAAa1E,EAAK0E,YAClB21B,iBAAkBr6B,EAAKq6B,iBACvBjT,iBAAkBpnB,EAAKonB,iBACvBrjB,KAAM/D,EAAK+D,KACX7W,SAAU8S,EAAK9S,SACf8W,QAAShE,EAAKgE,QACd0iB,cAAe1mB,EAAK0mB,cAGpB/lB,OAAQ5V,EAAK4V,OACbU,aAActW,EAAKsW,aACnBI,YAAa1W,EAAK0W,cAMb3E,OAFPA,EAASqxB,SAEFrxB,CACT,CFYqB42B,CAAkBlrB,EAAA,CAAEyd,iBAAkBv8B,KAAKqB,MAAQgU,EAAGuM,GAE5D,OADF5hB,KAAAy6C,aAAantC,KAAK6C,GAChBA,CAAA,EAETq6B,gBAAkBhnB,GAAOxjB,KAAKy6C,aAAalwB,MAAMJ,GAAMA,EAAE6P,UAAYxW,KAEzE,CAEQ,cAAAg3B,GACNx6C,KAAKqB,KAAK41B,YAAYvhB,GAAG,aAAcqT,IAEhC/oB,KAAAs8B,YAAYsM,OAAO7f,EAAQ,IAGlC/oB,KAAKqB,KAAK41B,YAAYvhB,GAAG,eAAgBqT,IACf,IAApBA,EAAS5qB,SACX6B,KAAKy6C,aAAe,GACpBz6C,KAAKiqC,cAAcpuC,UAAY,GACjC,IAIFmE,KAAKqB,KAAK41B,YAAYvhB,GAAG,oBAAqBtJ,UAC5C,MAAMuL,EAAevL,EAAQid,IACzB,OAAAxV,EAAA7T,KAAKy6C,aAAalwB,MAAMJ,GAAMA,EAAE6P,UAAY5tB,EAAQid,gBAAMjS,eAC1D,EACJpX,KAAKs8B,YAAYE,OAAOpwB,EAASuL,EAAY,IAI/C3X,KAAKqB,KAAK41B,YAAYvhB,GAAG,mBAAoBtJ,IACrC,MAAA+D,EAAOnQ,KAAKy6C,aAAalwB,MAAMJ,GAAMA,EAAE6P,UAAY5tB,EAAQoX,KAC5DrT,GAILA,EAAKwb,SACA3rB,KAAAy6C,aAAez6C,KAAKy6C,aAAaxsC,QAAQkc,GAAMA,EAAE6P,UAAY5tB,EAAQoX,MAJxE3jB,QAAQD,MAAM,mBAAmBwM,EAAQoX,eAIiC,IAK9ExjB,KAAKqB,KAAK41B,YAAYvhB,GAAG,mBAAoBtJ,IACrC,MAAA+D,EAAOnQ,KAAKy6C,aAAalwB,MAAMJ,GAAMA,EAAE6P,UAAY5tB,EAAQoX,KACzDrT,GAAAA,EAAK8iC,QAAQ7mC,EAAO,GAEhC,EGvFK,MAAMsuC,GASX,WAAArmC,CAAYhT,GARJkT,EAAAvU,KAAA,QACDuU,EAAAvU,KAAA,OACAuU,EAAAvU,KAAA,SACAuU,EAAAvU,KAAA,WACAuU,EAAAvU,KAAA,aACAuU,EAAAvU,KAAA,eACAuU,EAAAvU,KAAA,WAmBmBuU,EAAAvU,KAAA,mBAAA,GAGlBuU,EAAAvU,KAAA,aAnBNA,KAAKqB,KAAOA,EACPrB,KAAAmrB,IAAMvD,ECpCA,wSDqCX5nB,KAAKi2B,QAAUj2B,KAAKmrB,IAAIO,cAAc,uBACtC1rB,KAAKwgC,UAAYxgC,KAAKi2B,QAAQvK,cAAc,sBAC5C1rB,KAAKmgC,YAAcngC,KAAKmrB,IAAIO,cAAc,4BAErC1rB,KAAAwgC,UAAUxQ,QAAU,KACvBhwB,KAAK8Y,MAAK,CAEd,CAEa,aAAAknB,GAAgB,OAAAjgC,EAAAC,KAAA,MAAA,YAC3BA,KAAK26C,iBAAkB,CACzB,GAAA,CASa,IAAA/hC,GAAK,OAAA7Y,EAAAC,KAAAgK,WAAA,UAAAsM,EAA2B,IAQ3C,GAPKtW,KAAAmrB,IAAI7a,MAAMsqC,UAAY,GAG3B56C,KAAK66C,YACL76C,KAAK0iC,MAAO9pB,OAGR5Y,KAAK26C,gBACP36C,KAAK26C,iBAAkB,EACvB36C,KAAKmgC,YAAYtkC,UAAY,GAC7BmE,KAAKogC,QAAUpgC,KAAK86C,aAAaxkC,EAAKykC,MACjC/6C,KAAAmgC,YAAYrgB,OAAO9f,KAAKogC,aACxB,CAEL,MAAMA,EAAUpgC,KAAKogC,QACf4a,EAAY5a,EAAQzsB,IACtB3T,KAAKi7C,gBAAkBD,EAAU1sB,SAAS,gBACvCtuB,KAAAk7C,WACH9a,EACA4a,EAAUn+C,QAAQ,eAAgB,aAAa6D,OAAOV,KAAKi7C,kBAGjE,CAGAj7C,KAAKm7C,UAAU,CACb7mB,UAAW,IAAMt0B,KAAK4Y,KAAKtC,KAIxBtW,KAAAo7C,UAAYjvB,YAAW,aAC1BnsB,KAAKo7C,eAAY,EACZp7C,KAAAmrB,IAAI7a,MAAMsqC,UAAY,kBAE3B,OAAAp6B,GAAA3M,EAAA7T,KAAKqB,MAAKolC,SAAVjmB,EAAAzW,KAAA8J,EAAA,GACC,IACL,GAAA,CAGO,IAAAiF,SACL,OAAAjF,EAAA7T,KAAK0iC,QAAO7uB,EAAAiF,MACd,CAIc,SAAAqiC,CAAU95C,GAAiC,OAAAtB,EAAAC,KAAA,MAAA,YACvD,MAAM2d,SACE3d,KAAKqB,KAAK4V,SAASsF,KAAKiJ,cAAc1G,EAAA,CAAA,EACvC9e,KAAKqB,KAAK4V,SAASsQ,mBAExB5J,KACEA,EAAKyW,WAAazW,EAAKsW,WACzBj0B,KAAK26C,iBAAkB,EAGlB36C,KAAAqB,KAAK01B,cAAche,WAAW,CACjCub,UAAW,KACTnI,YAAW,KACT9qB,EAAKizB,WAAU,GACd,IAAG,EAERgO,SAAU,KACRtiC,KAAK8Y,MAAK,IAKd9Y,KAAK8Y,OAET,GAAA,CAEQ,SAAA+hC,GACF76C,KAAK0iC,QAEJ1iC,KAAA0iC,MAAQ1iC,KAAKqB,KAAKshC,YAAYC,OAAO,UAAW5iC,KAAKmrB,KACrDnrB,KAAA0iC,MAAMyD,gBAAe,aAEnBnmC,KAAAo7C,WAAaznB,aAAa3zB,KAAKo7C,WAG/Bp7C,KAAAmrB,IAAI7a,MAAMsqC,UAAY,GAG3B,OAAAp6B,GAAA3M,EAAA7T,KAAKqB,MAAKqlC,SAAVlmB,EAAAzW,KAAA8J,EAAA,IAEJ,CAEQ,YAAAinC,CAAaC,GACnB,MAAM3a,EAAUxY,EACd,sEAIItmB,EAEF4wB,EAAuB,CACrB3wB,KAAMvB,KAAKqB,KAAK+U,UAAUvB,MAAMrO,OAChChF,KAAM,cAGNyb,EAAa,CACjBtD,QAAS3Z,KAAKqB,KAAK+U,UAAUvB,MAAM8E,QACnCE,KAAM7Z,KAAKqB,KAAK+U,UAAUvB,MAAMgF,MAAQ,GACxC0C,KAAMmD,KAAKC,UAAU3f,KAAKqB,KAAK8V,UAAUC,WACzCikC,MAAO,IAAI18C,MAGTo8C,MAAYA,KAAOA,GACvB99B,EAAMpG,SAAW7W,KAAKi7C,cAAgB,IAAM,IAEtC,MAAAK,EAAY,IAAIC,gBAAgBt+B,GAG/B,OAFFjd,KAAAk7C,WAAW9a,EAAS,GAAG9+B,KAAWg6C,EAAUp9C,cAE1CkiC,CACT,CAEQ,WAAA6a,GACN,MAA8C,SAAvCj7C,KAAKqB,KAAK+U,UAAUvB,MAAMgC,SAC7Bpa,OAAO4f,WAAW,gCAAgCnN,QAClDlP,KAAKqB,KAAK+U,UAAUvB,MAAMgC,QAChC,CAEQ,UAAAqkC,CAAW9a,EAA4BzsB,GAC7CysB,EAAQzsB,IAAMA,EAGXwa,GAAYnuB,KAAKmgC,aACpBC,EAAQG,OAAS,KACZlS,GAAYruB,KAAKmgC,YAAW,CAEnC,EEzLW,MCSAqb,GAAiC,QCDCx9B,IAAI,CCRTmb,IACpCA,EAAA5jB,QAAQ,QAAS8hB,GAAW,IAAIuO,GAAYvO,IAAS,CAAC,WAEtD8B,EAAAzjB,GAAG,WAAW,KAEZyjB,EAAI/iB,UAAUsF,qBAChByd,EAAI/hB,UAAUG,cAAc,CAAEE,OAAQ,GACxC,GACD,EjDPsC0hB,IACvCA,EAAI5jB,QAAQ,eAAe,IkDiBtB,WACL,MAAMiH,EAAyB,GACxB,MAAA,CACL2B,IAAK,CAAC0I,EAAQlb,KACZ6Q,EAASlP,KAAK,CAAEuZ,SAAQlb,WAAS,EAEnCggB,OAAS9E,IACP,MAAM3a,EAAQsQ,EAASi/B,WAAWC,GAAMA,EAAE70B,SAAWA,KACvC,IAAV3a,GAAuBsQ,EAAAm/B,OAAOzvC,EAAO,EAAC,EAE5C2I,IAAK,IAAM2H,EAEf,ClD7BmCo/B,IAAqB,IAClDziB,EAAA5jB,QACF,OACA,CAACgH,EAAMs/B,EAAQC,IAAgB,IAAI10B,GAAI9K,GAAkBu/B,EAAOhnC,MAAO0H,EAAMu/B,KAC7E,CAAC,OAAQ,SAAU,eACnB,CACE/mC,UAAW,aACb,EmDTsCokB,IACxCA,EAAI3iB,UAAU,CAAC,WAAYF,IvH8CtB,IAAmBqF,KuH7CPrF,EAAKqF,UvH8CP7T,IACFA,EAAA6T,EACb5T,EAA+B,iBAAX4T,EAAsBnU,EAAcmU,GAAUA,EuHhDtC,GAC3B,ECHuCwd,IACpCA,EAAA5jB,QACF,QACA,IACS,IAAIsqB,GAAY,CACrBG,cAAgBriB,IACVwb,EAAAtjB,QAAQ,eAAgB8H,EAAI,KAItC,GAAC,ECVuCwb,IACtCA,EAAA5jB,QACF,UACA,CAAC8hB,EAAQwkB,KACD,MAAAjY,EAAS,IAAIU,GAAO,CACxBrN,UAAW,IAAMI,EACjBjhB,QAAS,IAAMylC,IAGV,OADP1iB,EAAInjB,QAAQgW,YAAY4X,EAAO5tB,SACxB4tB,CAAA,GAET,CAAC,SAAU,UAAQ,ECXmBzK,IACpCA,EAAA5jB,QACF,QACA,CAACqe,EAAKyD,EAAQwkB,EAAQl+B,EAAMimB,KACpB,MAAAn5B,EAAO,IAAI8vC,GAAK,CACpBtjC,OAAQ,IAAM2c,EACdqD,UAAW,IAAMI,EACjBjhB,QAAS,IAAMylC,EACfzkC,QAAS,IAAMuG,EAEfhG,aAAc,CAACwS,EAAGgB,IAAQyY,EAAO9rB,gBAAgBqS,EAAGgB,GACpDpT,YAAa,CAACoS,EAAGgB,IAAQyY,EAAO5rB,eAAemS,EAAGgB,GAClD2uB,iBAAkB,IAAMlW,EAAOlrB,aAC/BqhC,gBAAiB,IAAM5gB,EAAIzhB,kBAGtB,OADPyhB,EAAInjB,QAAQgW,YAAYvhB,EAAKuL,SACtBvL,CAAA,GAET,CAAC,MAAO,SAAU,SAAU,OAAQ,UAAQ,E/ClBF0uB,IACxCA,EAAA5jB,QACF,YACA,CAACqe,EAAKkoB,EAAaC,EAAQx/B,EAAMs/B,KACzB,MAAAG,EAAW,IAAIxZ,GAAgB,CACnCvrB,OAAQ,IAAM2c,EACd+O,UAAW,IAAMoZ,EACjB5kC,QAAS,IAAMoF,EACfklB,SAAU,IAAMtI,EAAI3hB,SAGpB8oB,oBAAqB,IAAM,GAAGub,EAAOhnC,MAAMrO,6BAAiC,IAAA7H,SAMvE,OAHPm9C,EAAY39B,IAAI,gBAAiBO,GAAQs9B,EAAShjC,aAAa0F,KAC/Do9B,EAAY39B,IAAI,cAAc,IAAM69B,EAASjjC,WAAW,CAAE,KAEnDijC,CAAA,GAET,CAAC,MAAO,cAAe,SAAU,OAAQ,UAAQ,EgDnBT7iB,IACtCA,EAAA5jB,QAAQ,UAAU,KACd,MAAA0mC,EAAe,IAAIxT,GAKlB,OAJP7sC,SAAS6kB,KAAKuL,YAAYiwB,EAAajmC,SACnCmjB,EAAAzjB,GAAG,aAAa,KACJ,MAAAumC,GAAAA,EAAAhmC,SAAA,IAETgmC,CAAA,GACR,ETR0C9iB,IACvCA,EAAA5jB,QACF,WACA,CAAC8hB,EAAQ1Z,EAAMimB,EAAQoY,EAAUpoB,EAAKioB,EAAQt/B,EAAMw/B,KAC5C,MAAAG,EAAe,IAAIxB,GAAa,CACpCjU,OAAQ,KACNta,YAAW,KACJxO,EAAAuW,eAAe,GAAE,GACrB,GAEHmD,EAAOxhB,QAAQ,eAAc,EAE/B6wB,OAAQ,KAEN9C,EAAOlrB,aAEP2e,EAAOxhB,QAAQ,eAAc,EAE/BkhB,YAAa,IAAMilB,EACnB/kC,OAAQ,IAAM2c,EACdxd,QAAS,IAAMylC,EACf1kC,QAAS,IAAMoF,EACfomB,UAAW,IAAMoZ,IAOZ,OAJH5iB,EAAAzjB,GAAG,gBAAgB,KACP,MAAAwmC,GAAAA,EAAAlc,eAAA,IAGTkc,CAAA,GAET,CAAC,SAAU,OAAQ,SAAU,WAAY,MAAO,SAAU,OAAQ,UAAQ,IU/BvC/iB,IACrCA,EAAI3iB,UAAU,CAAC,cAAe,kBAAmBF,K5G8B5C,SAAoBtN,GACrB,IACE,IAACmzC,EAAAA,OAAO9/C,KAAM,MAAA,CACZ,MAAAqW,GACN,MACF,CAGMT,MAAAA,EAAS,IAAIkqC,EAAAA,OACnBlqC,EAAOmqC,WAAWt9B,EAAAA,EAAA,CAChB9M,SAAUD,GAAY,CACpBoB,YAAanK,EAAQmK,eAEpBG,IACAtK,EAAQsK,gBAGFrB,GAAAA,CACb,C4G/CsBoqC,CAAA,CAChB/oC,cAAegD,EAAKhD,cACpBH,YAAamD,EAAKnD,aACnB,IAGHgmB,EAAI3iB,UAAU,CAAC,oBAAqBF,I5Ga/B,IAAsB0hC,E4GZpB1hC,EAAAwF,kB5GYoBk8B,E4GZmB1hC,EAAKwF,gB5GavCzI,GAAA2kC,E4GbsD,GACjE,E9EkBqC7e,IAClCA,EAAA5jB,QACF,eACA,CAACquB,EAAQiY,EAAQt/B,EAAMoB,EAAMq+B,EAAUpoB,KAC/B,MAAA0oB,EAAgB,IAAI/kB,GAAc,CACtCJ,gBAAiB,IAAMgC,EAAInjB,QAC3B6gB,UAAW,IAAM+M,EACjBxtB,QAAS,IAAMylC,EACf1kC,QAAS,IAAMoF,EACftF,OAAQ,IAAM2c,EACdxc,QAAS,IAAMuG,EACfoZ,YAAa,IAAMilB,EACnBhkB,YAAa,IAAMmB,EAAItjB,QAAQ,sBAG1B,OADP+tB,EAAOc,WAAW4X,GACXA,CAAA,GAET,CAAC,SAAU,SAAU,OAAQ,OAAQ,WAAY,OAAK,E+E9CdnjB,IACpC,MAAA5c,EAAO4c,EAAIxkB,OAAO,QAElB4nC,EAAY,KAuCpB,IAA2Bxc,IArCrBxjB,EAAKnF,UAAUgd,SAgBrB,SAAyB/yB,GACvB,MAAM0c,EAAqB,GAGtB1c,EAAA0V,MACFmH,iBAA8B,yBAC9B9P,SAAS1E,GAASqU,EAAIzQ,KAAK5D,KAMxB,MAAA8yC,EAAa5gD,SAAS8vB,cAA2B,gBAMhD,OALH8wB,GAECA,EAAAt+B,iBAA8B,yBAC9B9P,SAAS1E,GAASqU,EAAIzQ,KAAK5D,KAEzBqU,CACT,CAlCM0+B,CAAgB,CACd1lC,MAAOoiB,EAAInjB,UAoCb5H,SAAS0hB,IACPiQ,EAASjQ,EAAMvE,UAAUI,OAAO,YAC/BmE,EAAMvE,UAAUpN,IAAI,WAAU,GArChC,EAIDgb,EAAAzjB,GAAG,eAAe,YAIlByjB,EAAAzjB,GAAG,gBAAiB6G,UAEvB,KVHE2c,GWfkCC,IACjCA,EAAAzjB,GAAG,cAAe4B,IAChB,GAAkB,IAAlBA,EAAOG,OAAc,OAEzB,MAAM8E,EAAO4c,EAAIliB,SAASsQ,gBACrBhL,GAIF4c,EAAAliB,SACAkd,SAAStQ,YAAYtH,GACrBmF,MAAMhD,IACLya,EAAI/hB,UAAU8c,eAAexV,EAAIf,KAAKwW,SAAQ,GAC/C,GACJ,ExGGyCgF,IACtCA,EAAA3iB,UACF,CAAC,OAAQ,UAAW,YAAa,UAAW,OAAQ,kBAAmB,UACtEF,IACiBwG,GAAA,CACd7F,OAAQ,IAAMkiB,EAAIliB,SAClBwF,SAAUnG,EAAKuD,KACfF,QAASrD,EAAKqD,QACdC,UAAWtD,EAAKsD,UAChBY,QAASlE,EAAKkE,QACdC,KAAMnE,EAAKmE,KACX6D,YAAahI,EAAKoE,gBAClBe,MAAOnF,EAAKmF,OACb,GACH,E2C1BuC0d,IACnC,MAAA1uB,EAAO0uB,EAAIxkB,OAAO,QACxBwkB,EAAI3iB,UAAU,CAAC,aAAc,iBAAkBF,IACzCA,EAAKsF,YAActF,EAAK+E,eAAiB+iB,IAKjD,SAAsB3zB,EAAYiyC,EAAeC,GACzC,MAAAC,EpEwGQ,SAAeltC,EAAW85B,GAClC,MAAAqT,EAAKntC,EAAE9O,MAAM,KACbk8C,EAAKtT,EAAE5oC,MAAM,KACnB,IAAA,IAAS4M,EAAI,EAAGA,EAAI,EAAGA,IAAK,CAC1B,MAAMuvC,EAAKr8C,OAAOm8C,EAAGrvC,IACfwvC,EAAKt8C,OAAOo8C,EAAGtvC,IACjB,GAAAuvC,EAAKC,EAAW,OAAA,EAChB,GAAAA,EAAKD,EAAW,OAAA,EAChB,IAACr8C,OAAOu7B,MAAM8gB,IAAOr8C,OAAOu7B,MAAM+gB,GAAY,OAAA,EAC9C,GAAAt8C,OAAOu7B,MAAM8gB,KAAQr8C,OAAOu7B,MAAM+gB,GAAY,OAAA,CACpD,CACO,OAAA,CACT,CoEpHeC,CAAqBP,EAAOC,GAEzC,GADyB,IAATC,EACH,OAEb,MAAMjkB,EAAQ/Q,EACZ,yCAAyCtpB,EAAG,YAAa,CACvDjC,KAAiBiC,EAAXs+C,EAAO,EAAO,SAAe,sCAEhCt+C,EAAG,sBAAsBA,EAAG,aAAao+C,OAAWp+C,EAAG,aAAaq+C,kBAGrEO,EAAYt1B,EAAoB,gCAAgCtpB,EAAG,oBACzE4+C,EAAUltB,QAAU,KAClB2I,EAAMhN,SACeyS,IAAA,CAAA,EAEvBzF,EAAM7Y,OAAOo9B,GACbzyC,EAAKuL,QAAQgY,cAAe0I,QAAQiC,EACtC,CAvBmBtd,CAAA5Q,EAAMqyB,GAAgBxmB,EAAKsF,WAAU,GACrD,ECGoCud,IAC/B,MAAA7iB,EAAO6iB,EAAIxkB,OAAO,UAClBonC,EAAS5iB,EAAIxkB,OAAO,UAGtB,IAAAwoC,EAEE,MAAAC,EAAQvmC,IAEZ,MAAM0nB,EAAO,CAACpF,EAAInjB,QAAS+lC,EAAO/lC,SAG7BqoB,KACaA,GAAA5hC,OAAO4f,WAAW,iCAGnB,SAAbxF,GAEGsmC,IAEHA,EAAuBjsB,GAAQoN,GAAiBC,EAAMrN,EAAIhiB,SAC5CmvB,GAAAjR,iBAAiB,SAAU+vB,IAI1B7e,GAAAC,EAAMF,GAAcnvB,WAGjCiuC,IACY9e,GAAAlR,oBAAoB,SAAUgwB,GACtBA,OAAA,GAIxB7e,GAAiBC,EAAM1nB,GACzB,EAGEsiB,EAAA3iB,UAAU,CAAC,aAAcF,GAAS8mC,EAAK9mC,EAAKO,YAC5CsiB,EAAAzjB,GAAG,WAAW,IAAM0nC,EAAK9mC,EAAKzB,MAAMgC,YACpCsiB,EAAAzjB,GAAG,aAAa,KAEKynC,IAAA,MAAA9e,IAAAA,GAAelR,oBAAoB,SAAUgwB,IAC9CA,OAAA,CAAA,GACvB,EClB0ChkB,IACrC,MAAA7iB,EAAO6iB,EAAIxkB,OAAO,UACxB,IACI0oC,EADAte,EAsEG,GAnEP5F,EAAI3iB,UAAU,CAAC,aAAcF,IACrB,MAAAtN,EAAU8V,OAAKrP,IAAuC,iBAAlB6G,EAAK8D,SAAwB9D,EAAK8D,SAAW,CAAI,GAEjF,MAAAijC,GAAAA,IACN/mC,EAAK8D,WACP2kB,EAsCN,SACEue,EACAj8C,EACAk8C,EACAC,WAEM,MAAAze,EAAuBjgB,EAAK,CAAA,EAAAw+B,GAU3B,OATPve,EAAMN,QAAU7iC,SAAS8vB,cAA2BrqB,EAAKo9B,SACzDM,EAAML,UAAY9iC,SAAS8vB,cAA2BrqB,EAAKq9B,WAC3DK,EAAMJ,UAAY/iC,SAAS8vB,cAA2BrqB,EAAKs9B,WAC3DI,EAAMH,YAAchjC,SAAS8vB,cAA2BrqB,EAAKu9B,aAC7DG,EAAMF,YAAcx9B,EAAKw9B,YACzBE,EAAMwe,cAAgBA,EACtBxe,EAAMye,gBAAkBA,EAClB,OAAA3pC,EAAAkrB,EAAAN,UAAS5qB,EAAAuZ,iBAAiB,QAASmwB,GACnC,OAAA/8B,EAAAue,EAAAL,YAAWle,EAAA4M,iBAAiB,QAASowB,GACpCze,CACT,CAvDc0e,CAAY1e,EAAO/1B,EAASu0C,EAAeC,GACzCH,EAAA,IAAOte,EAgEvB,SAAoBA,WAGlB,OAFAA,EAAMwe,gBAAiB,OAAA1pC,EAAMkrB,EAAAN,UAAS5qB,EAAAsZ,oBAAoB,QAAS4R,EAAMwe,gBACzExe,EAAMye,kBAAmB,OAAAh9B,EAAMue,EAAAL,YAAWle,EAAA2M,oBAAoB,QAAS4R,EAAMye,kBALtE,EAOT,CApE+B9kC,CAAWqmB,GACtC,IAGE5F,EAAAzjB,GAAG,aAAa,KACR,MAAA2nC,GAAAA,IACNlkB,EAAAxjB,IAAI,eAAgB+nC,EAAkB,IAGxCvkB,EAAAzjB,GAAG,eAAgBgoC,GAGvB,IAAIC,EAAa,EACR,SAAAD,GAAmB//B,KAAEA,IACvBrH,EAAKzB,MAAMuF,UA0CpB,SAAkB2kB,GAChB,OAAOA,EAAMN,SAAWM,EAAML,WAAaK,EAAMJ,WAAaI,EAAMH,WACtE,CA5CiCgf,CAAS7e,IAAWphB,IAE7CggC,IAAehgC,EAAK0G,KAAKb,IAE3Bm6B,EAAahgC,EAAK0G,KAAKb,GACNsb,GAAAC,EAAOphB,EAAK0G,KAAKolB,QAAS9rB,EAAK0G,KAAKkrB,WAAW,GAAO,GAsG7E,SAAyBxQ,EAAsBO,EAAgBC,GACrDA,EAAAC,MACLzZ,QAAQ,OAAQuZ,GAChB5d,MAAK,EAAG/D,WACUmhB,GAAAC,EAAOphB,EAAKqhB,GAAIrhB,EAAKshB,KAAMthB,EAAK8hB,MAAO9hB,EAAK+hB,QAAO,IAErE3d,OAAOvhB,IACEX,QAAAD,MAAM,mBAAoBY,EAAG,GAE3C,CA9GMq9C,CAAgB9e,EAAO4e,EAAYxkB,EAAIliB,WAGvC6nB,GAAiBC,EAAOphB,EAAK0G,KAAKolB,QAAS9rB,EAAK0G,KAAKkrB,WAEzD,CAGA,MAAMuO,EAAiB,WAAO,MAAA,CAC5B/e,QACAO,QAAQ,OAAAzrB,EAAIslB,EAAA/hB,UAAUqjB,oBAAWjX,KAAM,EACvC+b,QAASpG,EAAIliB,SAAO,EAEhBsmC,EAAgBle,GAAe,KAAMye,GACrCN,EAAkBne,GAAe,OAAQye,EAAc,G4D7ElDC,GAAuC,IAAA//B,IAAI,IAAIw9B,KAK/CwC,OAAgDC,QAEvC,SAAAC,GAAMC,EAA0BhlB,GAAc,OAAAp5B,EAAAC,KAAA,MAAA,kBAC5D,MAAAo+C,MAAapgC,IACbqgC,EAAeznB,IACXA,EAAAxoB,SAASg2B,IACO,mBAAXA,IACPga,EAAOppC,IAAIovB,KACfA,EAAOjL,EAAK6kB,GAAcnpC,IAAIuvB,IAC9Bga,EAAOjgC,IAAIimB,IAAM,GAClB,EAIHia,EAAYN,IAGZ,MAAMpgC,KAAEA,SAAewb,EACpBliB,SACAX,KAAKA,OACLyL,OAAOvhB,IAEA,KC5B+C,EAAC24B,EAAK93B,EAAO,YAChE,MAAAoJ,EAAO0uB,EAAIxkB,OAAO,QAClB4H,EAAO4c,EAAIxkB,OAAO,QAClB2B,EAAO6iB,EAAIxkB,OAAO,UAElBnU,EAAMa,EAAKb,IACjB,IAAKA,EAAW,MAAA,IAAIsU,MAAM,iCAE1B,IAAIwpC,EAAkB,GAGlB,GAAA,OAAAzqC,EAAArT,EAAImd,WAAJ,EAAA9J,EAAU0qC,YAAa,CACzB,MAAMC,EAAgB,CACpBC,YAAanoC,EAAKzB,MAAMgF,KACxB6kC,YAAa,GAAGjiD,OAAOC,SAASyE,aAAa1E,OAAOC,SAASiiD,QAE/DL,EAAkB,SAAS5+B,KAAKC,UAAU6+B,IAC5C,CAEgB9lB,GAAA,CACdO,KAAMxuB,EAAKuL,QACX4iB,OAAQp4B,EAAI8X,KAAOzP,OAAOrI,GAC1B28B,QAAS38B,EAAImd,KACbkb,QAAS,WAAM,OAAA,OAAAhlB,EAAAxS,EAAKu9C,cAAL,EAAA/qC,EAAA9J,KAAA1I,EAAA,EACf03B,cAAexc,EAAKnF,UAAUgd,SAC1B,IACE+E,EAAIxgB,YAAY,CACdoiC,KAAMuD,SAEV,GACL,EDHcO,CAAA1lB,EAAK,CAAE34B,MAAKo+C,QAAS,IAAMV,GAAMC,EAAWhlB,KACjD34B,CAAA,IAIN,IAAA8V,EAAsBkL,OACrB28B,GADqB,CAExBviC,WAAY,OAAA/H,EAAK8J,EAAArU,cAAS,EAAAuK,EAAAvK,UAG5B,MAAMw1C,E1GCD,SAA8BxoC,GACnC,MAAMyoC,EAAiC,CACrC,KACA,UACA,YACA,SACA,OACA,OACA,UACA,kBACA,YAiBK,OAfP50C,OAAOgE,KAAKmI,GAAMlI,SAASm2B,IACrBwa,EAAazwB,SAASiW,WAAkBjuB,EAAKiuB,GACvC,aAANA,GAAgC,SAAZjuB,EAAKiuB,WAAsBjuB,EAAKiuB,EAAC,IAIvDjuB,EAAK6D,WAAuC,iBAAnB7D,EAAK6D,YAC3B7D,EAAA6D,UAAY7D,EAAK6D,UAAUre,OAC5Bwa,EAAK6D,UAAU6kC,WAAW,MAAQ1oC,EAAK6D,UAAU6kC,WAAW,KAC9D1oC,EAAK6D,UAAYuF,KAAK5L,MAAMwC,EAAK6D,WACL,UAAnB7D,EAAK6D,YACd7D,EAAK6D,WAAY,IAId7D,CACT,C0G7BqB2oC,CAAqBthC,EAAKuhC,eAAiB,CAAE,GACzD5oC,EAAAA,EAAKiF,iBAAmBtC,GAAU3C,EAAMwoC,GAAc7lC,GAAU6lC,EAAYxoC,GAGnF6iB,EAAI9iB,WAAWC,GAGfA,EAAKuF,mBAaP,SAAkCsjC,EAAmBC,GAA6C,OAAAr/C,EAAAC,KAAA,MAAA,YAC1F,MAAAq/C,MAAqBrhC,IAC3B,IAAKmhC,IAAYv1C,MAAM4P,QAAQ2lC,GAAiB,OAAAE,EAEhD,MAAMC,EAAyB,GAmCxB,OAjCCH,EAAA/wC,SAASpN,IAEV,qBAAqBsL,KAAKtL,KACvBA,EAAA,GAAGo+C,EAAQviD,QAAQ,MAAO,OAAOmE,EAAInE,QAAQ,MAAO,OAEtDyiD,EAAAhyC,KACJ,IAAIwZ,SAAeC,IAEjB,GAAInrB,SAAS8vB,cAAc,eAAe1qB,OAExC,gBAII,MAAAu+C,EAAS3jD,SAASH,cAAc,UACtC8jD,EAAO5rC,IAAM3S,EACJpF,SAAA4jD,KAAKxzB,YAAYuzB,GACnBA,EAAAhf,OAAS,IAAMxZ,IACfw4B,EAAAE,QAAWj/C,IACRX,QAAAD,MAAM,iCAAkCY,OACxC,IAEX,UAICsmB,QAAQ6H,IAAI2wB,GAGXn1C,OAAAglB,OAAO1yB,OAAOijD,eAAiB,CAAA,GAAItxC,SAASg2B,IAC3B,mBAAXA,GAAuBib,EAAelhC,IAAIimB,EAAM,IAGtDib,CACT,GAAA,CApDWM,CAAmBrpC,EAAKuF,WAAYsd,EAAI/iB,UAAU5P,QACtDkb,MAAMkV,IACLynB,EAAYznB,EAAO,IAEpB7U,OAAOvhB,IACEX,QAAAD,MAAM,wBAAyBY,EAAG,IAElD,GAAA,CE1DO,SAASgW,IAAsCrI,KACpDA,EAAAsI,OACAA,EAAAL,QACAA,EAAA6gB,UACAA,IAgBA,IAAI2oB,EAAe,KACnB,MAAMj0C,EAAU,KACd,MAAMk0C,EAVI,MACV,MAAMvpC,EAAOF,IACPsI,EAAW,CAAA,EAIV,OAHFvQ,EAAAC,SAASnG,IACRyW,EAAAzW,GAAOqO,EAAKrO,EAAG,IAEdyW,CAAA,EAIQ5H,GAXC,IAACpH,EAAQ85B,GAYC,MAAXoW,IAZElwC,EAY4BkwC,EAZpBpW,EAY6BqW,IAZlBngC,KAAKC,UAAUjQ,KAAOgQ,KAAKC,UAAU6pB,QAe7DoW,EAAAC,EACVppC,EAAOopC,GACT,MAEUnqC,GAAG,UAAW/J,OACd+J,GAAG,UAAW/J,EAC5B,CCZA,MAAqBm0C,GAGnB,WAAAzrC,CAAYiC,GAFL/B,EAAAvU,KAAA,OAIC,MAAA+W,E7GuDH,SAAmBT,GACpB,IAAAS,EACA,GAAmB,iBAAZT,EAAKvZ,GAAiB,CAC/B,MAAMA,EAAKnB,SAAS8vB,cAA2BpV,EAAKvZ,IAChD,IAACA,EAAU,MAAA,IAAI+X,MAAM,YAAYwB,EAAKvZ,kBAClCga,EAAAha,CAAA,KAAA,MACCuZ,EAAKvZ,cAAcywB,aAGtB,MAAA,IAAI1Y,MAAM,kDAFhBiC,EAAQT,EAAKvZ,EAGf,CACO,OAAAga,CACT,C6GnEkBgpC,CAAUzpC,GAClBS,EAAAwU,UAAUpN,IAAI,UACpBpH,EAAMlb,UAAY,GACD,GAAjBya,EAAKO,UAAoBE,EAAMwU,UAAUpN,IAAI,iBAG7C,MAAMgb,EAAOn5B,KAAKm5B,IAAM,IAAI/kB,GAAQ2C,GC9BG,CAACoiB,IAC1CA,EAAI5jB,QAAQ,UAAU,IAAM,IAAI6hB,IAA+B,EDkC3D4oB,CAAc7mB,GEjCuB,CAACA,IAC1C,IAAI7iB,EAAeyF,GAAiB,CAAC,GAAG,GAEpCod,EAAA5jB,QACF,UACC8hB,IACC,IAAI4oB,GAAU,EAiBP7sC,OAhBPikB,EAAO3hB,GAAG,WAAW,IAAOuqC,GAAU,IACN,CAC9BzpC,UAAW,CAACrI,EAAMsI,KACND,GAAA,CACRrI,OACAsI,SACAL,QAAS,IAAME,EACf2gB,UAAW,IAAMI,GAClB,EAEHxiB,IAAK,IAAMyB,EACXC,OAASslC,IACPvlC,EAAO2C,GAAkB3C,EAAMyF,GAAiB8/B,GAAQ,IAC7CoE,GAAA5oB,EAAOxhB,QAAQ,UAAWS,EAAI,EAGtClD,GAET,CAAC,UAAQ,EFWP8sC,CAAc/mB,GAIhBA,EAAI9iB,WAAWC,GAGf6iB,EAAItjB,QAAQ,WAGQ,MAAY9V,EAAAC,KAAA,MAAA,kBACxBk+C,GAAM5nC,EAAM6iB,GAGlBA,EAAItjB,QAAQ,UAAS,GAAA,IAQzB,CAGO,OAAAO,GACE,OAAApW,KAAKm5B,IAAI/iB,SAClB,CAGO,KAAAJ,GACE,OAAAhW,KAAKm5B,IAAInjB,OAClB,CAGO,MAAAO,CAAOD,GACPtW,KAAAm5B,IAAI9iB,WAAWC,EACtB,CAGO,MAAAkB,GACLxX,KAAKm5B,IAAI3hB,QACX,CAGO,OAAAvB,GACLjW,KAAKm5B,IAAIljB,SACX,CAGO,EAAAP,CAAoCrZ,EAASsP,GAC7C3L,KAAAm5B,IAAIzjB,GAAGrZ,EAAMsP,EACpB,CAGO,GAAAgK,CAAqCtZ,EAASsP,GAC9C3L,KAAAm5B,IAAIxjB,IAAItZ,EAAMsP,EACrB,CAGO,OAAAkK,CAAyCxZ,EAASuZ,GAClD5V,KAAAm5B,IAAItjB,QAAQxZ,EAAMuZ,EACzB,CAGO,WAAAgB,CAAYC,GACZ7W,KAAAm5B,IAAIviB,YAAYC,EACvB,CAOA,WAAcwP,CAAK/P,GACV,OAAA,IAAIwpC,GAAOxpC,EACpB,CAGA,UAAc6pC,CAAa/b,EAAyBp7B,GAClD+0C,GAAc5/B,IAAIimB,GACJ4Z,GAAA1oC,IAAI8uB,EAAQp7B,EAC5B,CAGA,sBAAco3C,CAAgBj2B,GACtB,MAAA7T,EAAOyF,GAAiBoO,GAAG,GAEZrN,GAAA,CACnB7F,OAAQ,IAAM,IAAImQ,GAAI9K,GAAkBhG,IACxCmG,SAAUnG,EAAKuD,KACfW,QAASlE,EAAKkE,QACdC,KAAMnE,EAAKmE,KACX6D,YAAahI,EAAKoE,gBAClBe,OAAO,GAEX,CAMA,SAAW1E,GAET,OADAlX,QAAQo+B,KAAK,uDACNj+B,KAAKgW,OACd,CAGA,QAAWM,GAET,OADAzW,QAAQo+B,KAAK,wDACNj+B,KAAKoW,SACd,EG1IK,MAAMiQ,GAAOy5B,GAAOz5B,KACd85B,GAAML,GAAOK,IACbC,GAAkBN,GAAOM","x_google_ignoreList":[5,6,7,8,9,10,11,12,13,14,16]}