{"version":3,"file":"index.min.cjs","sources":["../src/string-util.ts","../src/misc-util.ts","../src/browser-util.ts","../src/browser-graphics-util.ts","../src/index.ts"],"sourcesContent":["let notLetterPattern: RegExp;\nlet allUpperPattern: RegExp;\nlet wordPattern: RegExp;\nlet digitPattern: RegExp;\n\ntry {\n  // I want these regexes to fail if not supported, so it takes a bit of obfuscation\n  // to prevent Babel from transforming them into something that doesn't fail.\n  const u = String.fromCharCode(117);\n  'm&m'.split(new RegExp('(?<!4)[^\\\\' + 'p{L}]+', u));\n  // This line reached if Unicode character classes and lookbehind both work.\n  notLetterPattern = new RegExp('\\\\' + 'P{L}', 'g' + u);\n  digitPattern = new RegExp('^\\\\' + 'p{Nd}$', u);\n  allUpperPattern = new RegExp('^\\\\' + 'p{Lu}+$', u);\n  wordPattern = new RegExp(String.raw`(?<=^|[^\\p{L}])['’ʼ]?[` + '\\\\' + String.raw`p{L}'’ʼ\\u0300-\\u036F]+['’ʼ]?(?=[^\\p{L}]|$)`, 'g' + u);\n}\ncatch /* istanbul ignore next */ {\n  notLetterPattern = /[A-ZÀ-ÖØ-ÿ]/ig;\n  digitPattern = /^\\d$/;\n  allUpperPattern = /^[A-ZÀ-ÖØ-Þ]+$/;\n  wordPattern = /['’ʼ]?\\b[A-Za-zÀ-ÖØ-ÿ'’ʼ\\u0300-\\u036F]+\\b['’ʼ]?/g;\n}\n\nexport function asLines(s: string, trimFinalBlankLines = false, trimEachLine = false): string[] {\n  if (s) {\n    let lines = s.split(/\\r\\n|\\r|\\n/);\n\n    if (trimFinalBlankLines)\n      while (lines[lines.length - 1] === '')\n        lines.pop();\n\n    if (trimEachLine)\n      lines = lines.map(line => line.trim());\n\n    return lines;\n  }\n  else\n    return [];\n}\n\nexport function compareCaseInsensitive(a: string, b: string): number {\n  a = a.toLowerCase();\n  b = b.toLowerCase();\n\n  return (a < b ? -1 : (a > b ? 1 : 0));\n}\n\nexport function compareCaseSecondary(a: string, b: string): number {\n  const a1 = a.toLowerCase();\n  const b1 = b.toLowerCase();\n  const result = (a1 < b1 ? -1 : (a1 > b1 ? 1 : 0));\n\n  if (result !== 0)\n    return result;\n\n  return (a < b ? -1 : (a > b ? 1 : 0));\n}\n\nexport function compareStrings(a: string, b: string): number {\n  return (a < b ? -1 : (a > b ? 1 : 0));\n}\n\nexport function extendDelimited(base: string, newItem: string, delimiter = ', '): string {\n  if (!base)\n    return newItem;\n  else\n    return base + delimiter + newItem;\n}\n\n/* cspell:disable */ // noinspection SpellCheckingInspection\nconst diacriticals = '\\u00C0\\u00C1\\u00C2\\u00C3\\u00C4\\u00C5\\u00C7\\u00C8\\u00C9\\u00CA\\u00CB\\u00CC' +\n                     '\\u00CD\\u00CE\\u00CF\\u00D1\\u00D2\\u00D3\\u00D4\\u00D5\\u00D6\\u00D8\\u00D9\\u00DA' +\n                     '\\u00DB\\u00DC\\u00DD\\u00E0\\u00E1\\u00E2\\u00E3\\u00E4\\u00E5\\u00E7\\u00E8\\u00E9' +\n                     '\\u00EA\\u00EB\\u00EC\\u00ED\\u00EE\\u00EF\\u00F1\\u00F2\\u00F3\\u00F4\\u00F5\\u00F6' +\n                     '\\u00F8\\u00F9\\u00FA\\u00FB\\u00FC\\u00FD\\u00FF' +\n                     '\\u00AD\\u00B4\\u00B7\\u2022' + // soft hyphen, acute accent, middle dot, bullet\n                     '\\u2010\\u2011\\u2012\\u2013' + // hyphen, no-break hyphen, figure dash, en dash\n                     '\\u2018\\u2019\\u201A\\u201B' + // left single quote, right single quote, single low-9 quote, single high reversed-9 single quote\n                     '\\u201C\\u201D\\u201F\\u201C' + // left double quote, right double quote, double low-9 quote, double high reversed-9 single quote\n                     '\\u2024\\u2027\\u2032\\u2033' + // One dot leader, hyphenation point, prime, double prime\n                     '\\u2039\\u203A\\u2044';        // left single angle quote, right single angle quote, fraction slash\n// noinspection SpellCheckingInspection\nconst plainChars = 'AAAAAACEEEEI' +\n                   'IIINOOOOOOUU' +\n                   'UUYaaaaaacee' +\n                   'eeiiiinooooo' +\n                   'ouuuuyy' +\n                   \"-'**\" +\n                   '----' +\n                   \"''''\" +\n                   '\"\"\"\"' +\n                   `.-'\"` +\n                   '<>/';\nconst latinExtendedASubstitutions = 'AaAaAaCcCcCcCcDdDdEeEeEeEeEeGgGgGgGgHhHhIiIiIiIiIi--JjKkkLlLlLlL' +\n                                    'lLlNnNnNnn--OoOoOo--RrRrRrSsSsSsSsTtTtTtUuUuUuUuUuUuWwYyYZzZzZzs';\n/* cspell:enable */\n\nexport function makePlainASCII(s: string, forFileName = false): string {\n  if (!s)\n    return s;\n\n  let needsWork = false;\n\n  for (let i = 0; i < s.length && !needsWork; ++i) {\n    const cc = s.charCodeAt(i);\n    const ch = s.charAt(i);\n\n    if (cc < 32 || cc > 126 ||\n        (forFileName && (ch === '\"' || ch === '[' || ch === ']' || ch === '*' ||\n                         ch === '/' || ch === ':' || ch === ';' || ch === '<' ||\n                         ch === '>' || ch === '?' || ch === '\\\\' || ch === '|' ||\n                         (i === 0 && ch === '.'))))\n      needsWork = true;\n  }\n\n  if (!needsWork)\n    return s;\n\n  const sb: string[] = [];\n  const allUpper = (s === s.toUpperCase());\n\n  for (let i = 0; i < s.length; ++i) {\n    let ch = s.charAt(i);\n    let pos: number;\n    let ch2;\n\n    /* eslint-disable @stylistic/no-multi-spaces */\n    if (forFileName) {\n      if      (ch === '\"')\n        ch = \"'\";\n      else if (ch === '[')\n        ch = '(';\n      else if (ch === ']')\n        ch = ')';\n      else if (ch === '*')\n        ch = '-';\n      else if (ch === '/' || ch === ':' || ch === ';' || ch === '<' ||\n               ch === '>' || ch === '?' || ch === '\\\\' || ch === '|' ||\n               (i === 0 && ch === '.'))\n        ch = '_';\n    }\n\n    const cc = ch.charCodeAt(0);\n\n    if (32 <= cc && cc <= 126) {} // Do nothing\n    else if (cc === 0xC6) // Latin capital letter AE\n      ch2 = 'Ae';\n    else if (cc === 0xD0) // Latin capital letter Eth\n      ch2 = 'Dh';\n    else if (cc === 0xDE) // Latin capital letter Thorn\n      ch2 = 'Th';\n    else if (cc === 0xDF) // Latin small letter sharp s\n      ch2 = 'ss';\n    else if (cc === 0xE6) // Latin small letter ae\n      ch2 = 'ae';\n    else if (cc === 0xF0) // Latin capital letter eth\n      ch2 = 'dh';\n    else if (cc === 0xFE) // Latin small letter thorn\n      ch2 = 'th';\n    else if (cc === 0xA9 && !forFileName) // Copyright\n      ch2 = '(c)';\n    else if (cc === 0xAB && !forFileName) // Left-pointing double angle quotation\n      ch2 = '<<';\n    else if (cc === 0xAE && !forFileName) // Registered sign\n      ch2 = '(R)';\n    else if (cc === 0xB1 && !forFileName) // plus-minus sign\n      ch2 = '+/-';\n    else if (cc === 0xBB && !forFileName) // Right-pointing double angle quotation\n      ch2 = '>>';\n    else if (cc === 0x0132) // Latin capital ligature IJ\n      ch2 = 'Ij';\n    else if (cc === 0x0133) // Latin small ligature ij\n      ch2 = 'ij';\n    else if (cc === 0x014A) // Latin capital letter Eng\n      ch2 = 'Ng';\n    else if (cc === 0x014B) // Latin small letter eng\n      ch2 = 'ng';\n    else if (cc === 0x0152) // Latin capital ligature OE\n      ch2 = 'Oe';\n    else if (cc === 0x0153) // Latin small ligature oe\n      ch2 = 'oe';\n    else if (0x100 <= cc && cc <= 0x17F) // Various Latin Extended A\n      ch = latinExtendedASubstitutions.charAt(cc - 0x100);\n    else if ((cc === 0x2014 || cc === 0x2015) && !forFileName) // em dash, horizontal bar\n      ch2 = '--';\n    else if (cc === 0x2026 && !forFileName) // ellipsis\n      ch2 = '...';\n    else if ((pos = diacriticals.indexOf(ch)) >= 0)\n      ch  = plainChars.charAt(pos);\n    else if (0x0300 <= cc && cc <= 0x036F)\n      ch2 = ''; // Omit combining diacritical marks\n    else\n      ch  = '_';\n    /* eslint-enable @stylistic/no-multi-spaces */\n\n    if (ch2 === undefined)\n      sb.push(ch);\n    else {\n      if (allUpper)\n        ch2 = ch2.toUpperCase();\n\n      sb.push(ch2);\n    }\n  }\n\n  return sb.join('');\n}\n\nexport function makePlainASCII_lc(s: string, forFileName = false): string {\n  if (s)\n    return makePlainASCII(s, forFileName).toLowerCase();\n  else\n    return s;\n}\n\nexport function makePlainASCII_UC(s: string, forFileName = false): string {\n  if (s)\n    return makePlainASCII(s, forFileName).toUpperCase();\n  else\n    return s;\n}\n\nfunction capitalizeFirstLetter(s: string): string {\n  if (s.length > 1 && /^['’ʼ]/.test(s))\n    return s.charAt(0) + s.charAt(1).toUpperCase() + s.substring(2).toLowerCase();\n  else\n    return s.charAt(0).toUpperCase() + s.substring(1).toLowerCase();\n}\n\nfunction toCanonicalLowercase(s: string): string {\n  return s.toLowerCase().replace(/['’ʼ]/g, \"'\");\n}\n\nexport function isAllUppercase(s: string): boolean {\n  return !!s && allUpperPattern.test(s);\n}\n\nexport function isAllUppercaseWords(s: string): boolean {\n  return !!s && allUpperPattern.test(s.replace(notLetterPattern, ''));\n}\n\nexport function toMixedCase(s: string): string {\n  return s.replace(wordPattern, word => capitalizeFirstLetter(word));\n}\n\nconst defaultShortSmalls = new Set(['a', 'an', 'and', 'as', 'at', 'but', 'by', 'de', 'del', 'for', 'for', 'from',\n  'in', 'into', 'la', 'le', 'near', 'nor', 'of', 'on', 'onto', 'or', 'the', 'to', 'with']);\nconst specialsRaw = ['eBay', 'FedEx', 'iCloud', 'iMac', 'iOS', 'iPad', 'iPhone', 'MacBook', 'macOS', 'PepsiCo', 'watchOS'];\nconst defaultSpecials = new Map<string, string>();\n\nspecialsRaw.forEach(word => defaultSpecials.set(toCanonicalLowercase(word), word));\n\nexport interface TitleCaseOptions {\n  keepAllCaps?: boolean;\n  shortSmall?: string[];\n  special?: string[];\n}\n\nexport function toTitleCase(s: string, options?: TitleCaseOptions): string {\n  options = options ?? {};\n\n  let shortSmalls = defaultShortSmalls;\n  let specials = defaultSpecials;\n  const firstNonSpaceIndex = (/^\\s*/.exec(s)!)[0]?.length;\n  const lastNonSpaceIndex = s.length - ((/\\s*$/.exec(s)!)[0]?.length || 0);\n\n  if (options.shortSmall) {\n    shortSmalls = new Set(shortSmalls);\n    options.shortSmall.forEach(word => {\n      if (word.startsWith('-'))\n        shortSmalls.delete(word.substring(1));\n      else\n        shortSmalls.add(word);\n    });\n  }\n\n  if (options.special) {\n    specials = new Map(specials);\n    options.special.forEach(word => {\n      const lcWord = toCanonicalLowercase(word);\n\n      if (word.startsWith('-'))\n        specials.delete(lcWord.substring(1));\n      else\n        specials.set(lcWord, word);\n    });\n  }\n\n  const wordHandler = (word: string, offset: number): string => {\n    if (options?.keepAllCaps && isAllUppercase(word))\n      return word;\n\n    const lcWord = toCanonicalLowercase(word);\n\n    if (specials.has(lcWord))\n      return specials.get(lcWord) as string;\n\n    word = capitalizeFirstLetter(word);\n\n    const atStartOrEnd = (offset === firstNonSpaceIndex || offset === lastNonSpaceIndex - word.length);\n\n    if (!atStartOrEnd && shortSmalls.has(lcWord))\n      word = word.toLowerCase(); // Turn to lowercase again to keep original apostrophe forms.\n\n    return word;\n  };\n\n  return s.replace(wordPattern, wordHandler);\n}\n\nexport function padLeft(item: number, length: number, padChar?: string): string;\n/**\n * @deprecated String.padStart() now available.\n */\nexport function padLeft(item: string, length: number, padChar?: string): string;\nexport function padLeft(item: string | number, length: number, padChar = ' '): string {\n  let sign = '';\n\n  if (!/^\\s$/.test(padChar) && typeof item === 'number' && item < 0 && padChar === '0') {\n    sign = '-';\n    item = -item;\n    --length;\n  }\n\n  let result = String(item);\n\n  while (result.length < length)\n    result = padChar + result;\n\n  return sign + result;\n}\n\n/**\n * @deprecated String.padEnd() now available.\n */\nexport function padRight(item: string, length: number, padChar?: string): string {\n  if (!padChar)\n    padChar = ' ';\n\n  while (item.length < length)\n    item += padChar;\n\n  return item;\n}\n\nexport function replace(str: string, searchStr: string, replaceStr: string, caseInsensitive = false): string {\n  // escape regexp special characters in search string\n  searchStr = regexEscape(searchStr);\n\n  return str.replace(new RegExp(searchStr, 'g' + (caseInsensitive ? 'i' : '')), replaceStr);\n}\n\nexport function stripLatinDiacriticals(s: string): string {\n  if (!s)\n    return s;\n\n  let needsWork = false;\n\n  for (let i = 0; i < s.length && !needsWork; ++i) {\n    if (s.charCodeAt(i) >= 0xC0)\n      needsWork = true;\n  }\n\n  if (!needsWork)\n    return s;\n\n  const sb: string[] = [];\n\n  for (let i = 0; i < s.length; ++i) {\n    const cc = s.charCodeAt(i);\n    const ch = s.charAt(i);\n    let ch2;\n    let pos: number;\n\n    if (cc < 0xC0) {} // Do nothing\n    else if (0x100 <= cc && cc <= 0x17F) // Various Latin Extended A\n      ch2 = latinExtendedASubstitutions.charAt(cc - 0x100);\n    else if ((pos = diacriticals.indexOf(ch)) >= 0) {\n      ch2 = plainChars.charAt(pos);\n\n      if (!/[a-z]/i.test(ch2))\n        ch2 = undefined;\n    }\n    else if (0x0300 <= cc && cc <= 0x036F)\n      continue; // Omit combining diacritical marks\n\n    if (ch2)\n      sb.push(ch2);\n    else\n      sb.push(ch);\n  }\n\n  return sb.join('');\n}\n\nexport function stripLatinDiacriticals_lc(s: string): string {\n  if (s)\n    return stripLatinDiacriticals(s).toLowerCase();\n  else\n    return s;\n}\n\nexport function stripLatinDiacriticals_UC(s: string): string {\n  if (s)\n    return stripLatinDiacriticals(s).toUpperCase();\n  else\n    return s;\n}\n\nexport function stripDiacriticals(s: string): string {\n  if (s)\n    return s.normalize('NFD').replace(/[\\u0300-\\u036F\\u1AB0-\\u1AFF\\u1DC0-\\u1DFF]/g, '').replace(/Ø/g, 'O').replace(/ø/g, 'o');\n  else\n    return s;\n}\n\nexport function stripDiacriticals_lc(s: string): string {\n  if (s)\n    return stripDiacriticals(s).toLowerCase();\n  else\n    return s;\n}\n\nexport function stripDiacriticals_UC(s: string): string {\n  if (s)\n    return stripDiacriticals(s).toUpperCase();\n  else\n    return s;\n}\n\nexport function zeroPad(n: number | string, digits: number): string {\n  const s = n.toString();\n\n  return '0'.repeat(Math.max(0, digits - s.length)) + s;\n}\n\n// The \\ escape before the second [ is considered unnecessary here by ESLint,\n// but being left out is an error for some regex parsers.\nconst charsNeedingRegexEscape = /[-\\[\\]/{}()*+?.\\\\^$|]/g;\n\nexport function regexEscape(s: string): string {\n  return s.replace(charsNeedingRegexEscape, '\\\\$&');\n}\n\nconst digitSystems: [number, string][] = [\n  [0x0660, 'Arabic'],\n  [0x06F0, 'Extended Arabic'],\n  [0x07C0, \"N'Ko\"],\n  [0x0966, 'Devanagari'],\n  [0x09E6, 'Bengali'],\n  [0x0A66, 'Gurmukhi'],\n  [0x0AE6, 'Gujarati'],\n  [0x0B66, 'Oriya'],\n  [0x0BE6, 'Tamil'],\n  [0x0C66, 'Telugu'],\n  [0x0CE6, 'Kannada'],\n  [0x0D66, 'Malayalam'],\n  [0x0DE6, 'Sinhala Lith'],\n  [0x0E50, 'Thai'],\n  [0x0ED0, 'Lao'],\n  [0x0F20, 'Tibetan'],\n  [0x1040, 'Myanmar'],\n  [0x1090, 'Myanmar Shan'],\n  [0x17E0, 'Khmer'],\n  [0x1810, 'Mongolian'],\n  [0x1946, 'Limbu'],\n  [0x19D0, 'New Tai Lue'],\n  [0x1A80, 'Tai Tham Hora'],\n  [0x1A90, 'Tai Tham Tham'],\n  [0x1B50, 'Balinese'],\n  [0x1BB0, 'Sundanese'],\n  [0x1C40, 'Lepcha'],\n  [0x1C50, 'Ol Chiki'],\n  [0xA620, 'Vai'],\n  [0xA8D0, 'Saurashtra'],\n  [0xA900, 'Kayah Li'],\n  [0xA9D0, 'Javanese'],\n  [0xA9F0, 'Myanmar Tai Laing'],\n  [0xAA50, 'Cham'],\n  [0xABF0, 'Meetei Mayek'],\n];\n\nconst digitValues: Record<string, string> = {};\nconst digitBases: Record<string, string> = {};\nconst digitScripts: Record<string, string> = {};\n\nfor (const [base, script] of digitSystems) {\n  const zero = String.fromCodePoint(base);\n\n  for (let i = 0; i <= 9; ++i) {\n    const digit = String.fromCodePoint(base + i);\n\n    digitValues[digit] = String.fromCodePoint(0x30 + i);\n    digitBases[digit] = zero;\n    digitScripts[digit] = script;\n  }\n}\n\nexport function convertDigitsToAscii(n: string, info?: string[]): string {\n  let base = '0';\n  let script = 'ASCII';\n\n  const result = n.replace(/./g, match => {\n    if (digitValues[match]) {\n      base = digitBases[match];\n      script = digitScripts[match];\n\n      return digitValues[match];\n    }\n\n    return match;\n  });\n\n  if (info) {\n    info[0] = base;\n    info[1] = script;\n  }\n\n  return result;\n}\n\nexport function convertDigits(n: string, baseDigit: string): string {\n  const base: string[] = [];\n  const latn = convertDigitsToAscii(n, base);\n\n  if (base[0] !== baseDigit) {\n    const delta = baseDigit.charCodeAt(0) - 48;\n\n    n = latn.replace(/\\d/g, ch => String.fromCodePoint(ch.charCodeAt(0) + delta));\n  }\n\n  return n;\n}\n\nexport function isDigit(ch: string): boolean {\n  ch = ch?.charAt(0);\n\n  return digitPattern.test(ch) || !!digitValues[ch];\n}\n\nexport function digitScript(ch: string | null | undefined): string | undefined {\n  ch = ch?.charAt(0);\n\n  return digitScripts[ch ?? ''] || (/^\\d$/.test(ch ?? '') ? 'ASCII' : undefined);\n}\n\nexport function toMaxFixed(n: number, maximumFractionDigits: number, locale?: string, useGrouping = false): string {\n  return new Intl.NumberFormat(locale || 'en-US', { maximumFractionDigits, useGrouping }).format(n);\n}\n\nexport function toMaxSignificant(n: number, maximumSignificantDigits: number, locale?: string | null, useGrouping = false): string {\n  return new Intl.NumberFormat(locale || 'en-US', { maximumSignificantDigits, useGrouping }).format(n);\n}\n\nexport function checksum53(s: string, seed = 0): string {\n  let h1 = 0xDEADBEEF ^ seed;\n  let h2 = 0x41C6CE57 ^ seed;\n\n  s = s.normalize();\n\n  for (let i = 0, ch: number; i < s.length; ++i) {\n    ch = s.charCodeAt(i);\n    h1 = Math.imul(h1 ^ ch, 2654435761);\n    h2 = Math.imul(h2 ^ ch, 1597334677);\n  }\n\n  h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507) ^ Math.imul(h2 ^ (h2 >>> 13), 3266489909);\n  h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507) ^ Math.imul(h1 ^ (h1 >>> 13), 3266489909);\n\n  return (4294967296 * (2097151 & h2) + (h1 >>> 0)).toString(16).toUpperCase().padStart(14, '0');\n}\n","import { asLines, compareStrings, zeroPad } from './string-util';\n\nexport interface IsEqualOptions {\n  compare?: (a: any, b: any, key?: string | symbol) => boolean | undefined;\n  keysToIgnore?: Set<string | symbol> | string[];\n  mustBeSameClass?: boolean;\n}\n\n/* istanbul ignore next */\nexport function processMillis(): number {\n  if (typeof performance !== 'undefined')\n    return performance.now();\n  else if (typeof process !== 'undefined') {\n    if ((process.hrtime as any).bigint)\n      return Number((process.hrtime as any).bigint()) / 1000000;\n    else {\n      const time = process.hrtime();\n\n      return time[0] * 1000 + time[1] / 1000000;\n    }\n  }\n  else\n    return Date.now();\n}\n\nexport function sleep(ms: number): Promise<void> {\n  return new Promise(resolve => setTimeout(resolve, ms));\n}\n\nexport enum DateTimeOptions { DATE_ONLY, NO_SECONDS, NO_ZONE, TIME_ONLY, UTC, USE_T, USE_Z, WITH_MILLIS }\n\nexport function formatDateTime(options?: DateTimeOptions[]): string;\nexport function formatDateTime(date: Date | number | string, ...options: DateTimeOptions[]): string;\nexport function formatDateTime(date: Date | number | string, options?: DateTimeOptions[]): string;\nexport function formatDateTime(dateOrOptions: Date | number | string | DateTimeOptions[] | null | undefined, finalArg?: any): string {\n  let date: Date | undefined;\n  let dateOnly = false;\n  let timeOnly = false;\n  let noSeconds = false;\n  let noZone = false;\n  let utc = false;\n  let useT = false;\n  let useZ = false;\n  let withMillis = false;\n  let options: DateTimeOptions[] | undefined;\n\n  if (Array.isArray(dateOrOptions))\n    options = dateOrOptions;\n  else if (arguments.length > 1 && isNumber(finalArg))\n    options = Array.from(arguments).slice(1);\n  else if (isArray(finalArg))\n    options = finalArg;\n\n  if (typeof dateOrOptions === 'number' || typeof dateOrOptions === 'string')\n    date = new Date(dateOrOptions);\n\n  date = date ?? new Date();\n\n  if (options) {\n    options.forEach(option => {\n      switch (option) {\n        case DateTimeOptions.DATE_ONLY: dateOnly = true; break;\n        case DateTimeOptions.NO_SECONDS: noSeconds = true; withMillis = false; break;\n        case DateTimeOptions.NO_ZONE: noZone = true; break;\n        case DateTimeOptions.TIME_ONLY: timeOnly = true; break;\n        case DateTimeOptions.UTC: utc = true; break;\n        case DateTimeOptions.USE_T: useT = true; break;\n        case DateTimeOptions.USE_Z: useZ = true; utc = true; break;\n        case DateTimeOptions.WITH_MILLIS: withMillis = true; noSeconds = false; break;\n      }\n    });\n  }\n\n  const y = zeroPad(utc ? date.getUTCFullYear() : date.getFullYear(), 4);\n  const M = zeroPad(utc ? date.getUTCMonth() + 1 : date.getMonth() + 1, 2);\n  const d = zeroPad(utc ? date.getUTCDate() : date.getDate(), 2);\n  const dateStr = `${y}-${M}-${d}`;\n\n  if (dateOnly)\n    return dateStr;\n\n  const h = zeroPad(utc ? date.getUTCHours() : date.getHours(), 2);\n  const t = (useT ? 'T' : ' ');\n  const m = zeroPad(utc ? date.getMinutes() : date.getUTCMinutes(), 2);\n  const s = ':' + zeroPad(utc ? date.getUTCSeconds() : date.getSeconds(), 2);\n  const x = '.' + zeroPad(utc ? date.getUTCMilliseconds() : date.getMilliseconds(), 3);\n  const zoneMinutes = utc ? 0 : date.getTimezoneOffset();\n  const z = useZ ? 'Z' :\n    ' ' + (zoneMinutes > 0 ? '-' : '+') + zeroPad(Math.floor(Math.abs(zoneMinutes) / 60), 2) + zeroPad(Math.floor(Math.abs(zoneMinutes) % 60), 2);\n  let timeStr = `${h}:${m}`;\n\n  if (!noSeconds)\n    timeStr += s;\n\n  if (withMillis)\n    timeStr += x;\n\n  if (!noZone)\n    timeStr += z;\n\n  if (timeOnly)\n    return timeStr;\n  else\n    return dateStr + t + timeStr;\n}\n\nexport function numSort(a: any, b: any): number {\n  return toNumber(a) - toNumber(b);\n}\n\nexport function reverseNumSort(a: any, b: any): number {\n  return toNumber(b) - toNumber(a);\n}\n\nexport function toDefaultLocaleFixed(n: number, minFracDigits?: number, maxFracDigits?: number): string {\n  const options: any = {};\n\n  if (minFracDigits !== undefined)\n    options.minimumFractionDigits = minFracDigits;\n\n  if (maxFracDigits !== undefined)\n    options.maximumFractionDigits = maxFracDigits;\n\n  return n.toLocaleString(undefined, options);\n}\n\nexport function toBoolean(value: any, defaultValue?: boolean, forHtmlAttribute?: boolean): boolean;\nexport function toBoolean(value: any, defaultValue: null, forHtmlAttribute?: boolean): boolean | null;\nexport function toBoolean<T>(value: any, defaultValue: boolean | T = false, forHtmlAttribute = false): boolean | T {\n  if (typeof value === 'boolean')\n    return value;\n  else if (value == null)\n    return defaultValue;\n  else if (typeof value === 'number')\n    return isNaN(value) ? defaultValue : value !== 0;\n  else if (typeof value !== 'string')\n    return !!value;\n  else if (forHtmlAttribute && value === '')\n    return true;\n  else if (/^(true|t|yes|y)$/i.test(value) || (defaultValue && value === ''))\n    return true;\n  else if (/^(false|f|no|n)$/i.test(value))\n    return false;\n\n  const n = Number(value);\n\n  return isNaN(n) ? defaultValue : n !== 0;\n}\n\nconst digitMatchers: RegExp[] = [];\n\nfor (let radix = 2; radix <= 36; ++radix) {\n  if (radix <= 10)\n    digitMatchers[radix] = new RegExp('^[-+]?[0-' + (radix - 1) + ']+$');\n  else\n    digitMatchers[radix] = new RegExp('^[-+]?[0-9A-' + String.fromCharCode(54 + radix) + ']+$', 'i');\n}\n\nexport function toInt(value: any, defaultValue?: number, radix?: number): number;\nexport function toInt(value: any, defaultValue: null, radix?: number): number | null;\nexport function toInt<T>(value: any, defaultValue: number | T = 0, radix = 10): number | T {\n  if (typeof value === 'number')\n    return isNaN(value) || !isFinite(value) ? defaultValue : Math.floor(value);\n  else if (typeof value === 'string') {\n    const matcher = digitMatchers[radix];\n\n    // Let's be stricter than parseInt and allow only signs and valid base digits.\n    if (!matcher || !matcher.test(value))\n      return defaultValue;\n\n    const result = parseInt(value, radix);\n\n    if (isNaN(result) || !isFinite(result))\n      return defaultValue;\n    else\n      return result;\n  }\n  else if (typeof value === 'bigint') {\n    const result = Number(value);\n\n    if (isNaN(result) || !isFinite(result))\n      return defaultValue;\n    else\n      return result;\n  }\n  else\n    return defaultValue;\n}\n\nexport function toValidInt(value: any, defaultValue = 0, radix = 10): number {\n  if (typeof value === 'number' && (isNaN(value) || !isFinite(value)))\n    return defaultValue;\n  else\n    return toInt(value, defaultValue, radix);\n}\n\nexport function toNumber(value: any, defaultValue?: number): number;\nexport function toNumber(value: any, defaultValue: null): number | null;\nexport function toNumber<T>(value: any, defaultValue: number | T | undefined = 0): number | T {\n  if (typeof value === 'number')\n    return value;\n  else if (typeof value === 'string') {\n    const result = parseFloat(value);\n\n    if (isNaN(result) || !isFinite(result))\n      return defaultValue;\n    else\n      return result;\n  }\n  else if (typeof value === 'bigint') {\n    const result = Number(value);\n\n    if (!isFinite(result))\n      return defaultValue;\n    else\n      return result;\n  }\n  else\n    return defaultValue;\n}\n\nexport function toValidNumber(value: any, defaultValue = 0): number {\n  if (typeof value === 'number' && (isNaN(value) || !isFinite(value)))\n    return defaultValue;\n  else\n    return toNumber(value, defaultValue);\n}\n\nexport function first<T>(array: ArrayLike<T> | null | undefined, defaultValue?: T): T | undefined {\n  if (isArrayLike(array) && array.length > 0)\n    return array[0];\n  else\n    return defaultValue;\n}\n\nexport function nth<T>(array: ArrayLike<T> | null | undefined, n: number, defaultValue?: T): T | undefined {\n  if (isArrayLike(array) && array.length + (n < 0 ? 1 : 0) > Math.abs(n))\n    return n < 0 ? array[array.length + n] : array[n];\n  else\n    return defaultValue;\n}\n\nexport function last<T>(array: ArrayLike<T> | null | undefined, defaultValue?: T): T | undefined {\n  if (isArrayLike(array) && array.length > 0)\n    return array[array.length - 1];\n  else\n    return defaultValue;\n}\n\nexport function push<T>(array: T[] | null | undefined, ...items: any[]): T[] {\n  if (!array)\n    array = [];\n\n  array.push(...items);\n  return array;\n}\n\nexport function pushIf<T>(condition: boolean, array: T[] | null | undefined, ...items: any[]): T[] {\n  if (!array)\n    array = [];\n\n  if (condition)\n    array.push(...items);\n\n  return array;\n}\n\nexport function forEach<T>(obj: Record<string, T> | null | undefined, callback: (key: string, value: T) => void): void {\n  Object.keys(isObject(obj) ? obj : {}).forEach(key => callback(key, obj![key]));\n}\n\nexport function forEach2<T>(obj: Record<string | symbol, T> | null | undefined, callback: (key: string | symbol, value: T) => void): void {\n  Reflect.ownKeys(isObject(obj) ? obj : {}).forEach(key => callback(key, obj![key]));\n}\n\nexport function isArray(a: unknown): a is any[] {\n  return Array.isArray(a);\n}\n\nexport function nfe<T>(array: T[]): T[] | null { // Null For Empty\n  if (array && isArray(array) && array.length > 0)\n    return array;\n  else\n    return null;\n}\n\nexport function ufe<T>(array: T[]): T[] | undefined { // Undefined For Empty\n  if (array && isArray(array) && array.length > 0)\n    return array;\n  else\n    return undefined;\n}\n\nexport function getOrSet<T, U>(map: Map<T, U>, key: T, callbackOrValue: U | (() => U)): U {\n  let result = map.get(key);\n\n  if (result === undefined) {\n    if (isFunction(callbackOrValue))\n      result = callbackOrValue();\n    else\n      result = callbackOrValue;\n\n    map.set(key, result);\n  }\n\n  return result;\n}\n\nexport async function getOrSetAsync<T, U>(map: Map<T, U>, key: T, callback: () => Promise<U>): Promise<U> {\n  let result = map.get(key);\n\n  if (result === undefined) {\n    result = await callback();\n    map.set(key, result);\n  }\n\n  return result;\n}\n\nexport function isArrayLike(a: unknown): a is ArrayLike<any> {\n  return Array.isArray(a) || a instanceof Array || (isObject(a) && isNumber((a as any).length) &&\n      (a as any).length >= 0 && (a as any).length <= Number.MAX_SAFE_INTEGER && (a as any).length === Math.floor((a as any).length));\n}\n\nexport function isBigint(a: unknown): a is bigint {\n  return typeof a === 'bigint';\n}\n\nexport function isBoolean(a: unknown): a is boolean {\n  return typeof a === 'boolean';\n}\n\nexport function isFunction(a: unknown): a is Function {\n  return typeof a === 'function';\n}\n\nexport function isNonFunctionObject(a: unknown): a is Exclude<Record<string | symbol, any>, Function> {\n  return !!a && typeof a === 'object';\n}\n\nexport function isNumber(a: unknown): a is number {\n  return typeof a === 'number';\n}\n\nexport function isObject(a: unknown): a is Record<string | symbol, any> {\n  return !!a && (typeof a === 'function' || typeof a === 'object');\n}\n\nexport function isString(a: unknown): a is string {\n  return typeof a === 'string';\n}\n\nexport function isSymbol(a: unknown): a is symbol {\n  return typeof a === 'symbol';\n}\n\nexport function classOf(a: unknown, noClassResult = false): string | null {\n  if (isObject(a))\n    return a.constructor.name;\n  else\n    return noClassResult ? 'no-class:' + typeof a : null;\n}\n\nexport function clone<T>(orig: T, shallow: boolean | Set<any> | ((value: any, depth: number) => boolean) = false): T {\n  return cloneAux(orig, shallow, 0, new WeakMap<any, any>());\n}\n\nfunction cloneAux<T>(orig: T, shallow: boolean | Set<Function> | ((value: any, depth: number) => boolean), depth: number,\n                     hash: WeakMap<any, any>): T {\n  if (isFunction(orig) || !isObject(orig) || (shallow === true && depth > 0))\n    return orig;\n  else if (hash.has(orig))\n    return hash.get(orig);\n  else if (shallow && depth > 0) {\n    if (shallow instanceof Set) {\n      for (const qlass of shallow.values()) {\n        if (orig instanceof qlass)\n          return orig;\n      }\n    }\n    else if (isFunction(shallow) && shallow(orig, depth))\n      return orig;\n  }\n\n  let theClone: any;\n\n  if (orig instanceof Date)\n    theClone = new Date(orig);\n  else if (orig instanceof RegExp)\n    theClone = new RegExp(orig);\n  else if (orig instanceof Map) {\n    theClone = new Map();\n    hash.set(orig, theClone);\n    Array.from(orig.entries()).forEach(entry => theClone.set(entry[0], cloneAux(entry[1], shallow, depth + 1, hash)));\n\n    return theClone;\n  }\n  else if (orig instanceof Set) {\n    theClone = new Set();\n    hash.set(orig, theClone);\n    orig.forEach(item => theClone.add(cloneAux(item, shallow, depth + 1, hash)));\n\n    return theClone;\n  }\n  else if (typeof BigInt64Array !== 'undefined' && orig instanceof BigInt64Array)\n    theClone = new BigInt64Array(orig);\n  else if (typeof BigUint64Array !== 'undefined' && orig instanceof BigUint64Array)\n    theClone = new BigUint64Array(orig);\n  else if (orig instanceof Float32Array)\n    theClone = new Float32Array(orig);\n  else if (orig instanceof Float64Array)\n    theClone = new Float64Array(orig);\n  else if (orig instanceof Int8Array)\n    theClone = new Int8Array(orig);\n  else if (orig instanceof Int16Array)\n    theClone = new Int16Array(orig);\n  else if (orig instanceof Int32Array)\n    theClone = new Int32Array(orig);\n  else if (orig instanceof Uint8Array)\n    theClone = new Uint8Array(orig);\n  else if (orig instanceof Uint16Array)\n    theClone = new Uint16Array(orig);\n  else if (orig instanceof Uint32Array)\n    theClone = new Uint32Array(orig);\n  else if (orig instanceof Uint8ClampedArray)\n    theClone = new Uint8ClampedArray(orig);\n\n  if (theClone) {\n    hash.set(orig, theClone);\n\n    return theClone;\n  }\n\n  const qlass = classOf(orig);\n\n  if (qlass != null && qlass !== 'Array' && qlass !== 'Object') {\n    theClone = Object.create(Object.getPrototypeOf(orig));\n\n    if (isArray(orig))\n      theClone.length = orig.length;\n  }\n  else if (isArray(orig)) {\n    theClone = [];\n    theClone.length = orig.length;\n  }\n  else\n    theClone = {};\n\n  hash.set(orig, theClone);\n\n  const keys = Reflect.ownKeys(orig as any);\n\n  for (const key of keys)\n    theClone[key] = cloneAux((orig as any)[key], shallow, depth + 1, hash);\n\n  return theClone;\n}\n\nexport function isEqual(a: any, b: any, options: boolean | IsEqualOptions = false, key?: string | symbol): boolean {\n  if (isBoolean(options))\n    options = { mustBeSameClass: options };\n\n  if (isArray(options?.keysToIgnore))\n    options.keysToIgnore = new Set(options.keysToIgnore);\n\n  let comp: boolean | undefined;\n\n  if (options.compare && (comp = options.compare(a, b, key)) !== undefined)\n    return comp;\n  else if (key && options.keysToIgnore && options.keysToIgnore.has(key))\n    return true;\n  else if (a === b || Object.is(a, b))\n    return true;\n  else if (typeof a !== typeof b || isArray(a) !== isArray(b) || (isArray(a) && a.length !== b.length))\n    return false;\n  else if (options.mustBeSameClass && (!a.constructor !== !b.constructor || a.constructor !== b.constructor))\n    return false;\n  else if (!isObject(a) || !isObject(b))\n    return false;\n  else {\n    const keys = Reflect.ownKeys(a);\n    const keysB = new Set(Reflect.ownKeys(b));\n\n    for (const key of keys) {\n      keysB.delete(key);\n\n      if (options?.keysToIgnore && options.keysToIgnore.has(key))\n        continue;\n\n      if (!b.hasOwnProperty(key) || !isEqual(a[key], b[key], options, key))\n        return false;\n    }\n\n    if (keysB.size > 0 && options?.keysToIgnore)\n      options.keysToIgnore.forEach(key => keysB.delete(key));\n\n    if (keysB.size > 0)\n      return false;\n  }\n\n  return true;\n}\n\nfunction _flatten(result: any[], source: any[], depth: number): any[] {\n  for (const item of source) {\n    if (depth === 0 || !isArray(item))\n      result.push(item);\n    else\n      _flatten(result, item, depth - 1);\n  }\n\n  return result;\n}\n\nexport function flatten(a: any[]): any[] {\n  return _flatten([], a, 1);\n}\n\nexport function flattenDeep(a: any[]): any[] {\n  return _flatten([], a, Number.MAX_SAFE_INTEGER);\n}\n\nexport type EntrySorter = (a: [string | symbol, any], b: [string | symbol, any]) => number;\nconst defaultSorter: EntrySorter = (a, b) => compareStrings(a[0].toString(), b[0].toString());\n\nexport function sortObjectEntries<T>(obj: T, inPlace?: boolean): T;\nexport function sortObjectEntries<T>(obj: T, sorter?: EntrySorter, inPlace?: boolean): T;\nexport function sortObjectEntries<T>(obj: T, sorterOrInPlace?: boolean | EntrySorter, inPlace = false): T {\n  const sorter = isFunction(sorterOrInPlace) ? sorterOrInPlace : undefined;\n  let result: T = {} as any;\n  // @ts-ignore\n  const entries = Object.entries(obj);\n\n  inPlace = isBoolean(sorterOrInPlace) ? sorterOrInPlace : inPlace;\n  entries.sort(sorter ?? defaultSorter);\n\n  if (inPlace) {\n    // @ts-ignore\n    Object.keys(obj).forEach(key => delete (obj as any)[key]);\n    result = obj;\n  }\n\n  entries.forEach(entry => (result as any)[entry[0]] = entry[1]);\n\n  return result;\n}\n\n/* istanbul ignore next */ // noinspection JSUnusedGlobalSymbols\nexport const noop = (..._args: any[]): void => {};\n\nexport const repeat = (n: number, f: (n?: number) => any): void => { while (n-- > 0) f(n); };\n\nexport function isValidJson(s: string): boolean {\n  try {\n    JSON.parse(s);\n    return true;\n  }\n  catch {}\n\n  return false;\n}\n\nexport function keyCount(obj: any): number {\n  return obj ? Reflect.ownKeys(obj).length : 0;\n}\n\n// Intended to be used as a tag function.\nexport function regex(main: TemplateStringsArray, flags?: string): RegExp {\n  const parts = asLines(main.raw[0], true, true).filter(line => !line.startsWith('//')).map(line => line.replace(/\\s\\/\\/\\s.*$/, ''));\n\n  return new RegExp(parts.join(''), flags);\n}\n\nexport function compareDottedValues(a: string, b: string): number {\n  if ((!a && !b) || a === b)\n    return 0;\n\n  // Lop off strings, starting at any non-numeric, non-dot characters\n  a = a.replace(/[-_]/g, '.').replace(/[^.0-9].*$/, '');\n  b = b.replace(/[-_]/g, '.').replace(/[^.0-9].*$/, '');\n\n  while (a.length > 0 && b.length > 0) {\n    let pos = a.indexOf('.');\n    let na: number;\n    let nb: number;\n\n    if (pos < 0) {\n      na = toInt(a);\n      a = '';\n    }\n    else {\n      na = toInt(a.substring(0, pos));\n      a = a.substring(pos + 1);\n    }\n\n    pos = b.indexOf('.');\n\n    if (pos < 0) {\n      nb = toInt(b);\n      b = '';\n    }\n    else {\n      nb = toInt(b.substring(0, pos));\n      b = b.substring(pos + 1);\n    }\n\n    if (na < nb)\n      return -1;\n    else if (na > nb)\n      return 1;\n  }\n\n  if (!a)\n    return -1;\n  else\n    return 1;\n}\n\nexport type TbuAnyFunction = (...args: any[]) => any;\n\nclass Debouncer<F extends TbuAnyFunction> {\n  private pendingArgs: any;\n  private timer: any;\n  private readonly trailing: boolean;\n\n  constructor(private delay: number, private func: F, private callback?: (result: ReturnType<F>) => void) {\n    this.trailing = delay < 0;\n  }\n\n  debouncer = (...args: Parameters<F>): void => {\n    if (this.timer)\n      clearTimeout(this.timer);\n\n    this.timer = setTimeout(() => {\n      const result = this.func.apply(this, args);\n\n      if (this.callback)\n        this.callback(result);\n    }, this.delay);\n  };\n\n  private callFunc = (args: any) => {\n    const result = this.func.apply(this, args);\n\n    if (this.callback)\n      this.callback(result);\n\n    this.timer = setTimeout(() => {\n      this.timer = undefined;\n\n      if (this.pendingArgs) {\n        args = this.pendingArgs;\n        this.pendingArgs = undefined;\n        this.callFunc(args);\n      }\n    }, Math.abs(this.delay));\n  };\n\n  throttler = (...args: Parameters<F>): void => {\n    if (!this.timer)\n      this.callFunc(args);\n    else if (this.trailing)\n      this.pendingArgs = args;\n  };\n\n  cancel = (): void => {\n    if (this.timer)\n      clearTimeout(this.timer);\n\n    this.timer = undefined;\n  };\n}\n\nexport function debounce<F extends TbuAnyFunction>(delay: number, func: F, callback?: (result: ReturnType<F>) => void):\n    ((...args: Parameters<F>) => void) & { cancel: () => void } {\n  const d = new Debouncer(delay, func, callback);\n\n  (d.debouncer as any).cancel = d.cancel;\n\n  return d.debouncer as any;\n}\n\nexport function throttle<F extends TbuAnyFunction>(delay: number, func: F, callback?: (result: ReturnType<F>) => void):\n    ((...args: Parameters<F>) => void) & { cancel: () => void } {\n  const t = new Debouncer(delay, func, callback);\n\n  (t.throttler as any).cancel = t.cancel;\n\n  return t.throttler as any;\n}\n","// noinspection JSDeprecatedSymbols\n\nimport { forEach, isNumber, toInt, toNumber } from './misc-util';\n\nconst { ceil, floor, max, min } = Math;\n\nlet _navigator = { appVersion: '?', maxTouchPoints: 0, platform: '?', userAgent: '?', vendor: '?' } as Navigator;\n\ntry {\n  if (typeof navigator !== 'undefined')\n    _navigator = navigator;\n}\ncatch {}\n\nlet _window: typeof window | undefined;\n\ntry {\n  if (typeof window !== 'undefined')\n    _window = window;\n}\ncatch {}\n\nexport interface FontMetrics {\n  font: string;\n  lineHeight: number;\n  ascent: number;\n  fullAscent: number;\n  descent: number;\n  leading: number;\n  extraAscent?: number;\n  extraDescent?: number;\n  extraLineHeight?: number;\n}\n\ninterface FsDocument extends Document {\n  mozFullScreenElement?: Element;\n  msFullscreenElement?: Element;\n  msExitFullscreen?: () => void;\n  mozCancelFullScreen?: () => void;\n  webkitExitFullscreen?: () => void;\n  webkitFullscreenElement?: Element;\n}\n\ninterface FsDocumentElement extends HTMLElement {\n  msRequestFullscreen?: () => void;\n  mozRequestFullScreen?: () => void;\n  webkitRequestFullscreen?: () => void;\n}\n\n/* istanbul ignore next */\nexport function beep(frequency = 440, gainValue = 0.025, duration = 100): void {\n  beepPromise(frequency, gainValue, duration).finally();\n}\n\n/* istanbul ignore next */\nexport async function beepPromise(frequency = 440, gainValue = 0.025, duration = 100): Promise<void> {\n  if (!_window)\n    return;\n\n  return new Promise(resolve => {\n    const audioContext = new ((_window as any).AudioContext)() as AudioContext;\n    const oscillator = audioContext.createOscillator();\n    const gain = audioContext.createGain();\n\n    oscillator.type = 'square';\n    oscillator.frequency.value = frequency;\n    oscillator.connect(gain);\n    gain.gain.value = gainValue;\n    gain.connect(audioContext.destination);\n\n    oscillator.start();\n\n    setTimeout(() => {\n      oscillator.stop();\n      oscillator.disconnect();\n      gain.disconnect();\n      // noinspection JSIgnoredPromiseFromCall\n      audioContext.close();\n      resolve();\n    }, duration);\n  });\n}\n\nexport function eventToKey(event: KeyboardEvent): string {\n  let key = event.key;\n\n  if (key === undefined) {\n    // noinspection JSDeprecatedSymbols\n    const charCode = event.charCode;\n\n    if (charCode !== 0 && charCode != null) {\n      key = String.fromCodePoint(charCode);\n    }\n    else {\n      // noinspection JSDeprecatedSymbols\n      const keyCode = event.keyCode || event.which;\n\n      /* eslint-disable @stylistic/no-multi-spaces, */\n      /* istanbul ignore next */\n      switch (keyCode) {\n        case   3: case 13: key = 'Enter'; break;\n        case   8: key = 'Backspace'; break;\n        case   9: key = 'Tab'; break;\n        case  12: key = 'Clear'; break;\n        case  16: key = 'Shift'; break;\n        case  17: key = 'Control'; break;\n        case  18: key = 'Alt'; break;\n        case  19: key = 'Pause'; break;\n        case  20: key = 'CapsLock'; break;\n        case  27: key = 'Escape'; break;\n        case  33: key = 'PageUp'; break;\n        case  34: key = 'PageDown'; break;\n        case  35: key = 'End'; break;\n        case  36: key = 'Home'; break;\n        case  37: key = 'ArrowLeft'; break;\n        case  38: key = 'ArrowUp'; break;\n        case  39: key = 'ArrowRight'; break;\n        case  40: key = 'ArrowDown'; break;\n        case  43: key = '+'; break;\n        case  44: key = 'PrintScreen'; break;\n        case  45: key = 'Insert'; break;\n        case  46: key = 'Delete'; break;\n        case  91: key = 'OS'; break;\n        case  93: key = 'ContextMenu'; break;\n        case 107: key = '+'; break;\n        case 109: key = '-'; break;\n        case 110: key = '.'; break;\n        case 111: key = '/'; break;\n        case 144: key = 'NumLock'; break;\n        case 145: key = 'ScrollLock'; break;\n        case 173: case 181: key = 'AudioVolumeMute'; break;\n        case 174: case 182: key = 'AudioVolumeDown'; break;\n        case 175: case 183: key = 'AudioVolumeUp'; break;\n        case 179: key = 'MediaPlayPause'; break;\n        case 186: key = ';'; break;\n        case 187: key = '='; break;\n        case 188: key = ','; break;\n        case 189: key = '-'; break;\n        case 191: key = '/'; break;\n        case 192: key = '~'; break;\n        case 219: key = '['; break;\n        case 220: key = '\\\\'; break;\n        case 221: key = ']'; break;\n        case 222: key = '\\''; break;\n        case 224: key = 'Meta'; break;\n        /* eslint-enable @stylistic/no-multi-spaces, */\n\n        default:\n          if (112 <= keyCode && keyCode <= 135)\n            key = 'F' + (keyCode - 111);\n          else if (48 <= keyCode && keyCode <= 90)\n            key = String.fromCharCode(keyCode);\n          else if (96 <= keyCode && keyCode <= 105)\n            key = String.fromCharCode(keyCode - 48);\n      }\n    }\n  }\n  else {\n    /* eslint-disable @stylistic/no-multi-spaces, */\n    /* istanbul ignore next */\n    switch (key) {\n      case 'Left':\n      case 'UIKeyInputLeftArrow':  key = 'ArrowLeft'; break;\n      case 'Up':\n      case 'UIKeyInputUpArrow':    key = 'ArrowUp'; break;\n      case 'Right':\n      case 'UIKeyInputRightArrow': key = 'ArrowRight'; break;\n      case 'Down':\n      case 'UIKeyInputDownArrow':  key = 'ArrowDown'; break;\n\n      case 'Add':      key = '+'; break;\n      case 'Subtract': key = '-'; break;\n      case 'Multiply': key = '*'; break;\n      case 'Divide':   key = '/'; break;\n      case 'Decimal':  key = '.'; break;\n\n      case 'Apps':     key = 'ContextMenu'; break;\n      case 'Del ':     key = 'Delete'; break;\n      case 'Esc':      key = 'Escape'; break;\n      case 'Scroll':   key = 'ScrollLock'; break;\n      case 'Spacebar': key = ' '; break;\n      case 'Win':      key = 'Meta'; break;\n      /* eslint-enable @stylistic/no-multi-spaces, */\n    }\n  }\n\n  return key;\n}\n\nexport function getCssValue(element: Element, property: string): string {\n  return document.defaultView!.getComputedStyle(element, null).getPropertyValue(property);\n}\n\nexport function getCssValues(element: Element, properties: string[]): string[] {\n  const styles = document.defaultView!.getComputedStyle(element, null);\n\n  return properties.map(p => styles.getPropertyValue(p));\n}\n\nexport function getCssVariable(name: string): string {\n  return (document.querySelector(':root') as HTMLElement).style.getPropertyValue(name);\n}\n\nexport function setCssVariable(name: string, value: string): void {\n  (document.querySelector(':root') as HTMLElement).style.setProperty(name, value);\n}\n\nexport function getCssRuleValue(element: Element, property: string): string | undefined {\n  return (getCssRuleValues(element, [property]))[0] || undefined;\n}\n\nexport function getCssRuleValues(element: Element, properties: string[]): (string | undefined)[] {\n  const stack: CSSStyleDeclaration[] = [];\n\n  function searchRules(rules: CSSRuleList) {\n    Array.from(rules ?? /* istanbul ignore next */ []).forEach(rule => {\n      if (rule instanceof CSSMediaRule && _window?.matchMedia(rule.conditionText).matches)\n        searchRules(rule.cssRules);\n      else if (rule instanceof CSSSupportsRule) {\n        try {\n          if (CSS.supports(rule.conditionText))\n            searchRules(rule.cssRules);\n        }\n        catch {}\n      }\n      else if (rule instanceof CSSStyleRule) {\n        try {\n          if (element.matches(rule.selectorText))\n            stack.push(rule.style);\n        }\n        catch {}\n      }\n    });\n  }\n\n  Array.from(document.styleSheets ?? /* istanbul ignore next */ [])\n    .forEach(sheet => searchRules(sheet.rules || /* istanbul ignore next */ sheet.cssRules));\n\n  let results: (string | undefined)[] = properties.map(_p => undefined);\n  let last: CSSStyleDeclaration | undefined;\n\n  while ((last = stack.pop())) {\n    const values = properties.map(p => last![p as any]);\n\n    results = results.map((v, i) => v || values[i]);\n  }\n\n  return results;\n}\n\nconst fontStretches: Record<string, string> = {\n  '50%': 'ultra-condensed',\n  '62.5%': 'extra-condensed',\n  '75%': 'condensed',\n  '87.5%': 'semi-condensed',\n  '100%': 'normal',\n  '112.5%': 'semi-expanded',\n  '125%': 'expanded',\n  '150%': 'extra-expanded',\n  '200%': 'ultra-expanded'\n};\n\nexport function getFont(element: Element): string {\n  const style = document.defaultView!.getComputedStyle(element, null);\n  let font = style.getPropertyValue('font');\n\n  /* istanbul ignore next */ // Can't seem to force this situation to arise anymore.\n  if (!font) {\n    const fontStyle = style.getPropertyValue('font-style');\n    const fontVariant = style.getPropertyValue('font-variant');\n    const fontWeight = style.getPropertyValue('font-weight');\n    const fontStretch = fontStretches[style.getPropertyValue('font-stretch')] || '';\n    const fontSize = style.getPropertyValue('font-size');\n    const lineHeight = style.getPropertyValue('line-height');\n    const fontFamily = style.getPropertyValue('font-family');\n\n    font = (\n      fontStyle + ' ' +\n      fontVariant + ' ' +\n      fontWeight + ' ' +\n      fontStretch + ' ' +\n      fontSize + (lineHeight ? ' / ' + lineHeight : '') + ' ' +\n      fontFamily\n    ).replace(/ +/g, ' ').trim();\n  }\n\n  return font;\n}\n\nconst cachedMetrics: { [font: string]: FontMetrics } = {};\n\nexport function getFontMetrics(elementOrFont: Element | string, specificChar?: string): FontMetrics {\n  let font;\n\n  if (typeof elementOrFont === 'string')\n    font = elementOrFont;\n  else\n    font = getFont(elementOrFont);\n\n  let metrics: FontMetrics | false = !specificChar && cachedMetrics[font];\n\n  if (metrics)\n    return metrics;\n\n  let testFont = font;\n  let fontSize = 12;\n  let testFontSize = 12;\n  const fontParts = /(.*?\\b)((?:\\d|\\.)+)(px\\b.*)/.exec(font);\n\n  // Double the font size so there's more pixel detail to scan, then scale down the result afterward.\n  if (fontParts) {\n    fontSize = parseFloat(fontParts[2]);\n    testFontSize = fontSize * 2;\n    testFont = fontParts[1] + testFontSize + fontParts[3];\n  }\n\n  const sampleText1 = 'Eg';\n  const sampleText2 = 'ÅÊ';\n\n  let lineHeight = fontSize * 1.2;\n  const padding = min(50, lineHeight * 1.5);\n  const heightDiv = document.createElement('div');\n\n  heightDiv.style.position = 'absolute';\n  heightDiv.style.opacity = '0';\n  heightDiv.style.font = font;\n  heightDiv.innerHTML = sampleText1 + '<br>' + sampleText1;\n  document.body.appendChild(heightDiv);\n\n  const heightDivHeight = parseFloat(getCssValue(heightDiv, 'height').replace('px', ''));\n\n  if (heightDivHeight >= fontSize * 2)\n    lineHeight = heightDivHeight / 2;\n\n  document.body.removeChild(heightDiv);\n\n  const canvas = ((getFontMetrics as any).canvas || ((getFontMetrics as any).canvas =\n                  document.createElement('canvas'))) as HTMLCanvasElement;\n\n  canvas.width = testFontSize * 2 + padding;\n  canvas.height = testFontSize * 3;\n  canvas.style.opacity = '1';\n\n  const context = canvas.getContext('2d', { willReadFrequently: true }) as CanvasRenderingContext2D;\n  const w = canvas.width, w4 = w * 4, h = canvas.height, baseline = h / 2;\n\n  context.fillStyle = 'white';\n  context.fillRect(-1, -1, w + 2, h + 2);\n  context.fillStyle = 'black';\n  context.font = testFont;\n  context.fillText(sampleText1, padding / 2, baseline);\n\n  let pixels = context.getImageData(0, 0, w, h).data;\n  let i = 0;\n  const len = pixels.length;\n\n  // Finding the ascent uses a normal, forward scanline\n  while (++i < len && pixels[i] > 192) {}\n  let ascent = baseline - floor(i / w4);\n\n  // Finding the descent uses a reverse scanline\n  i = len - 1;\n  while (--i > 0 && pixels[i] > 192) {}\n  let descent = floor(i / w4) - baseline;\n\n  context.fillStyle = 'white';\n  context.fillRect(-1, -1, w + 2, h + 2);\n  context.fillStyle = 'black';\n  context.fillText(sampleText2, padding / 2, baseline);\n  pixels = context.getImageData(0, 0, w, h).data;\n\n  // Find full ascent, including diacriticals.\n  i = 0;\n  while (++i < len && pixels[i] > 192) {}\n  let fullAscent = baseline - floor(i / w4);\n\n  let extraAscent = fullAscent;\n  let extraDescent = descent;\n\n  if (specificChar) {\n    context.fillStyle = 'white';\n    context.fillRect(-1, -1, w + 2, h + 2);\n    context.fillStyle = 'black';\n    context.fillText(specificChar, padding / 2, baseline);\n    pixels = context.getImageData(0, 0, w, h).data;\n\n    // Find ascent of specificChar.\n    i = 0;\n    while (++i < len && pixels[i] > 192) {}\n    extraAscent = max(floor(i / w4) - baseline, fullAscent);\n\n    // Find descent of specificChar.\n    i = len - 1;\n    while (--i > 0 && pixels[i] > 192) {}\n    extraDescent = max(floor(i / w4) - baseline, descent);\n  }\n\n  if (testFontSize > fontSize) {\n    ascent = ceil(ascent / 2);\n    fullAscent = ceil(fullAscent / 2);\n    descent = ceil(descent / 2);\n    extraAscent = ceil(extraAscent / 2);\n    extraDescent = ceil(extraDescent / 2);\n  }\n\n  const leading = lineHeight - fullAscent - descent;\n\n  metrics = { font, lineHeight, ascent, fullAscent, descent, leading };\n\n  if (!specificChar)\n    cachedMetrics[font] = metrics;\n  else {\n    metrics.extraAscent = extraAscent;\n    metrics.extraDescent = extraDescent;\n    metrics.extraLineHeight = max(extraAscent + extraDescent, lineHeight);\n  }\n\n  return metrics;\n}\n\n/* istanbul ignore next */ // Only sometimes called for checking glyphs on Firefox\nfunction changeItalic(font: string): string {\n  if (/\\b(italic|oblique)\\b/.test(font))\n    return font.replace(/\\b(italic|oblique)\\b/, '');\n  else\n    return 'italic ' + font;\n}\n\nexport function doesCharacterGlyphExist(elementOrFont: Element | string, charOrCodePoint: string | number): boolean {\n  if (isNumber(charOrCodePoint))\n    charOrCodePoint = String.fromCodePoint(charOrCodePoint);\n\n  const self: any = doesCharacterGlyphExist;\n  const firefox = isFirefox();\n  const metrics = getFontMetrics(elementOrFont);\n  const PADDING = 8;\n  const size = metrics.lineHeight + PADDING;\n\n  const canvas0 = (self.canvas0 || (self.canvas0 = document.createElement('canvas'))) as HTMLCanvasElement;\n  const canvas1 = (self.canvas1 || (self.canvas1 = document.createElement('canvas'))) as HTMLCanvasElement;\n  const canvas2 = (self.canvas2 || (self.canvas2 =\n    /* istanbul ignore next */ firefox && document.createElement('canvas'))) as HTMLCanvasElement;\n  const canvases = [canvas0, canvas1, canvas2];\n  const pixmaps: any[] = [];\n\n  for (let i = 0; i < (/* istanbul ignore next */ firefox ? 3 : 2); ++i) {\n    const canvas = canvases[i];\n\n    canvas.width = size;\n    canvas.height = size;\n    canvas.style.opacity = '1';\n\n    const context = canvas.getContext('2d', { willReadFrequently: true })!;\n\n    context.fillStyle = 'white';\n    context.fillRect(-1, -1, size + 2, size + 2);\n    context.fillStyle = 'black';\n    // Compare pixels for test character to pixels for known character without a glyph.\n    // For Firefox, which renders missing glyphs all differently, check if a character\n    // looks the same as itself when rendered in italics -- the missing glyph boxes\n    // remain straight when italicized.\n    /* istanbul ignore next */\n    context.font = (i === 1 && firefox ? changeItalic(metrics.font) : metrics.font);\n    /* istanbul ignore next */\n    context.fillText(i === 0 || (firefox && i !== 2) ? charOrCodePoint : '\\uFFFE', 0, metrics.fullAscent);\n\n    pixmaps[i] = context.getImageData(0, 0, size, size).data;\n  }\n\n  for (let i = 0; i < pixmaps[0].length; i += 4) {\n    if (pixmaps[0][i] !== pixmaps[1][i])\n      return true;\n  }\n\n  // Italic font trick doesn't always help with Firefox, so take the extra step of looking for box edges.\n  /* istanbul ignore next */\n  if (firefox) {\n    for (let i = 0; i < pixmaps[0].length; i += 4) {\n      const row = floor(i / 4 / size);\n      const col = floor(i / 4) % size;\n\n      if ((row < 2 || row === metrics.fullAscent - 1 || col < 2) && pixmaps[0][i] !== pixmaps[2][i])\n        return true;\n    }\n  }\n\n  return false;\n}\n\nexport function getTextWidth(items: string | string[], font: string | HTMLElement, fallbackFont?: string): number {\n  const canvas = ((getTextWidth as any).canvas ||\n                  ((getTextWidth as any).canvas = document.createElement('canvas'))) as HTMLCanvasElement;\n  const context = canvas.getContext('2d', { willReadFrequently: true })!;\n  let maxWidth = 0;\n  let elementFont;\n\n  if (typeof font === 'string')\n    elementFont = font;\n  else if (typeof font === 'object')\n    elementFont = getFont(font);\n\n  /* istanbul ignore else */\n  if (elementFont)\n    context.font = elementFont;\n  else if (fallbackFont)\n    context.font = fallbackFont;\n  else\n    context.font = 'normal 12px sans-serif';\n\n  if (!Array.isArray(items))\n    items = [items];\n\n  for (const item of items) {\n    const width = context.measureText(item).width;\n    maxWidth = max(maxWidth, width);\n  }\n\n  return maxWidth;\n}\n\nconst escapeLookup: Record<string, string> = {\n  '<': '&lt;',\n  '>': '&gt;',\n  '&': '&amp;',\n  '\"': '&quot;',\n  \"'\": '&apos;'\n};\n\nconst unescapeLookup: Record<string, string> = {};\nObject.keys(escapeLookup).forEach(key => unescapeLookup[escapeLookup[key]] = key);\n\nexport function htmlEscape(s: string, escapeQuotes = false): string {\n  return s.replace(escapeQuotes ? /[<>&\"']/g : /[<>&]/g, m => escapeLookup[m[0]]);\n}\n\nexport function htmlUnescape(s: string): string {\n  s = s.replace(/&(?:#[xX]?)?[a-zA-Z0-9]+(?:;|$|(?=[^a-fA-F0-9]))/g, entity => {\n    let replacement = unescapeLookup[entity];\n\n    if (!replacement) {\n      let base = 10;\n      let digits: RegExpMatchArray | null | undefined;\n\n      if (/^&#x/i.test(entity)) {\n        base = 16;\n        digits = /^([a-fA-F0-9]+);?/.exec(entity.substr(3));\n      }\n      else if (entity.startsWith('&#'))\n        digits = /^([0-9]+);?/.exec(entity.substr(2));\n\n      if (digits) {\n        const n = toInt(digits[1], -1, base);\n\n        if (0 <= n && n <= 0x10FFFF)\n          replacement = String.fromCodePoint(n);\n      }\n    }\n\n    return replacement ?? entity;\n  });\n\n  return s;\n}\n\nlet _platform: string;\nlet _isMacOS_ish: boolean;\nlet _isMacOS: boolean;\nlet _isSamsung: boolean;\nlet _isWindows: boolean;\nlet _isLinux: boolean;\nlet _isEdge: boolean;\nlet _isChromium: boolean;\nlet _isChromiumEdge: boolean;\nlet _isAndroid: boolean;\nlet _isOpera: boolean;\nlet _isChrome: boolean;\nlet _isChromeOS: boolean;\nlet _isRaspbian: boolean;\nlet _isFirefox: boolean;\nlet _isSafari: boolean;\nlet _isIOS: boolean;\nlet _iosVersion: number;\nlet _isIOS14OrEarlier: boolean;\nlet _isLikelyMobile: boolean;\n\nexport function initPlatformDetection(nav: Navigator = _navigator, win?: Window, smallScreen?: boolean): void {\n  win = win ?? _window;\n  smallScreen = smallScreen ?? !!_window?.matchMedia('only screen and (max-width: 760px)').matches;\n  _platform = nav.platform || (nav as any).userAgentData?.platform || '?';\n  _isMacOS_ish = _platform.startsWith('Mac') || /\\b(Mac OS X|macOS)\\b/i.test(nav.userAgent);\n  _isMacOS = _isMacOS_ish && !/\\bmobile\\b/i.test(nav.userAgent);\n  _isSamsung = /\\bSamsungBrowser\\b|(\\bAndroid\\b[^)]+\\bSM-)/i.test(nav.userAgent);\n  _isWindows = nav.appVersion?.includes('Windows') || _platform.startsWith('Win');\n  _isLinux = _platform.startsWith('Linux') || /\\bLinux\\b/i.test(nav.userAgent);\n  _isEdge = /\\bedge\\b/i.test(nav.userAgent) && _isWindows;\n  _isChromium = !!(win as any)?.chrome;\n  _isChromiumEdge = _isChromium && _isEdge;\n  _isAndroid = nav.userAgent.includes('Android') || _isSamsung;\n  _isOpera = typeof (win as any)?.opr !== 'undefined' || /\\bOPR\\/\\d+\\b/.test(nav.userAgent);\n  _isChrome = nav.vendor === 'Google Inc.' &&\n    ((/\\bChrome\\b/i.test(nav.userAgent) && !_isEdge && !_isSamsung && !_isOpera && !_isChromiumEdge) ||\n      /\\bCriOS\\b/.test(nav.userAgent));\n  _isChromeOS = nav.vendor === 'Google Inc.' && /\\bCrOS\\b/i.test(nav.userAgent);\n  _isRaspbian = nav.userAgent.includes('Raspbian') || _platform.includes('Linux armv');\n  _isFirefox = /firefox/i.test(nav.userAgent) && !/seamonkey/i.test(nav.userAgent);\n  _isSafari = /^((?!chrome|android).)*safari/i.test(nav.userAgent) && !_isEdge;\n  _isIOS = /i(Pad|Pod|Phone)/i.test(_platform) || (_isMacOS_ish && _isSafari && nav.maxTouchPoints > 1);\n  _iosVersion = toNumber((((_isIOS || null) &&\n    /(((iPhone|iPad).+?OS\\s+)|(Version\\/))(\\d+)/i.exec(nav.userAgent)) ?? [])[5]);\n  _isIOS14OrEarlier = _isIOS && _iosVersion <= 14;\n  _isLikelyMobile = _isIOS ||\n    /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini|\\bmobile\\b/i.test(nav.userAgent) || smallScreen;\n}\n\ninitPlatformDetection();\n\nexport function isAndroid(): boolean {\n  return _isAndroid;\n}\n\nexport function isChrome(): boolean {\n  return _isChrome;\n}\n\nexport function isChromeOS(): boolean {\n  return _isChromeOS;\n}\n\nexport function isChromium(): boolean {\n  return _isChromium;\n}\n\nexport function isChromiumEdge(): boolean {\n  return _isChromiumEdge;\n}\n\nexport function isEdge(): boolean {\n  return _isEdge;\n}\n\nexport function isFirefox(): boolean {\n  return _isFirefox;\n}\n\n/**\n * @deprecated will always be false as this code no longer supports IE.\n */\nexport function isIE(): boolean {\n  // return /(?:\\b(MS)?IE\\s+|\\bTrident\\/7\\.0;.*\\s+rv:)(\\d+)/.test(_navigator.userAgent);\n  return false;\n}\n\nexport function isIOS(): boolean {\n  return _isIOS;\n}\n\nexport function isLinux(): boolean {\n  return _isLinux;\n}\n\nexport function iosVersion(): number {\n  return _iosVersion;\n}\n\nexport function isIOS14OrEarlier(): boolean {\n  return _isIOS14OrEarlier;\n}\n\nexport function isLikelyMobile(): boolean {\n  return _isLikelyMobile;\n}\n\nexport function isMacOS(): boolean {\n  return _isMacOS;\n}\n\nexport function isOpera(): boolean {\n  return _isOpera;\n}\n\n/**\n * @deprecated no longer reliably detectable.\n */\nexport function isRaspbian(): boolean {\n  return _isRaspbian;\n}\n\nexport function isSafari(): boolean {\n  return _isSafari;\n}\n\nexport function isSamsung(): boolean {\n  return _isSamsung;\n}\n\nexport function isWindows(): boolean {\n  return _isWindows;\n}\n\nexport function restrictPixelWidth(text: string, font: string | HTMLElement, maxWidth: number, clipString = '\\u2026'): string {\n  let width = getTextWidth(text, font);\n  let takeOffEnd = 1;\n\n  while (width > maxWidth) {\n    text = text.substring(0, text.length - takeOffEnd) + clipString;\n    takeOffEnd = 1 + clipString.length;\n    width = getTextWidth(text, font);\n  }\n\n  return text;\n}\n\n/* istanbul ignore next */\nexport function setFullScreen(full: boolean): void {\n  // noinspection JSIgnoredPromiseFromCall\n  setFullScreenAsync(full, true);\n}\n\n/* istanbul ignore next */\nexport function setFullScreenAsync(full: boolean, throwImmediate = false): Promise<void> {\n  if (full !== isFullScreen())\n    return toggleFullScreenAsync(throwImmediate);\n\n  return Promise.resolve();\n}\n\n/* istanbul ignore next */\nexport function toggleFullScreen(): void {\n  // noinspection JSIgnoredPromiseFromCall\n  toggleFullScreenAsync();\n}\n\n/* istanbul ignore next */\nexport function toggleFullScreenAsync(throwImmediate = false): Promise<void> {\n  const fsDoc = document as FsDocument;\n\n  try {\n    if (!isFullScreen()) {\n      const fsDocElem = document.documentElement as FsDocumentElement;\n\n      if (fsDocElem.requestFullscreen)\n        return fsDocElem.requestFullscreen();\n      else if (fsDocElem.msRequestFullscreen)\n        fsDocElem.msRequestFullscreen();\n      else if (fsDocElem.mozRequestFullScreen)\n        fsDocElem.mozRequestFullScreen();\n      else if (fsDocElem.webkitRequestFullscreen)\n        fsDocElem.webkitRequestFullscreen();\n    }\n    else if (fsDoc.exitFullscreen)\n      return fsDoc.exitFullscreen();\n    else if (fsDoc.msExitFullscreen)\n      fsDoc.msExitFullscreen();\n    else if (fsDoc.mozCancelFullScreen)\n      fsDoc.mozCancelFullScreen();\n    else if (fsDoc.webkitExitFullscreen)\n      fsDoc.webkitExitFullscreen();\n  }\n  catch (e) {\n    if (throwImmediate)\n      throw e;\n\n    return Promise.reject(e instanceof Error ? e : new Error(e));\n  }\n\n  return Promise.resolve();\n}\n\n/* istanbul ignore next */\nexport function isFullScreen(): boolean {\n  const fsDoc = document as FsDocument;\n\n  return !!(fsDoc.fullscreenElement || fsDoc.mozFullScreenElement || fsDoc.webkitFullscreenElement || fsDoc.msFullscreenElement);\n}\n\n/* istanbul ignore next */\nexport function isEffectivelyFullScreen(): boolean {\n  return isFullScreen() ||\n    (!!_window && _window.innerWidth === _window.screen?.width && _window.innerHeight === _window.screen?.height);\n}\n\nexport function encodeForUri(s: string, spaceAsPlus = false): string {\n  s = encodeURIComponent(s).replace(/[!'()*]/g, m => '%' + m.charCodeAt(0).toString(16).toUpperCase());\n\n  return spaceAsPlus ? s.replace(/%20/g, '+') : s;\n}\n\nexport function urlEncodeParams(params: Record<string, string | number | boolean | bigint | null>, spaceAsPlus = false): string {\n  const result: string[] = [];\n\n  forEach(params, (key, value) => {\n    if (value != null)\n      result.push(encodeForUri(key) + '=' + encodeForUri(value.toString(), spaceAsPlus));\n  });\n\n  return result.join('&');\n}\n","/* eslint-disable @stylistic/computed-property-spacing, @stylistic/no-multi-spaces, */\n\nconst { max, min, round } = Math;\n\nexport interface RGBA {\n  r: number;\n  g: number;\n  b: number;\n  alpha: number;\n}\n\nconst colorNameRegex = /^[a-z]+$/i;\nconst rgbaRegex = /^rgba\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*([0-9.]+)\\s*\\)$/;\nconst rgbRegex  = /^rgb\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\)$/;\n\nlet utilContext: CanvasRenderingContext2D;\n\nexport function blendColors(color1: string, color2: string, portion1 = 0.5): string {\n  const c1 = parseColor(color1);\n  const c2 = parseColor(color2);\n  const r1 = c1.r;\n  const g1 = c1.g;\n  const b1 = c1.b;\n  const a1 = c1.alpha;\n  const r2 = c2.r;\n  const g2 = c2.g;\n  const b2 = c2.b;\n  const a2 = c2.alpha;\n  const portion2 = 1 - portion1;\n\n  return colorFromRGB(r1 * portion1 + r2 * portion2,\n                      g1 * portion1 + g2 * portion2,\n                      b1 * portion1 + b2 * portion2,\n                      a1 * portion1 + a2 * portion2);\n}\n\nexport function colorFrom24BitInt(i: number, alpha = 1.0): string {\n  const r = (i & 0xFF0000) >> 16;\n  const g = (i & 0x00FF00) >> 8;\n  const b =  i & 0x0000FF;\n\n  return colorFromRGB(r, g, b, alpha);\n}\n\nexport function colorFromByteArray(array: number[], offset = 0): string {\n  const r = array[offset] || 0;\n  const g = array[offset + 1] || 0;\n  const b = array[offset + 2] || 0;\n  const alpha = (array[offset + 3] ?? 255) / 255;\n\n  return colorFromRGB(r, g, b, alpha);\n}\n\nexport function colorFromRGB(r: number, g: number, b: number, alpha = 1.0): string {\n  r = min(max(round(r), 0), 255);\n  g = min(max(round(g), 0), 255);\n  b = min(max(round(b), 0), 255);\n  const a = min(max(alpha, 0), 1).toFixed(4).replace(/([01]).0000/, '$1').replace(/([^0])0+$/, '$1');\n\n  if (a === '1')\n    return ('#' + r.toString(16).padStart(2, '0')\n                + g.toString(16).padStart(2, '0')\n                + b.toString(16).padStart(2, '0')).toUpperCase();\n  else\n    return `rgba(${r}, ${g}, ${b}, ${a})`;\n}\n\nexport function drawOutlinedText(context: CanvasRenderingContext2D, text: string, x: number, y: number,\n                                 outlineStyle?: string, fillStyle?: string, strokeWidth = 4): void {\n  context.save();\n  context.lineWidth = strokeWidth;\n  context.lineJoin = 'round';\n\n  if (outlineStyle)\n    context.strokeStyle = outlineStyle;\n\n  if (fillStyle)\n    context.fillStyle = fillStyle;\n\n  context.strokeText(text, x, y);\n  context.fillText(text, x, y);\n  context.restore();\n}\n\nexport function fillEllipse(context: CanvasRenderingContext2D, cx: number, cy: number, rx: number, ry: number): void {\n  context.save();\n  context.beginPath();\n\n  context.translate(cx - rx, cy - ry);\n  context.scale(rx, ry);\n  context.arc(1, 1, 1, 0, Math.PI * 2, false);\n\n  context.closePath();\n  context.restore();\n  context.fill();\n}\n\nexport function fillCircle(context: CanvasRenderingContext2D, cx: number, cy: number, r: number): void {\n  fillEllipse(context, cx, cy, r, r);\n}\n\nexport function parseColor(color: string): RGBA {\n  let match = colorNameRegex.exec((color = color.trim()));\n\n  if (match) {\n    if (!utilContext) {\n      const canvas = document.createElement('canvas');\n      utilContext = canvas.getContext('2d', { willReadFrequently: true })!;\n    }\n\n    utilContext.fillStyle = color; // Let the context parse the color name.\n    color = String(utilContext.fillStyle); // Get the same color back in hex/RGB form.\n  }\n\n  if (color.startsWith('#')) {\n    switch (color.length) {\n      case 4:\n      case 5:\n        return {\n          r: parseInt(color.substr(1, 1) + color.substr(1, 1), 16),\n          g: parseInt(color.substr(2, 1) + color.substr(2, 1), 16),\n          b: parseInt(color.substr(3, 1) + color.substr(3, 1), 16),\n          alpha: color.length === 4 ? 1.0 : parseInt(color.substr(4, 1) + color.substr(4, 1), 16) / 255.0\n        };\n\n      case 7:\n      case 9:\n        return {\n          r: parseInt(color.substr(1, 2), 16),\n          g: parseInt(color.substr(3, 2), 16),\n          b: parseInt(color.substr(5, 2), 16),\n          alpha: color.length === 7 ? 1.0 : parseInt(color.substr(7, 2), 16) / 255.0\n        };\n    }\n  }\n\n  match = rgbRegex.exec(color);\n\n  if (match)\n    return { r: Number(match[1]), g: Number(match[2]), b: Number(match[3]), alpha: 1 };\n\n  match = rgbaRegex.exec(color);\n\n  if (match)\n    return { r: Number(match[1]), g: Number(match[2]), b: Number(match[3]), alpha: Number(match[4]) };\n\n  return { r: 0, g: 0, b: 0, alpha: 0 };\n}\n\nexport function replaceAlpha(color: string, newAlpha: number): string {\n  const rgba = parseColor(color);\n\n  return colorFromRGB(rgba.r, rgba.g, rgba.b, newAlpha);\n}\n\nexport function getPixel(imageData: ImageData, x: number, y: number): number {\n  if (x < 0 || y < 0 || x >= imageData.width || y >= imageData.height)\n    return 0;\n\n  const offset = (y * imageData.width + x) * 4;\n\n  return (imageData.data[offset    ] << 16) |\n         (imageData.data[offset + 1] <<  8) |\n          imageData.data[offset + 2]        |\n         (imageData.data[offset + 3] << 24);\n}\n\nexport function setPixel(imageData: ImageData, x: number, y: number, pixel: number): void {\n  if (x < 0 || y < 0 || x >= imageData.width || y >= imageData.height)\n    return;\n\n  const offset = (y * imageData.width + x) * 4;\n\n  imageData.data[offset    ] =  (pixel & 0x00FF0000) >> 16;\n  imageData.data[offset + 1] =  (pixel & 0x0000FF00) >>  8;\n  imageData.data[offset + 2] =   pixel & 0x000000FF;\n  imageData.data[offset + 3] = ((pixel & 0xFF000000) >> 24) & 0xFF;\n}\n\nexport function strokeCircle(context: CanvasRenderingContext2D, cx: number, cy: number, radius: number): void {\n  context.beginPath();\n  context.arc(cx, cy, radius, 0, Math.PI * 2, false);\n  context.stroke();\n  context.closePath();\n}\n\nexport function strokeEllipse(context: CanvasRenderingContext2D, cx: number, cy: number, rx: number, ry: number): void {\n  context.save();\n  context.beginPath();\n\n  context.translate(cx - rx, cy - ry);\n  context.scale(rx, ry);\n  context.arc(1, 1, 1, 0, Math.PI * 2, false);\n\n  context.restore();\n  context.stroke();\n  context.closePath();\n}\n\nexport function strokeLine(context: CanvasRenderingContext2D, x0: number, y0: number, x1: number, y1: number): void {\n  context.beginPath();\n  context.moveTo(x0, y0);\n  context.lineTo(x1, y1);\n  context.stroke();\n  context.closePath();\n}\n","/*\n  Copyright © 2017-2025 Kerry Shetline, kerry@shetline.com\n\n  MIT license: https://opensource.org/licenses/MIT\n\n  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated\n  documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the\n  rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit\n  persons to whom the Software is furnished to do so, subject to the following conditions:\n\n  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the\n  Software.\n\n  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE\n  WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\n  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n  OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n*/\nimport * as browserUtil from './browser-util';\n\n/* eslint-disable @typescript-eslint/no-unused-vars */\n// noinspection JSUnusedGlobalSymbols\nconst { initPlatformDetection, ...publicBrowserUtil } = browserUtil;\n\nexport { publicBrowserUtil };\nexport * from './browser-util';\nexport * from './browser-graphics-util';\nexport * from './misc-util';\nexport * from './string-util';\n\n// Deprecation, schmeprecation. substr forever!\nif (String.prototype.substr == null)\n  String.prototype.substr = function (a: number, b: number): string {\n    return this.substring(a, a + b);\n  };\n"],"names":["notLetterPattern","allUpperPattern","wordPattern","digitPattern","u","String","fromCharCode","split","RegExp","raw","asLines","s","trimFinalBlankLines","trimEachLine","lines","length","pop","map","line","trim","compareStrings","a","b","diacriticals","plainChars","latinExtendedASubstitutions","makePlainASCII","forFileName","needsWork","i","cc","charCodeAt","ch","charAt","sb","allUpper","toUpperCase","pos","ch2","indexOf","undefined","push","join","capitalizeFirstLetter","test","substring","toLowerCase","toCanonicalLowercase","replace","isAllUppercase","defaultShortSmalls","Set","defaultSpecials","Map","stripLatinDiacriticals","stripDiacriticals","normalize","zeroPad","n","digits","toString","repeat","Math","max","forEach","word","set","charsNeedingRegexEscape","regexEscape","digitSystems","digitValues","digitBases","digitScripts","base","script","zero","fromCodePoint","digit","convertDigitsToAscii","info","result","match","DateTimeOptions","digitMatchers","radix","toInt","value","defaultValue","isNaN","isFinite","floor","matcher","parseInt","Number","toNumber","parseFloat","obj","callback","Object","keys","isObject","key","isArray","Array","isArrayLike","isNumber","MAX_SAFE_INTEGER","isBoolean","isFunction","classOf","noClassResult","constructor","name","cloneAux","orig","shallow","depth","hash","has","get","qlass","values","theClone","Date","from","entries","entry","item","add","BigInt64Array","BigUint64Array","Float32Array","Float64Array","Int8Array","Int16Array","Int32Array","Uint8Array","Uint16Array","Uint32Array","Uint8ClampedArray","create","getPrototypeOf","Reflect","ownKeys","_flatten","source","defaultSorter","Debouncer","delay","func","this","debouncer","args","timer","clearTimeout","setTimeout","apply","callFunc","pendingArgs","abs","throttler","trailing","cancel","ceil","min","_window","_navigator","appVersion","maxTouchPoints","platform","userAgent","vendor","navigator","window","beep","frequency","gainValue","duration","beepPromise","finally","async","Promise","resolve","audioContext","oscillator","createOscillator","gain","createGain","type","connect","destination","start","stop","disconnect","close","eventToKey","event","charCode","keyCode","which","getCssValue","element","property","document","defaultView","getComputedStyle","getPropertyValue","getCssValues","properties","styles","p","getCssVariable","querySelector","style","setCssVariable","setProperty","getCssRuleValue","getCssRuleValues","stack","searchRules","rules","rule","CSSMediaRule","matchMedia","conditionText","matches","cssRules","CSSSupportsRule","CSS","supports","CSSStyleRule","selectorText","styleSheets","sheet","last","results","_p","v","fontStretches","getFont","font","fontStyle","fontVariant","fontWeight","fontStretch","fontSize","lineHeight","cachedMetrics","getFontMetrics","elementOrFont","specificChar","metrics","testFont","testFontSize","fontParts","exec","sampleText1","padding","heightDiv","createElement","position","opacity","innerHTML","body","appendChild","heightDivHeight","removeChild","canvas","width","height","context","getContext","willReadFrequently","w","w4","h","baseline","fillStyle","fillRect","fillText","pixels","getImageData","data","len","ascent","descent","fullAscent","extraAscent","extraDescent","leading","extraLineHeight","changeItalic","doesCharacterGlyphExist","charOrCodePoint","self","firefox","isFirefox","size","canvases","canvas0","canvas1","canvas2","pixmaps","row","col","getTextWidth","items","fallbackFont","elementFont","maxWidth","measureText","escapeLookup","unescapeLookup","htmlEscape","escapeQuotes","m","htmlUnescape","entity","replacement","substr","startsWith","_platform","_isMacOS_ish","_isMacOS","_isSamsung","_isWindows","_isLinux","_isEdge","_isChromium","_isChromiumEdge","_isAndroid","_isOpera","_isChrome","_isChromeOS","_isRaspbian","_isFirefox","_isSafari","_isIOS","_iosVersion","_isIOS14OrEarlier","_isLikelyMobile","initPlatformDetection","nav","win","smallScreen","userAgentData","includes","chrome","opr","isAndroid","isChrome","isChromeOS","isChromium","isChromiumEdge","isEdge","isIE","isIOS","isLinux","iosVersion","isIOS14OrEarlier","isLikelyMobile","isMacOS","isOpera","isRaspbian","isSafari","isSamsung","isWindows","restrictPixelWidth","text","clipString","takeOffEnd","setFullScreen","full","setFullScreenAsync","throwImmediate","isFullScreen","toggleFullScreenAsync","toggleFullScreen","fsDoc","exitFullscreen","msExitFullscreen","mozCancelFullScreen","webkitExitFullscreen","fsDocElem","documentElement","requestFullscreen","msRequestFullscreen","mozRequestFullScreen","webkitRequestFullscreen","e","reject","Error","fullscreenElement","mozFullScreenElement","webkitFullscreenElement","msFullscreenElement","isEffectivelyFullScreen","innerWidth","screen","innerHeight","encodeForUri","spaceAsPlus","encodeURIComponent","urlEncodeParams","params","round","colorNameRegex","rgbaRegex","rgbRegex","utilContext","colorFromRGB","r","g","alpha","toFixed","padStart","fillEllipse","cx","cy","rx","ry","save","beginPath","translate","scale","arc","PI","closePath","restore","fill","parseColor","color","publicBrowserUtil","browserUtil","prototype","color1","color2","portion1","c1","c2","r1","g1","b1","a1","portion2","seed","h1","h2","imul","WeakMap","array","offset","na","nb","baseDigit","latn","delta","d","x","y","outlineStyle","strokeWidth","lineWidth","lineJoin","strokeStyle","strokeText","newItem","delimiter","dateOrOptions","finalArg","date","options","dateOnly","timeOnly","noSeconds","noZone","utc","useT","useZ","withMillis","arguments","slice","option","DATE_ONLY","NO_SECONDS","NO_ZONE","TIME_ONLY","UTC","USE_T","USE_Z","WITH_MILLIS","dateStr","getUTCFullYear","getFullYear","getUTCMonth","getMonth","getUTCDate","getDate","getUTCHours","getHours","t","getMinutes","getUTCMinutes","getUTCSeconds","getSeconds","getUTCMilliseconds","getMilliseconds","zoneMinutes","getTimezoneOffset","z","timeStr","callbackOrValue","imageData","isEqual","comp","mustBeSameClass","keysToIgnore","compare","is","keysB","delete","hasOwnProperty","JSON","parse","_args","padChar","sign","performance","now","process","hrtime","bigint","time","condition","main","flags","parts","filter","f","str","searchStr","replaceStr","caseInsensitive","newAlpha","rgba","pixel","ms","sorterOrInPlace","inPlace","sorter","sort","radius","stroke","x0","y0","x1","y1","moveTo","lineTo","forHtmlAttribute","minFracDigits","maxFracDigits","minimumFractionDigits","maximumFractionDigits","toLocaleString","locale","useGrouping","Intl","NumberFormat","format","maximumSignificantDigits","shortSmalls","specials","firstNonSpaceIndex","lastNonSpaceIndex","shortSmall","special","lcWord","keepAllCaps"],"mappings":"aAAA,IAAIA,EACAC,EACAC,EACAC,EAEJ,IAGE,MAAMC,EAAIC,OAAOC,aAAa,KAC9B,MAAMC,MAAM,IAAIC,OAAO,mBAAyBJ,IAEhDJ,EAAmB,IAAIQ,OAAO,SAAe,IAAMJ,GACnDD,EAAe,IAAIK,OAAO,YAAkBJ,GAC5CH,EAAkB,IAAIO,OAAO,aAAmBJ,GAChDF,EAAc,IAAIM,OAAOH,OAAOI,GAAG,yBAA2B,KAAOJ,OAAOI,GAAG,6CAA8C,IAAML,EACpI,CACD,MACEJ,EAAmB,gBACnBG,EAAe,OACfF,EAAkB,iBAClBC,EAAc,kDACf,CAEK,SAAUQ,EAAQC,EAAWC,GAAsB,EAAOC,GAAe,GAC7E,GAAIF,EAAG,CACL,IAAIG,EAAQH,EAAEJ,MAAM,cAEpB,GAAIK,EACF,KAAmC,KAA5BE,EAAMA,EAAMC,OAAS,IAC1BD,EAAME;CAKV,OAHIH,IACFC,EAAQA,EAAMG,IAAIC,GAAQA,EAAKC,SAE1BL,CACR,CAEC,MAAO,EACX,CAoBM,SAAUM,EAAeC,EAAWC,GACxC,OAAQD,EAAIC,GAAI,EAAMD,EAAIC,EAAI,EAAI,CACpC,CAUA,MAAMC,EAAe,iFAYfC,EAAa,sFAWbC,EAA8B,4IAIpBC,EAAef,EAAWgB,GAAc,GACtD,IAAKhB,EACH,OAAOA,EAET,IAAIiB,GAAY,EAEhB,IAAK,IAAIC,EAAI,EAAGA,EAAIlB,EAAEI,SAAWa,IAAaC,EAAG,CAC/C,MAAMC,EAAKnB,EAAEoB,WAAWF,GAClBG,EAAKrB,EAAEsB,OAAOJ;EAEhBC,EAAK,IAAMA,EAAK,KACfH,IAAuB,MAAPK,GAAqB,MAAPA,GAAqB,MAAPA,GAAqB,MAAPA,GACnC,MAAPA,GAAqB,MAAPA,GAAqB,MAAPA,GAAqB,MAAPA,GACnC,MAAPA,GAAqB,MAAPA,GAAqB,OAAPA,GAAsB,MAAPA,GACpC,IAANH,GAAkB,MAAPG,MAC/BJ,GAAY,EACf,CAED,IAAKA,EACH,OAAOjB,EAET,MAAMuB,EAAe,GACfC,EAAYxB,IAAMA,EAAEyB,cAE1B,IAAK,IAAIP,EAAI,EAAGA,EAAIlB,EAAEI,SAAUc,EAAG,CACjC,IACIQ,EACAC,EAFAN,EAAKrB,EAAEsB,OAAOJ,GAKdF,IACc,MAAPK,EACPA,EAAK,IACS,MAAPA,EACPA,EAAK,IACS,MAAPA,EACPA,EAAK,IACS,MAAPA,EACPA,EAAK,KACS,MAAPA,GAAqB,MAAPA,GAAqB,MAAPA,GAAqB,MAAPA,GACnC,MAAPA,GAAqB,MAAPA,GAAqB,OAAPA,GAAsB,MAAPA,GACpC,IAANH,GAAkB,MAAPG,KACnBA,EAAK,MAGT,MAAMF,EAAKE,EAAGD,WAAW;CAErB,IAAMD,GAAMA,GAAM,MACN,MAAPA,EACPQ,EAAM,KACQ,MAAPR,EACPQ,EAAM,KACQ,MAAPR,EACPQ,EAAM,KACQ,MAAPR,EACPQ,EAAM,KACQ,MAAPR,EACPQ,EAAM,KACQ,MAAPR,EACPQ,EAAM,KACQ,MAAPR,EACPQ,EAAM,KACQ,MAAPR,GAAgBH,EAET,MAAPG,GAAgBH,EAET,MAAPG,GAAgBH,EAET,MAAPG,GAAgBH,EAET,MAAPG,GAAgBH,EAET,MAAPG,EACPQ,EAAM,KACQ,MAAPR,EACPQ,EAAM,KACQ,MAAPR,EACPQ,EAAM,KACQ,MAAPR,EACPQ,EAAM,KACQ,MAAPR,EACPQ,EAAM,KACQ,MAAPR,EACPQ,EAAM,KACC,KAASR,GAAMA,GAAM,IAC5BE,EAAKP,EAA4BQ,OAAOH,EAAK,KAC9B,OAAPA,GAAwB,OAAPA,GAAmBH,EAE9B,OAAPG,GAAkBH,GAEjBU,EAAMd,EAAagB,QAAQP,KAAQ,EAC3CA,EAAMR,EAAWS,OAAOI,GACjB,KAAUP,GAAMA,GAAM,IAC7BQ,EAAM,GAENN,EAAM,IANNM,EAAM,MAFNA,EAAM,KAhBNA,EAAM,KAFNA,EAAM,MAFNA,EAAM,MAFNA,EAAM,KAFNA,EAAM,YAmCIE,IAARF,EACFJ,EAAGO,KAAKT,IAEJG,IACFG,EAAMA,EAAIF,eAEZF,EAAGO,KAAKH,GAEX;AAED,OAAOJ,EAAGQ,KAAK,GACjB,CAgBA,SAASC,EAAsBhC,GAC7B,OAAIA,EAAEI,OAAS,GAAK,SAAS6B,KAAKjC,GACzBA,EAAEsB,OAAO,GAAKtB,EAAEsB,OAAO,GAAGG,cAAgBzB,EAAEkC,UAAU,GAAGC,cAEzDnC,EAAEsB,OAAO,GAAGG,cAAgBzB,EAAEkC,UAAU,GAAGC,aACtD,CAEA,SAASC,EAAqBpC,GAC5B,OAAOA,EAAEmC,cAAcE,QAAQ,SAAU,IAC3C,CAEM,SAAUC,EAAetC,GAC7B,QAASA,GAAKV,EAAgB2C,KAAKjC,EACrC,CAUA,MAAMuC,EAAqB,IAAIC,IAAI,CAAC,IAAK,KAAM,MAAO,KAAM,KAAM,MAAO,KAAM,KAAM,MAAO,MAAO,MAAO,OACxG,KAAM,OAAQ,KAAM,KAAM,OAAQ,MAAO,KAAM,KAAM,OAAQ,KAAM,MAAO,KAAM,SAE5EC,EAAkB,IAAIC,IAwGtB,SAAUC,EAAuB3C,GACrC,IAAKA,EACH,OAAOA,EAET,IAAIiB,GAAY;CAEhB,IAAK,IAAIC,EAAI,EAAGA,EAAIlB,EAAEI,SAAWa,IAAaC,EACxClB,EAAEoB,WAAWF,IAAM,MACrBD,GAAY,GAGhB,IAAKA,EACH,OAAOjB,EAET,MAAMuB,EAAe,GAErB,IAAK,IAAIL,EAAI,EAAGA,EAAIlB,EAAEI,SAAUc,EAAG,CACjC,MAAMC,EAAKnB,EAAEoB,WAAWF,GAClBG,EAAKrB,EAAEsB,OAAOJ,GACpB,IAAIS,EACAD,EAEJ,GAAIP,EAAK,UACJ,GAAI,KAASA,GAAMA,GAAM,IAC5BQ,EAAMb,EAA4BQ,OAAOH,EAAK,UAC3C,IAAKO,EAAMd,EAAagB,QAAQP,KAAQ,EAC3CM,EAAMd,EAAWS,OAAOI,GAEnB,SAASO,KAAKN,KACjBA,OAAME,QAEL,GAAI,KAAUV,GAAMA,GAAM,IAC7B,SAEEQ,EACFJ,EAAGO,KAAKH,GAERJ,EAAGO,KAAKT,EACX,CAED,OAAOE,EAAGQ,KAAK,GACjB,CAgBM,SAAUa,EAAkB5C,GAChC,OAAIA,EACKA,EAAE6C,UAAU,OAAOR,QAAQ,6CAA8C,IAAIA,QAAQ,KAAM,KAAKA,QAAQ,KAAM,KAE9GrC,CACX,CAgBM,SAAU8C,EAAQC,EAAoBC;AAC1C,MAAMhD,EAAI+C,EAAEE,WAEZ,MAAO,IAAIC,OAAOC,KAAKC,IAAI,EAAGJ,EAAShD,EAAEI,SAAWJ,CACtD,CA3LoB,CAAC,OAAQ,QAAS,SAAU,OAAQ,MAAO,OAAQ,SAAU,UAAW,QAAS,UAAW,WAGpGqD,QAAQC,GAAQb,EAAgBc,IAAInB,EAAqBkB,GAAOA,IA4L5E,MAAME,EAA0B,yBAE1B,SAAUC,EAAYzD,GAC1B,OAAOA,EAAEqC,QAAQmB,EAAyB,OAC5C;AAEA,MAAME,EAAmC,CACvC,CAAC,KAAQ,UACT,CAAC,KAAQ,mBACT,CAAC,KAAQ,QACT,CAAC,KAAQ,cACT,CAAC,KAAQ,WACT,CAAC,KAAQ,YACT,CAAC,KAAQ,YACT,CAAC,KAAQ,SACT,CAAC,KAAQ,SACT,CAAC,KAAQ,UACT,CAAC,KAAQ,WACT,CAAC,KAAQ,aACT,CAAC,KAAQ,gBACT,CAAC,KAAQ,QACT,CAAC,KAAQ,OACT,CAAC,KAAQ,WACT,CAAC,KAAQ,WACT,CAAC,KAAQ,gBACT,CAAC,KAAQ,SACT,CAAC,KAAQ,aACT,CAAC,KAAQ,SACT,CAAC,KAAQ,eACT,CAAC,KAAQ,iBACT,CAAC,KAAQ,iBACT,CAAC,KAAQ,YACT,CAAC,KAAQ,aACT,CAAC,KAAQ,UACT,CAAC,KAAQ,YACT,CAAC,MAAQ,OACT,CAAC,MAAQ,cACT,CAAC,MAAQ,YACT,CAAC,MAAQ,YACT,CAAC,MAAQ,qBACT,CAAC,MAAQ,QACT,CAAC,MAAQ,iBAGLC,EAAsC,CAAA,EACtCC,EAAqC,CAAA,EACrCC,EAAuC,CAAA;CAE7C,IAAK,MAAOC,EAAMC,KAAWL,EAAc,CACzC,MAAMM,EAAOtE,OAAOuE,cAAcH,GAElC,IAAK,IAAI5C,EAAI,EAAGA,GAAK,IAAKA,EAAG,CAC3B,MAAMgD,EAAQxE,OAAOuE,cAAcH,EAAO5C,GAE1CyC,EAAYO,GAASxE,OAAOuE,cAAc,GAAO/C,GACjD0C,EAAWM,GAASF,EACpBH,EAAaK,GAASH,CACvB,CACF,CAEK,SAAUI,EAAqBpB,EAAWqB,GAC9C,IAAIN,EAAO,IACPC,EAAS,QAEb,MAAMM,EAAStB,EAAEV,QAAQ,KAAMiC,GACzBX,EAAYW,IACdR,EAAOF,EAAWU,GAClBP,EAASF,EAAaS,GAEfX,EAAYW,IAGdA,GAQT,OALIF,IACFA,EAAK,GAAKN,EACVM,EAAK,GAAKL,GAGLM,CACT,CC1eA,IAAYE,EAAAA,QAAAA,qBAAAA,GAAAA,EAAAA,QAAAA,kBAAAA,wBAAe,CAAA,IAAGA,EAAA,UAAA,GAAA,YAAWA,EAAAA,EAAA,WAAA,GAAA,aAAYA,EAAAA,EAAA,QAAA,GAAA,UAASA,EAAAA,EAAA,UAAA,GAAA,YAAWA,EAAAA,EAAA,IAAA,GAAA;AAAKA,EAAAA,EAAA,MAAA,GAAA,QAAOA,EAAAA,EAAA,MAAA,GAAA,QAAOA,EAAAA,EAAA,YAAA,GAAA,cAwH5F,MAAMC,EAA0B,GAEhC,IAAK,IAAIC,EAAQ,EAAGA,GAAS,KAAMA,EAE/BD,EAAcC,GADZA,GAAS,GACY,IAAI5E,OAAO,aAAe4E,EAAQ,GAAK,OAEvC,IAAI5E,OAAO,eAAiBH,OAAOC,aAAa,GAAK8E,GAAS,MAAO,KAK1F,SAAUC,EAASC,EAAYC,EAA2B,EAAGH,EAAQ,IACzE,GAAqB,iBAAVE,EACT,OAAOE,MAAMF,KAAWG,SAASH,GAASC,EAAezB,KAAK4B,MAAMJ,GACjE,GAAqB,iBAAVA,EAAoB,CAClC,MAAMK,EAAUR,EAAcC,GAG9B,IAAKO,IAAYA,EAAQ/C,KAAK0C,GAC5B,OAAOC,EAET,MAAMP,EAASY,SAASN,EAAOF,GAE/B,OAAII,MAAMR,KAAYS,SAAST,GACtBO,EAEAP,CACV,CACI,GAAqB,iBAAVM,EAAoB,CAClC,MAAMN,EAASa,OAAOP,GAEtB,OAAIE,MAAMR,KAAYS,SAAST,GACtBO,EAEAP,CACV,CAEC,OAAOO;AACX,UAWgBO,EAAYR,EAAYC,EAAuC,GAC7E,GAAqB,iBAAVD,EACT,OAAOA,EACJ,GAAqB,iBAAVA,EAAoB,CAClC,MAAMN,EAASe,WAAWT,GAE1B,OAAIE,MAAMR,KAAYS,SAAST,GACtBO,EAEAP,CACV,CACI,GAAqB,iBAAVM,EAAoB,CAClC,MAAMN,EAASa,OAAOP,GAEtB,OAAKG,SAAST,GAGLA,EAFAO,CAGV,CAEC,OAAOA,CACX,CAgDM,SAAUvB,EAAWgC,EAA2CC,GACpEC,OAAOC,KAAKC,EAASJ,GAAOA,EAAM,CAAA,GAAIhC,QAAQqC,GAAOJ,EAASI,EAAKL,EAAKK,IAC1E,CAMM,SAAUC,EAAQjF,GACtB,OAAOkF,MAAMD,QAAQjF,EACvB,CA0CM,SAAUmF,EAAYnF,GAC1B,OAAOkF,MAAMD,QAAQjF,IAAMA,aAAakF,OAAUH,EAAS/E,IAAMoF,EAAUpF,EAAUN,SAChFM,EAAUN,QAAU,GAAMM,EAAUN,QAAU8E,OAAOa,kBAAqBrF,EAAUN,SAAW+C,KAAK4B,MAAOrE,EAAUN,OAC5H,CAMM,SAAU4F,EAAUtF,GACxB,MAAoB,kBAANA,CAChB;AAEM,SAAUuF,EAAWvF,GACzB,MAAoB,mBAANA,CAChB,CAMM,SAAUoF,EAASpF,GACvB,MAAoB,iBAANA,CAChB,CAEM,SAAU+E,EAAS/E,GACvB,QAASA,IAAmB,mBAANA,GAAiC,iBAANA,EACnD,UAUgBwF,EAAQxF,EAAYyF,GAAgB,GAClD,OAAIV,EAAS/E,GACJA,EAAE0F,YAAYC,KAEdF,EAAgB,mBAAqBzF,EAAI,IACpD,CAMA,SAAS4F,EAAYC,EAASC,EAA6EC,EACtFC,GACnB,GAAIT,EAAWM,KAAUd,EAASc,KAAsB,IAAZC,GAAoBC,EAAQ,EACtE,OAAOF,EACJ,GAAIG,EAAKC,IAAIJ,GAChB,OAAOG,EAAKE,IAAIL,GACb,GAAIC,GAAWC,EAAQ,EAC1B,GAAID,aAAmBhE,KACrB,IAAK,MAAMqE,KAASL,EAAQM,SAC1B,GAAIP,aAAgBM,EAClB,OAAON,OAGR,GAAIN,EAAWO,IAAYA,EAAQD,EAAME,GAC5C,OAAOF,EAGX,IAAIQ;CAEJ,GAAIR,aAAgBS,KAClBD,EAAW,IAAIC,KAAKT,QACjB,GAAIA,aAAgB1G,OACvBkH,EAAW,IAAIlH,OAAO0G,OACnB,IAAIA,aAAgB7D,IAKvB,OAJAqE,EAAW,IAAIrE,IACfgE,EAAKnD,IAAIgD,EAAMQ,GACfnB,MAAMqB,KAAKV,EAAKW,WAAW7D,QAAQ8D,GAASJ,EAASxD,IAAI4D,EAAM,GAAIb,EAASa,EAAM,GAAIX,EAASC,EAAQ,EAAGC,KAEnGK,EAEJ,GAAIR,aAAgB/D,IAKvB,OAJAuE,EAAW,IAAIvE,IACfkE,EAAKnD,IAAIgD,EAAMQ,GACfR,EAAKlD,QAAQ+D,GAAQL,EAASM,IAAIf,EAASc,EAAMZ,EAASC,EAAQ,EAAGC,KAE9DK;CAEyB,oBAAlBO,eAAiCf,aAAgBe,cAC/DP,EAAW,IAAIO,cAAcf,GACI,oBAAnBgB,gBAAkChB,aAAgBgB,eAChER,EAAW,IAAIQ,eAAehB,GACvBA,aAAgBiB,aACvBT,EAAW,IAAIS,aAAajB,GACrBA,aAAgBkB,aACvBV,EAAW,IAAIU,aAAalB,GACrBA,aAAgBmB,UACvBX,EAAW,IAAIW,UAAUnB,GAClBA,aAAgBoB,WACvBZ,EAAW,IAAIY,WAAWpB,GACnBA,aAAgBqB,WACvBb,EAAW,IAAIa,WAAWrB,GACnBA,aAAgBsB,WACvBd,EAAW,IAAIc,WAAWtB,GACnBA,aAAgBuB,YACvBf,EAAW,IAAIe,YAAYvB,GACpBA,aAAgBwB,YACvBhB,EAAW,IAAIgB,YAAYxB,GACpBA,aAAgByB,oBACvBjB,EAAW,IAAIiB,kBAAkBzB;AAAK,CAExC,GAAIQ,EAGF,OAFAL,EAAKnD,IAAIgD,EAAMQ,GAERA,EAGT,MAAMF,EAAQX,EAAQK,GAET,MAATM,GAA2B,UAAVA,GAA+B,WAAVA,GACxCE,EAAWxB,OAAO0C,OAAO1C,OAAO2C,eAAe3B,IAE3CZ,EAAQY,KACVQ,EAAS3G,OAASmG,EAAKnG,SAElBuF,EAAQY,IACfQ,EAAW,GACXA,EAAS3G,OAASmG,EAAKnG,QAGvB2G,EAAW,CAAA,EAEbL,EAAKnD,IAAIgD,EAAMQ,GAEf,MAAMvB,EAAO2C,QAAQC,QAAQ7B,GAE7B,IAAK,MAAMb,KAAOF,EAChBuB,EAASrB,GAAOY,EAAUC,EAAab,GAAMc,EAASC,EAAQ,EAAGC,GAEnE,OAAOK,CACT,CA+CA,SAASsB,EAAShE,EAAeiE,EAAe7B,GAC9C,IAAK,MAAMW,KAAQkB,EACH,IAAV7B,GAAgBd,EAAQyB,GAG1BiB,EAAShE,EAAQ+C,EAAMX,EAAQ,GAF/BpC,EAAOvC,KAAKsF,GAKhB,OAAO/C,CACT,CAWA,MAAMkE,EAA6B,CAAC7H,EAAGC,IAAMF,EAAeC,EAAE,GAAGuC,WAAYtC,EAAE,GAAGsC,YAiGlF,MAAMuF,EAKJ,WAAApC,CAAoBqC,EAAuBC,EAAiBpD,GAAxCqD,KAAAF,MAAAA,EAAuBE,KAAAD,KAAAA,EAAiBC,KAAArD,SAAAA,EAI5DqD,KAAAC,UAAY,IAAIC;AACVF,KAAKG,OACPC,aAAaJ,KAAKG,OAEpBH,KAAKG,MAAQE,WAAW,KACtB,MAAM3E,EAASsE,KAAKD,KAAKO,MAAMN,KAAME,GAEjCF,KAAKrD,UACPqD,KAAKrD,SAASjB,IACfsE,KAAKF,QAGFE,KAAAO,SAAYL,IAClB,MAAMxE,EAASsE,KAAKD,KAAKO,MAAMN,KAAME,GAEjCF,KAAKrD,UACPqD,KAAKrD,SAASjB,GAEhBsE,KAAKG,MAAQE,WAAW,KACtBL,KAAKG,WAAQjH,EAET8G,KAAKQ,cACPN,EAAOF,KAAKQ,YACZR,KAAKQ,iBAActH,EACnB8G,KAAKO,SAASL,KAEf1F,KAAKiG,IAAIT,KAAKF,SAGnBE,KAAAU,UAAY,IAAIR,KACTF,KAAKG,MAEDH,KAAKW,WACZX,KAAKQ,YAAcN,GAFnBF,KAAKO,SAASL,IAKlBF,KAAAY,OAAS;AACHZ,KAAKG,OACPC,aAAaJ,KAAKG,OAEpBH,KAAKG,WAAQjH,GA3Cb8G,KAAKW,SAAWb,EAAQ,GC9mB5B,MAAMe,KAAEA,EAAIzE,MAAEA,EAAK3B,IAAEA,EAAGqG,IAAEA,GAAQtG,KAElC,IAQIuG,EARAC,EAAa,CAAEC,WAAY,IAAKC,eAAgB,EAAGC,SAAU,IAAKC,UAAW,IAAKC,OAAQ,KAE9F,IAC2B,oBAAdC,YACTN,EAAaM,UAChB,CACD,MAAM,CAIN,IACwB,oBAAXC,SACTR,EAAUQ,OACb,CACD,MAAM,CA8BA,SAAUC,EAAKC,EAAY,IAAKC,EAAY,KAAOC,EAAW,KAClEC,EAAYH,EAAWC,EAAWC,GAAUE,SAC9C,CAGOC,eAAeF,EAAYH,EAAY,IAAKC,EAAY,KAAOC,EAAW,KAC/E,GAAKZ,EAGL,OAAO,IAAIgB,QAAQC,IACjB,MAAMC,EAAe,IAAMlB,EAA4B,aACjDmB,EAAaD,EAAaE,mBAC1BC,EAAOH,EAAaI,aAE1BH,EAAWI,KAAO;AAClBJ,EAAWT,UAAUzF,MAAQyF,EAC7BS,EAAWK,QAAQH,GACnBA,EAAKA,KAAKpG,MAAQ0F,EAClBU,EAAKG,QAAQN,EAAaO,aAE1BN,EAAWO,QAEXpC,WAAW,KACT6B,EAAWQ,OACXR,EAAWS,aACXP,EAAKO,aAELV,EAAaW,QACbZ,KACCL,IAEP,CAEM,SAAUkB,EAAWC,GACzB,IAAI/F,EAAM+F,EAAM/F,IAEhB,QAAY7D,IAAR6D,EAAmB,CAErB,MAAMgG,EAAWD,EAAMC,SAEvB,GAAiB,IAAbA,GAA8B,MAAZA,EACpBhG,EAAMhG,OAAOuE,cAAcyH,OAExB,CAEH,MAAMC,EAAUF,EAAME,SAAWF,EAAMG,MAIvC,OAAQD,GACN,KAAO,EAAG,KAAK,GAAIjG,EAAM,QAAS,MAClC,KAAO,EAAGA,EAAM,YAAa,MAC7B,KAAO,EAAGA,EAAM,MAAO,MACvB,KAAM,GAAIA,EAAM,QAAS,MACzB,KAAM,GAAIA,EAAM,QAAS,MACzB,KAAM,GAAIA,EAAM,UAAW,MAC3B,KAAM,GAAIA,EAAM,MAAO,MACvB,KAAM,GAAIA,EAAM,QAAS,MACzB,KAAM;AAAIA,EAAM,WAAY,MAC5B,KAAM,GAAIA,EAAM,SAAU,MAC1B,KAAM,GAAIA,EAAM,SAAU,MAC1B,KAAM,GAAIA,EAAM,WAAY,MAC5B,KAAM,GAAIA,EAAM,MAAO,MACvB,KAAM,GAAIA,EAAM,OAAQ,MACxB,KAAM,GAAIA,EAAM,YAAa,MAC7B,KAAM,GAAIA,EAAM,UAAW,MAC3B,KAAM,GAAIA,EAAM,aAAc,MAC9B,KAAM,GAAIA,EAAM,YAAa,MAC7B,KAAM,GAMN,KAAK,IAAKA,EAAM,IAAK,MALrB,KAAM,GAAIA,EAAM,cAAe,MAC/B,KAAM,GAAIA,EAAM,SAAU,MAC1B,KAAM,GAAIA,EAAM,SAAU,MAC1B,KAAM,GAAIA,EAAM,KAAM,MACtB,KAAM,GAAIA,EAAM,cAAe,MAE/B,KAAK,IAYL,KAAK,IAAKA,EAAM,IAAK,MAXrB,KAAK,IAAKA,EAAM,IAAK,MACrB,KAAK,IAWL,KAAK,IAAKA,EAAM,IAAK,MAVrB,KAAK;AAAKA,EAAM,UAAW,MAC3B,KAAK,IAAKA,EAAM,aAAc,MAC9B,KAAK,IAAK,KAAK,IAAKA,EAAM,kBAAmB,MAC7C,KAAK,IAAK,KAAK,IAAKA,EAAM,kBAAmB,MAC7C,KAAK,IAAK,KAAK,IAAKA,EAAM,gBAAiB,MAC3C,KAAK,IAAKA,EAAM,iBAAkB,MAClC,KAAK,IAAKA,EAAM,IAAK,MACrB,KAAK,IAAKA,EAAM,IAAK,MACrB,KAAK,IAAKA,EAAM,IAAK,MAGrB,KAAK,IAAKA,EAAM,IAAK,MACrB,KAAK,IAAKA,EAAM,IAAK,MACrB,KAAK,IAAKA,EAAM,KAAM,MACtB,KAAK,IAAKA,EAAM,IAAK,MACrB,KAAK,IAAKA,EAAM,IAAM,MACtB,KAAK,IAAKA,EAAM,OAAQ,MAGxB;AACM,KAAOiG,GAAWA,GAAW,IAC/BjG,EAAM,KAAOiG,EAAU,KAChB,IAAMA,GAAWA,GAAW,GACnCjG,EAAMhG,OAAOC,aAAagM,GACnB,IAAMA,GAAWA,GAAW,MACnCjG,EAAMhG,OAAOC,aAAagM,EAAU,KAE3C,CACF,MAIC,OAAQjG,GACN,IAAK,OACL,IAAK,sBAAwBA,EAAM,YAAa,MAChD,IAAK,KACL,IAAK,oBAAwBA,EAAM,UAAW,MAC9C,IAAK,QACL,IAAK,uBAAwBA,EAAM,aAAc,MACjD,IAAK,OACL,IAAK,sBAAwBA,EAAM,YAAa,MAEhD,IAAK,MAAYA,EAAM,IAAK,MAC5B,IAAK,WAAYA,EAAM,IAAK,MAC5B,IAAK,WAAYA,EAAM,IAAK,MAC5B,IAAK,SAAYA,EAAM,IAAK,MAC5B,IAAK,UAAYA,EAAM,IAAK,MAE5B,IAAK,OAAYA,EAAM;CAAe,MACtC,IAAK,OAAYA,EAAM,SAAU,MACjC,IAAK,MAAYA,EAAM,SAAU,MACjC,IAAK,SAAYA,EAAM,aAAc,MACrC,IAAK,WAAYA,EAAM,IAAK,MAC5B,IAAK,MAAYA,EAAM,OAK3B,OAAOA,CACT,CAEM,SAAUmG,EAAYC,EAAkBC,GAC5C,OAAOC,SAASC,YAAaC,iBAAiBJ,EAAS,MAAMK,iBAAiBJ,EAChF,CAEM,SAAUK,EAAaN,EAAkBO,GAC7C,MAAMC,EAASN,SAASC,YAAaC,iBAAiBJ,EAAS,MAE/D,OAAOO,EAAW/L,IAAIiM,GAAKD,EAAOH,iBAAiBI,GACrD,CAEM,SAAUC,EAAenG,GAC7B,OAAQ2F,SAASS,cAAc,SAAyBC,MAAMP,iBAAiB9F,EACjF,CAEM,SAAUsG,EAAetG,EAAc1B,GAC1CqH,SAASS,cAAc,SAAyBC,MAAME,YAAYvG,EAAM1B,EAC3E;AAEM,SAAUkI,GAAgBf,EAAkBC,GAChD,OAAQe,GAAiBhB,EAAS,CAACC,IAAY,SAAMlK,CACvD,CAEM,SAAUiL,GAAiBhB,EAAkBO,GACjD,MAAMU,EAA+B,GAErC,SAASC,EAAYC,GACnBrH,MAAMqB,KAAKgG,GAAoC,IAAI5J,QAAQ6J,IACzD,GAAIA,aAAgBC,cAAgBzD,GAAS0D,WAAWF,EAAKG,eAAeC,QAC1EN,EAAYE,EAAKK,eACd,GAAIL,aAAgBM,gBACvB,IACMC,IAAIC,SAASR,EAAKG,gBACpBL,EAAYE,EAAKK,SACpB,CACD,MAAM,MAEH,GAAIL,aAAgBS,aACvB,IACM7B,EAAQwB,QAAQJ,EAAKU,eACvBb,EAAMjL,KAAKoL,EAAKR,MACnB,CACD,MAAM,IAKZ9G,MAAMqB,KAAK+E,SAAS6B,aAA0C,IAC3DxK,QAAQyK,GAASd,EAAYc,EAAMb,OAAoCa,EAAMP,WAEhF,IACIQ,EADAC,EAAkC3B,EAAW/L,IAAI2N,OAGrD,KAAQF,EAAOhB,EAAM1M,OAAQ;AAC3B,MAAMyG,EAASuF,EAAW/L,IAAIiM,GAAKwB,EAAMxB,IAEzCyB,EAAUA,EAAQ1N,IAAI,CAAC4N,EAAGhN,IAAMgN,GAAKpH,EAAO5F,GAC7C,CAED,OAAO8M,CACT,CAEA,MAAMG,GAAwC,CAC5C,MAAO,kBACP,QAAS,kBACT,MAAO,YACP,QAAS,iBACT,OAAQ,SACR,SAAU,gBACV,OAAQ,WACR,OAAQ,iBACR,OAAQ,kBAGJ,SAAUC,GAAQtC,GACtB,MAAMY,EAAQV,SAASC,YAAaC,iBAAiBJ,EAAS,MAC9D,IAAIuC,EAAO3B,EAAMP,iBAAiB,QAGlC,IAAKkC,EAAM;AACT,MAAMC,EAAY5B,EAAMP,iBAAiB,cACnCoC,EAAc7B,EAAMP,iBAAiB,gBACrCqC,EAAa9B,EAAMP,iBAAiB,eACpCsC,EAAcN,GAAczB,EAAMP,iBAAiB,kBAAoB,GACvEuC,EAAWhC,EAAMP,iBAAiB,aAClCwC,EAAajC,EAAMP,iBAAiB,eAG1CkC,GACEC,EAAY,IACZC,EAAc,IACdC,EAAa,IACbC,EAAc,IACdC,GAAYC,EAAa,MAAQA,EAAa,IAAM,IAPnCjC,EAAMP,iBAAiB,gBASxC9J,QAAQ,MAAO,KAAK7B,MACvB,CAED,OAAO6N,CACT,CAEA,MAAMO,GAAiD,CAAA,EAEjD,SAAUC,GAAeC,EAAiCC,GAC9D,IAAIV,EAGFA,EAD2B,iBAAlBS,EACFA,EAEAV,GAAQU,GAEjB,IAAIE,GAAgCD,GAAgBH,GAAcP,GAElE,GAAIW,EACF,OAAOA,EAET,IAAIC,EAAWZ,EACXK,EAAW,GACXQ,EAAe,GACnB,MAAMC,EAAY,8BAA8BC,KAAKf;CAGjDc,IACFT,EAAWtJ,WAAW+J,EAAU,IAChCD,EAA0B,EAAXR,EACfO,EAAWE,EAAU,GAAKD,EAAeC,EAAU,IAGrD,MAAME,EAAc,KAGpB,IAAIV,EAAwB,IAAXD,EACjB,MAAMY,EAAU7F,EAAI,GAAiB,IAAbkF,GAClBY,EAAYvD,SAASwD,cAAc,OAEzCD,EAAU7C,MAAM+C,SAAW,WAC3BF,EAAU7C,MAAMgD,QAAU,IAC1BH,EAAU7C,MAAM2B,KAAOA,EACvBkB,EAAUI,UAAYN,WACtBrD,SAAS4D,KAAKC,YAAYN,GAE1B,MAAMO,EAAkB1K,WAAWyG,EAAY0D,EAAW,UAAUlN,QAAQ,KAAM,KAE9EyN,GAA8B,EAAXpB,IACrBC,EAAamB,EAAkB,GAEjC9D,SAAS4D,KAAKG,YAAYR,GAE1B,MAAMS,EAAWnB,GAAuBmB,SAAYnB,GAAuBmB,OAC3DhE,SAASwD,cAAc,WAEvCQ,EAAOC,MAAuB,EAAff,EAAmBI,EAClCU,EAAOE,OAAwB,EAAfhB,EAChBc,EAAOtD,MAAMgD,QAAU,IAEvB,MAAMS,EAAUH,EAAOI,WAAW,KAAM,CAAEC,oBAAoB;GACxDC,EAAIN,EAAOC,MAAOM,EAAS,EAAJD,EAAOE,EAAIR,EAAOE,OAAQO,EAAWD,EAAI,EAEtEL,EAAQO,UAAY,QACpBP,EAAQQ,aAAa,EAAIL,EAAI,EAAGE,EAAI,GACpCL,EAAQO,UAAY,QACpBP,EAAQ9B,KAAOY,EACfkB,EAAQS,SAASvB,EAAaC,EAAU,EAAGmB,GAE3C,IAAII,EAASV,EAAQW,aAAa,EAAG,EAAGR,EAAGE,GAAGO,KAC1C7P,EAAI,EACR,MAAM8P,EAAMH,EAAOzQ,OAGnB,OAASc,EAAI8P,GAAOH,EAAO3P,GAAK,MAChC,IAAI+P,EAASR,EAAW1L,EAAM7D,EAAIqP,GAIlC,IADArP,EAAI8P,EAAM,IACD9P,EAAI,GAAK2P,EAAO3P,GAAK,MAC9B,IAAIgQ,EAAUnM,EAAM7D,EAAIqP,GAAME,EAU9B,IARAN,EAAQO,UAAY,QACpBP,EAAQQ,aAAa,EAAIL,EAAI,EAAGE,EAAI,GACpCL,EAAQO,UAAY,QACpBP,EAAQS,SAnDY,KAmDUtB,EAAU,EAAGmB,GAC3CI,EAASV,EAAQW,aAAa,EAAG,EAAGR,EAAGE,GAAGO,KAG1C7P,EAAI,IACKA,EAAI8P,GAAOH,EAAO3P,GAAK,MAChC,IAAIiQ,EAAaV,EAAW1L,EAAM7D,EAAIqP,GAElCa,EAAcD,EACdE,EAAeH,EAEnB,GAAInC,EAAc,CAShB,IARAoB,EAAQO,UAAY,QACpBP,EAAQQ,aAAa,EAAIL,EAAI,EAAGE,EAAI;AACpCL,EAAQO,UAAY,QACpBP,EAAQS,SAAS7B,EAAcO,EAAU,EAAGmB,GAC5CI,EAASV,EAAQW,aAAa,EAAG,EAAGR,EAAGE,GAAGO,KAG1C7P,EAAI,IACKA,EAAI8P,GAAOH,EAAO3P,GAAK,MAKhC,IAJAkQ,EAAchO,EAAI2B,EAAM7D,EAAIqP,GAAME,EAAUU,GAG5CjQ,EAAI8P,EAAM,IACD9P,EAAI,GAAK2P,EAAO3P,GAAK,MAC9BmQ,EAAejO,EAAI2B,EAAM7D,EAAIqP,GAAME,EAAUS,EAC9C,CAEGhC,EAAeR,IACjBuC,EAASzH,EAAKyH,EAAS,GACvBE,EAAa3H,EAAK2H,EAAa,GAC/BD,EAAU1H,EAAK0H,EAAU,GACzBE,EAAc5H,EAAK4H,EAAc,GACjCC,EAAe7H,EAAK6H,EAAe,IAerC,OAVArC,EAAU,CAAEX,OAAMM,aAAYsC,SAAQE,aAAYD,UAASI,QAF3C3C,EAAawC,EAAaD,GAIrCnC,GAGHC,EAAQoC,YAAcA,EACtBpC,EAAQqC,aAAeA,EACvBrC,EAAQuC,gBAAkBnO,EAAIgO,EAAcC,EAAc1C,IAJ1DC,GAAcP,GAAQW,EAOjBA,CACT,CAGA,SAASwC,GAAanD,GACpB,MAAI,uBAAuBpM,KAAKoM,GACvBA,EAAKhM,QAAQ,uBAAwB,IAErC,UAAYgM,CACvB,CAEM,SAAUoD,GAAwB3C,EAAiC4C,GACnE5L,EAAS4L,KACXA,EAAkBhS,OAAOuE,cAAcyN;CAEzC,MAAMC,EAAYF,GACZG,EAAUC,KACV7C,EAAUH,GAAeC,GAEzBgD,EAAO9C,EAAQL,WADL,EAOVoD,EAAW,CAJAJ,EAAKK,UAAYL,EAAKK,QAAUhG,SAASwD,cAAc,WACvDmC,EAAKM,UAAYN,EAAKM,QAAUjG,SAASwD,cAAc,WACvDmC,EAAKO,UAAYP,EAAKO,QACVN,GAAW5F,SAASwD,cAAc,YAEzD2C,EAAiB,GAEvB,IAAK,IAAIjR,EAAI,EAAGA,GAAgC0Q,EAAU,EAAI,KAAM1Q,EAAG,CACrE,MAAM8O,EAAS+B,EAAS7Q,GAExB8O,EAAOC,MAAQ6B,EACf9B,EAAOE,OAAS4B,EAChB9B,EAAOtD,MAAMgD,QAAU,IAEvB,MAAMS,EAAUH,EAAOI,WAAW,KAAM,CAAEC,oBAAoB,IAE9DF,EAAQO,UAAY,QACpBP,EAAQQ,aAAa,EAAImB,EAAO,EAAGA,EAAO,GAC1C3B,EAAQO,UAAY,QAMpBP,EAAQ9B,KAAc,IAANnN,GAAW0Q,EAAUJ,GAAaxC,EAAQX,MAAQW,EAAQX,KAE1E8B,EAAQS,SAAe,IAAN1P,GAAY0Q,GAAiB,IAAN1Q,EAAWwQ,EAAkB,IAAU,EAAG1C,EAAQmC;AAE1FgB,EAAQjR,GAAKiP,EAAQW,aAAa,EAAG,EAAGgB,EAAMA,GAAMf,IACrD,CAED,IAAK,IAAI7P,EAAI,EAAGA,EAAIiR,EAAQ,GAAG/R,OAAQc,GAAK,EAC1C,GAAIiR,EAAQ,GAAGjR,KAAOiR,EAAQ,GAAGjR,GAC/B,OAAO,EAKX,GAAI0Q,EACF,IAAK,IAAI1Q,EAAI,EAAGA,EAAIiR,EAAQ,GAAG/R,OAAQc,GAAK,EAAG,CAC7C,MAAMkR,EAAMrN,EAAM7D,EAAI,EAAI4Q,GACpBO,EAAMtN,EAAM7D,EAAI,GAAK4Q,EAE3B,IAAKM,EAAM,GAAKA,IAAQpD,EAAQmC,WAAa,GAAKkB,EAAM,IAAMF,EAAQ,GAAGjR,KAAOiR,EAAQ,GAAGjR,GACzF,OAAO,CACV,CAGH,OAAO,CACT,UAEgBoR,GAAaC,EAA0BlE,EAA4BmE,GACjF,MAEMrC,GAFWmC,GAAqBtC,SACpBsC,GAAqBtC,OAAShE,SAASwD,cAAc,YAChDY,WAAW,KAAM,CAAEC,oBAAoB,IAC9D,IACIoC,EADAC,EAAW,EAGK,iBAATrE,EACToE,EAAcpE,EACS,iBAATA,IACdoE,EAAcrE,GAAQC,IAItB8B,EAAQ9B,KADNoE,IAEKD,GAGQ,0BAEZ5M,MAAMD,QAAQ4M,KACjBA,EAAQ,CAACA,IAEX,IAAK,MAAMnL,KAAQmL,EAAO;AACxB,MAAMtC,EAAQE,EAAQwC,YAAYvL,GAAM6I,MACxCyC,EAAWtP,EAAIsP,EAAUzC,EAC1B,CAED,OAAOyC,CACT,CAEA,MAAME,GAAuC,CAC3C,IAAK,OACL,IAAK,OACL,IAAK,QACL,IAAK,SACL,IAAK,UAGDC,GAAyC,CAAA,WAG/BC,GAAW9S,EAAW+S,GAAe,GACnD,OAAO/S,EAAEqC,QAAQ0Q,EAAe,WAAa,SAAUC,GAAKJ,GAAaI,EAAE,IAC7E,CAEM,SAAUC,GAAajT,GA0B3B,OAzBAA,EAAIA,EAAEqC,QAAQ,oDAAqD6Q,IACjE,IAAIC,EAAcN,GAAeK,GAEjC,IAAKC,EAAa,CAChB,IACInQ,EADAc,EAAO,GAUX,GAPI,QAAQ7B,KAAKiR,IACfpP,EAAO,GACPd,EAAS,oBAAoBoM,KAAK8D,EAAOE,OAAO,KAEzCF,EAAOG,WAAW,QACzBrQ,EAAS,cAAcoM,KAAK8D,EAAOE,OAAO,KAExCpQ,EAAQ,CACV,MAAMD,EAAI2B,EAAM1B,EAAO,IAAI,EAAIc,GAE3B,GAAKf,GAAKA,GAAK,UACjBoQ,EAAczT,OAAOuE,cAAclB,GACtC,CACF;AAED,OAAOoQ,GAAeD,GAI1B,CAEA,IAAII,GACAC,GACAC,GACAC,GACAC,GACAC,GACAC,GACAC,GACAC,GACAC,GACAC,GACAC,GACAC,GACAC,GACAC,GACAC,GACAC,GACAC,GACAC,GACAC,GAEE,SAAUC,GAAsBC,EAAiBhL,EAAYiL,EAAcC,GAC/ED,EAAMA,GAAOlL,EACbmL,EAAcA,KAAiBnL,GAAS0D,WAAW,sCAAsCE,QACzFgG,GAAYqB,EAAI7K,UAAa6K,EAAYG,eAAehL,UAAY,IACpEyJ,GAAeD,GAAUD,WAAW,QAAU,wBAAwBpR,KAAK0S,EAAI5K,WAC/EyJ,GAAWD,KAAiB,cAActR,KAAK0S,EAAI5K,WACnD0J,GAAa,8CAA8CxR,KAAK0S,EAAI5K,WACpE2J,GAAaiB,EAAI/K,YAAYmL,SAAS,YAAczB,GAAUD,WAAW,OACzEM,GAAWL,GAAUD,WAAW,UAAY,aAAapR,KAAK0S,EAAI5K;AAClE6J,GAAU,YAAY3R,KAAK0S,EAAI5K,YAAc2J,GAC7CG,KAAiBe,GAAaI,OAC9BlB,GAAkBD,IAAeD,GACjCG,GAAaY,EAAI5K,UAAUgL,SAAS,YAActB,GAClDO,QAAwC,IAArBY,GAAaK,KAAuB,eAAehT,KAAK0S,EAAI5K,WAC/EkK,GAA2B,gBAAfU,EAAI3K,SACZ,cAAc/H,KAAK0S,EAAI5K,aAAe6J,KAAYH,KAAeO,KAAaF,IAC9E,YAAY7R,KAAK0S,EAAI5K,YACzBmK,GAA6B,gBAAfS,EAAI3K,QAA4B,YAAY/H,KAAK0S,EAAI5K,WACnEoK,GAAcQ,EAAI5K,UAAUgL,SAAS,aAAezB,GAAUyB,SAAS,cACvEX,GAAa,WAAWnS,KAAK0S,EAAI5K,aAAe,aAAa9H,KAAK0S,EAAI5K;AACtEsK,GAAY,iCAAiCpS,KAAK0S,EAAI5K,aAAe6J,GACrEU,GAAS,oBAAoBrS,KAAKqR,KAAeC,IAAgBc,IAAaM,EAAI9K,eAAiB,EACnG0K,GAAcpP,IAAYmP,GACxB,8CAA8ClF,KAAKuF,EAAI5K,WADrB,OACoC,IAAI,IAC5EyK,GAAoBF,IAAUC,IAAe,GAC7CE,GAAkBH,IAChB,4EAA4ErS,KAAK0S,EAAI5K,YAAc8K,CACvG,UAIgBK,KACd,OAAOnB,EACT,UAEgBoB,KACd,OAAOlB,EACT,UAEgBmB,KACd,OAAOlB,EACT,UAEgBmB,KACd,OAAOxB,EACT,UAEgByB,KACd,OAAOxB,EACT,UAEgByB,KACd,OAAO3B,EACT,UAEgB/B,KACd,OAAOuC,EACT,UAKgBoB;AAEd,OAAO,CACT,UAEgBC,KACd,OAAOnB,EACT,UAEgBoB,KACd,OAAO/B,EACT,UAEgBgC,KACd,OAAOpB,EACT,UAEgBqB,KACd,OAAOpB,EACT,UAEgBqB,KACd,OAAOpB,EACT,UAEgBqB,KACd,OAAOtC,EACT,UAEgBuC,KACd,OAAO/B,EACT,UAKgBgC,KACd,OAAO7B,EACT,UAEgB8B,KACd,OAAO5B,EACT,UAEgB6B,KACd,OAAOzC,EACT,UAEgB0C,KACd,OAAOzC,EACT,CAEM,SAAU0C,GAAmBC,EAAchI,EAA4BqE,EAAkB4D,EAAa,KAC1G,IAAIrG,EAAQqC,GAAa+D,EAAMhI,GAC3BkI,EAAa,EAEjB,KAAOtG,EAAQyC,GACb2D,EAAOA,EAAKnU,UAAU,EAAGmU,EAAKjW,OAASmW,GAAcD,EACrDC,EAAa,EAAID,EAAWlW,OAC5B6P,EAAQqC,GAAa+D,EAAMhI,GAG7B,OAAOgI,CACT,CAGM,SAAUG,GAAcC,GAE5BC,GAAmBD,GAAM,EAC3B,UAGgBC,GAAmBD,EAAeE,GAAiB,GACjE,OAAIF,IAASG,KACJC,GAAsBF,GAExBjM,QAAQC,SACjB,UAGgBmM,KAEdD,IACF,CAGM,SAAUA,GAAsBF,GAAiB;AACrD,MAAMI,EAAQ/K,SAEd,IACE,GAAK4K,KAYA,IAAIG,EAAMC,eACb,OAAOD,EAAMC,iBACND,EAAME,iBACbF,EAAME,mBACCF,EAAMG,oBACbH,EAAMG,sBACCH,EAAMI,sBACbJ,EAAMI,sBAAsB,KAnBT,CACnB,MAAMC,EAAYpL,SAASqL,gBAE3B,GAAID,EAAUE,kBACZ,OAAOF,EAAUE,oBACVF,EAAUG,oBACjBH,EAAUG,sBACHH,EAAUI,qBACjBJ,EAAUI,uBACHJ,EAAUK,yBACjBL,EAAUK,yBACb,CASF,CACD,MAAOC,GACL,GAAIf,EACF,MAAMe;CAER,OAAOhN,QAAQiN,OAAOD,aAAaE,MAAQF,EAAI,IAAIE,MAAMF,GAC1D,CAED,OAAOhN,QAAQC,SACjB,UAGgBiM,KACd,MAAMG,EAAQ/K,SAEd,SAAU+K,EAAMc,mBAAqBd,EAAMe,sBAAwBf,EAAMgB,yBAA2BhB,EAAMiB,oBAC5G,UAGgBC,KACd,OAAOrB,QACFlN,GAAWA,EAAQwO,aAAexO,EAAQyO,QAAQlI,OAASvG,EAAQ0O,cAAgB1O,EAAQyO,QAAQjI,MAC1G,UAEgBmI,GAAarY,EAAWsY,GAAc,GAGpD,OAFAtY,EAAIuY,mBAAmBvY,GAAGqC,QAAQ,WAAY2Q,GAAK,IAAMA,EAAE5R,WAAW,GAAG6B,SAAS,IAAIxB,eAE/E6W,EAActY,EAAEqC,QAAQ,OAAQ,KAAOrC,CAChD,UAEgBwY,GAAgBC,EAAmEH,GAAc,GAC/G,MAAMjU,EAAmB;CAOzB,OALAhB,EAAQoV,EAAQ,CAAC/S,EAAKf,KACP,MAATA,GACFN,EAAOvC,KAAKuW,GAAa3S,GAAO,IAAM2S,GAAa1T,EAAM1B,WAAYqV,MAGlEjU,EAAOtC,KAAK,IACrB,CA3QAwD,OAAOC,KAAKoN,IAAcvP,QAAQqC,GAAOmN,GAAeD,GAAalN,IAAQA,GAqF7EgP;;CCpmBA,MAAMtR,IAAEA,GAAGqG,IAAEA,GAAGiP,MAAEA,IAAUvV,KAStBwV,GAAiB,YACjBC,GAAY,gEACZC,GAAY,+CAElB,IAAIC,GAsCE,SAAUC,GAAaC,EAAWC,EAAWtY,EAAWuY,EAAQ,GACpEF,EAAIvP,GAAIrG,GAAIsV,GAAMM,GAAI,GAAI,KAC1BC,EAAIxP,GAAIrG,GAAIsV,GAAMO,GAAI,GAAI,KAC1BtY,EAAI8I,GAAIrG,GAAIsV,GAAM/X,GAAI,GAAI,KAC1B,MAAMD,EAAI+I,GAAIrG,GAAI8V,EAAO,GAAI,GAAGC,QAAQ,GAAG9W,QAAQ,cAAe,MAAMA,QAAQ,YAAa,MAE7F,MAAU,MAAN3B,GACM,IAAMsY,EAAE/V,SAAS,IAAImW,SAAS,EAAG,KAC3BH,EAAEhW,SAAS,IAAImW,SAAS,EAAG,KAC3BzY,EAAEsC,SAAS,IAAImW,SAAS,EAAG,MAAM3X,cAExC,QAAQuX,MAAMC,MAAMtY,MAAMD,IACrC;AAmBM,SAAU2Y,GAAYlJ,EAAmCmJ,EAAYC,EAAYC,EAAYC,GACjGtJ,EAAQuJ,OACRvJ,EAAQwJ,YAERxJ,EAAQyJ,UAAUN,EAAKE,EAAID,EAAKE,GAChCtJ,EAAQ0J,MAAML,EAAIC,GAClBtJ,EAAQ2J,IAAI,EAAG,EAAG,EAAG,EAAa,EAAV3W,KAAK4W,IAAQ,GAErC5J,EAAQ6J,YACR7J,EAAQ8J,UACR9J,EAAQ+J,MACV,CAMM,SAAUC,GAAWC,GACzB,IAAI9V,EAAQqU,GAAevJ,KAAMgL,EAAQA,EAAM5Z,QAE/C,GAAI8D,EAAO,CACT,IAAKwU,GAAa,CAChB,MAAM9I,EAAShE,SAASwD,cAAc,UACtCsJ,GAAc9I,EAAOI,WAAW,KAAM,CAAEC,oBAAoB,GAC7D,CAEDyI,GAAYpI,UAAY0J,EACxBA,EAAQ1a,OAAOoZ,GAAYpI,UAC5B,CAED,GAAI0J,EAAM/G,WAAW,KACnB,OAAQ+G,EAAMha,QACZ,KAAK,EACL,KAAK,EACH,MAAO,CACL4Y,EAAG/T,SAASmV,EAAMhH,OAAO,EAAG,GAAKgH,EAAMhH,OAAO,EAAG,GAAI,IACrD6F,EAAGhU,SAASmV,EAAMhH,OAAO,EAAG,GAAKgH,EAAMhH,OAAO,EAAG,GAAI,IACrDzS,EAAGsE,SAASmV,EAAMhH,OAAO,EAAG,GAAKgH,EAAMhH,OAAO,EAAG,GAAI;AACrD8F,MAAwB,IAAjBkB,EAAMha,OAAe,EAAM6E,SAASmV,EAAMhH,OAAO,EAAG,GAAKgH,EAAMhH,OAAO,EAAG,GAAI,IAAM,KAG9F,KAAK,EACL,KAAK,EACH,MAAO,CACL4F,EAAG/T,SAASmV,EAAMhH,OAAO,EAAG,GAAI,IAChC6F,EAAGhU,SAASmV,EAAMhH,OAAO,EAAG,GAAI,IAChCzS,EAAGsE,SAASmV,EAAMhH,OAAO,EAAG,GAAI,IAChC8F,MAAwB,IAAjBkB,EAAMha,OAAe,EAAM6E,SAASmV,EAAMhH,OAAO,EAAG,GAAI,IAAM,KAO7E,OAFA9O,EAAQuU,GAASzJ,KAAKgL,GAElB9V,EACK,CAAE0U,EAAG9T,OAAOZ,EAAM,IAAK2U,EAAG/T,OAAOZ,EAAM,IAAK3D,EAAGuE,OAAOZ,EAAM,IAAK4U,MAAO,IAEjF5U,EAAQsU,GAAUxJ,KAAKgL,GAEnB9V,EACK,CAAE0U,EAAG9T,OAAOZ,EAAM,IAAK2U,EAAG/T,OAAOZ,EAAM,IAAK3D,EAAGuE,OAAOZ,EAAM,IAAK4U,MAAOhU,OAAOZ,EAAM,KAEvF,CAAE0U,EAAG,EAAGC,EAAG,EAAGtY,EAAG,EAAGuY,MAAO,GACpC,CC7HA,MAAMxE,sBAAEA,MAA0B2F,IAAsBC;CASzB,MAA3B5a,OAAO6a,UAAUnH,SACnB1T,OAAO6a,UAAUnH,OAAS,SAAU1S,EAAWC,GAC7C,OAAOgI,KAAKzG,UAAUxB,EAAGA,EAAIC,EAC/B,8EDjBI,SAAsB6Z,EAAgBC,EAAgBC,EAAW,IACrE,MAAMC,EAAKR,GAAWK,GAChBI,EAAKT,GAAWM,GAChBI,EAAKF,EAAG3B,EACR8B,EAAKH,EAAG1B,EACR8B,EAAKJ,EAAGha,EACRqa,EAAKL,EAAGzB,MAKR+B,EAAW,EAAIP,EAErB,OAAO3B,GAAa8B,EAAKH,EANdE,EAAG5B,EAM2BiC,EACrBH,EAAKJ,EANdE,EAAG3B,EAM2BgC,EACrBF,EAAKL,EANdE,EAAGja,EAM2Bsa,EACrBD,EAAKN,EANdE,EAAG1B,MAM2B+B,EAC3C,8BHwgB2Bjb,EAAWkb,EAAO,GAC3C,IAAIC,EAAK,WAAaD,EAClBE,EAAK,WAAaF,EAEtBlb,EAAIA,EAAE6C,YAEN,IAAK,IAAWxB,EAAPH,EAAI,EAAeA,EAAIlB,EAAEI,SAAUc,EAC1CG,EAAKrB,EAAEoB,WAAWF,GAClBia,EAAKhY,KAAKkY,KAAKF,EAAK9Z,EAAI,YACxB+Z,EAAKjY,KAAKkY,KAAKD,EAAK/Z,EAAI;CAM1B,OAHA8Z,EAAKhY,KAAKkY,KAAKF,EAAMA,IAAO,GAAK,YAAchY,KAAKkY,KAAKD,EAAMA,IAAO,GAAK,YAC3EA,EAAKjY,KAAKkY,KAAKD,EAAMA,IAAO,GAAK,YAAcjY,KAAKkY,KAAKF,EAAMA,IAAO,GAAK,aAEnE,YAAc,QAAUC,IAAOD,IAAO,IAAIlY,SAAS,IAAIxB,cAAc2X,SAAS,GAAI,IAC5F,2CC/MyB7S,EAASC,GAAyE,GACzG,OAAOF,EAASC,EAAMC,EAAS,EAAG,IAAI8U,QACxC,qCEzUkCpa,EAAWgY,EAAQ,GAKnD,OAAOH,IAJQ,SAAJ7X,IAAiB,IACb,MAAJA,IAAiB,EACb,IAAJA,EAEkBgY,EAC/B,sCAEmCqC,EAAiBC,EAAS,GAM3D,OAAOzC,GALGwC,EAAMC,IAAW,EACjBD,EAAMC,EAAS,IAAM,EACrBD,EAAMC,EAAS,IAAM,GAChBD,EAAMC,EAAS,IAAM,KAAO,IAG7C;+BHXM,SAAiC9a,EAAWC,GAIhD,OAHAD,EAAIA,EAAEyB,gBACNxB,EAAIA,EAAEwB,gBAEU,EAAMzB,EAAIC,EAAI,EAAI,CACpC,+BAEM,SAA+BD,EAAWC,GAC9C,MAAMqa,EAAKta,EAAEyB,cACP4Y,EAAKpa,EAAEwB,cACPkC,EAAU2W,EAAKD,GAAK,EAAMC,EAAKD,EAAK,EAAI,EAE9C,OAAe,IAAX1W,EACKA,EAED3D,EAAIC,GAAI,EAAMD,EAAIC,EAAI,EAAI,CACpC,8BCqgBM,SAA8BD,EAAWC,GAC7C,IAAMD,IAAMC,GAAMD,IAAMC,EACtB,OAAO,EAMT,IAHAD,EAAIA,EAAE2B,QAAQ,QAAS,KAAKA,QAAQ,aAAc,IAClD1B,EAAIA,EAAE0B,QAAQ,QAAS,KAAKA,QAAQ,aAAc,IAE3C3B,EAAEN,OAAS,GAAKO,EAAEP,OAAS,GAAG,CACnC,IACIqb,EACAC,EAFAha,EAAMhB,EAAEkB,QAAQ,KAwBpB,GApBIF,EAAM,GACR+Z,EAAK/W,EAAMhE,GACXA,EAAI,KAGJ+a,EAAK/W,EAAMhE,EAAEwB,UAAU,EAAGR;AAC1BhB,EAAIA,EAAEwB,UAAUR,EAAM,IAGxBA,EAAMf,EAAEiB,QAAQ,KAEZF,EAAM,GACRga,EAAKhX,EAAM/D,GACXA,EAAI,KAGJ+a,EAAKhX,EAAM/D,EAAEuB,UAAU,EAAGR,IAC1Bf,EAAIA,EAAEuB,UAAUR,EAAM,IAGpB+Z,EAAKC,EACP,OAAO,EACJ,GAAID,EAAKC,EACZ,OAAO,CACV,CAED,OAAKhb,EAGI,GAFA,CAGX,iDD/FM,SAAwBqC,EAAW4Y,GACvC,MAAM7X,EAAiB,GACjB8X,EAAOzX,EAAqBpB,EAAGe,GAErC,GAAIA,EAAK,KAAO6X,EAAW,CACzB,MAAME,EAAQF,EAAUva,WAAW,GAAK,GAExC2B,EAAI6Y,EAAKvZ,QAAQ,MAAOhB,GAAM3B,OAAOuE,cAAc5C,EAAGD,WAAW,GAAKya,GACvE,CAED,OAAO9Y,CACT,2DC6ImD0F,EAAeC,EAASpD,GAEzE,MAAMwW,EAAI,IAAItT,EAAUC,EAAOC,EAAMpD,GAIrC,OAFCwW,EAAElT,UAAkBW,OAASuS,EAAEvS,OAEzBuS,EAAElT,SACX,sBD5IM,SAAsBvH;AAG1B,OAFAA,EAAKA,GAAIC,OAAO,GAETuC,EAAaxC,GAAM,MAAQ,OAAOY,KAAKZ,GAAM,IAAM,aAAUQ,EACtE,uEG7diCsO,EAAmCkG,EAAc0F,EAAWC,EAC5DC,EAAuBvL,EAAoBwL,EAAc,GACxF/L,EAAQuJ,OACRvJ,EAAQgM,UAAYD,EACpB/L,EAAQiM,SAAW,QAEfH,IACF9L,EAAQkM,YAAcJ,GAEpBvL,IACFP,EAAQO,UAAYA,GAEtBP,EAAQmM,WAAWjG,EAAM0F,EAAGC,GAC5B7L,EAAQS,SAASyF,EAAM0F,EAAGC,GAC1B7L,EAAQ8J,SACV,uEHpBM,SAA0BnW,EAAcyY,EAAiBC,EAAY,MACzE,OAAK1Y,EAGIA,EAAO0Y,EAAYD,EAFnBA,CAGX,qBG8BM,SAAqBpM,EAAmCmJ,EAAYC,EAAYP,GACpFK,GAAYlJ,EAASmJ,EAAIC,EAAIP,EAAGA,EAClC,uCFiIM,SAAmBuC,EAAwC3W;AAC/D,OAAIiB,EAAY0V,IAAUA,EAAMnb,OAAS,EAChCmb,EAAM,GAEN3W,CACX,kBAyRM,SAAkBlE,GACtB,OAAO2H,EAAS,GAAI3H,EAAG,EACzB,sBAEM,SAAsBA,GAC1B,OAAO2H,EAAS,GAAI3H,EAAGwE,OAAOa,iBAChC,qCAzPM,SAAsBV,EAAoDC,GAC9E6C,QAAQC,QAAQ3C,EAASJ,GAAOA,EAAM,CAAA,GAAIhC,QAAQqC,GAAOJ,EAASI,EAAKL,EAAKK,IAC9E,yBA/OM,SAAyB+W,EAA8EC,GAC3G,IAAIC,EASAC,EARAC,GAAW,EACXC,GAAW,EACXC,GAAY,EACZC,GAAS,EACTC,GAAM,EACNC,GAAO,EACPC,GAAO,EACPC,GAAa,EAGbxX,MAAMD,QAAQ8W,GAChBG,EAAUH,EACHY,UAAUjd,OAAS,GAAK0F,EAAS4W,GACxCE,EAAUhX,MAAMqB,KAAKoW,WAAWC,MAAM,GAC/B3X,EAAQ+W,KACfE,EAAUF,GAEiB,iBAAlBD,GAAuD,iBAAlBA,IAC9CE,EAAO,IAAI3V,KAAKyV,IAElBE,EAAOA,GAAQ,IAAI3V;AAEf4V,GACFA,EAAQvZ,QAAQka,IACd,OAAQA,GACN,KAAKhZ,QAAAA,gBAAgBiZ,UAAWX,GAAW,EAAM,MACjD,KAAKtY,QAAAA,gBAAgBkZ,WAAYV,GAAY,EAAMK,GAAa,EAAO,MACvE,KAAK7Y,QAAAA,gBAAgBmZ,QAASV,GAAS,EAAM,MAC7C,KAAKzY,QAAAA,gBAAgBoZ,UAAWb,GAAW,EAAM,MACjD,KAAKvY,QAAAA,gBAAgBqZ,IAAKX,GAAM,EAAM,MACtC,KAAK1Y,QAAAA,gBAAgBsZ,MAAOX,GAAO,EAAM,MACzC,KAAK3Y,QAAAA,gBAAgBuZ,MAAOX,GAAO,EAAMF,GAAM,EAAM,MACrD,KAAK1Y,QAAAA,gBAAgBwZ,YAAaX,GAAa,EAAML,GAAY;CAKvE,MAGMiB,EAAU,GAHNlb,EAAQma,EAAMN,EAAKsB,iBAAmBtB,EAAKuB,cAAe,MAC1Dpb,EAAQma,EAAMN,EAAKwB,cAAgB,EAAIxB,EAAKyB,WAAa,EAAG,MAC5Dtb,EAAQma,EAAMN,EAAK0B,aAAe1B,EAAK2B,UAAW,KAG5D,GAAIzB,EACF,OAAOmB,EAET,MAAMxN,EAAI1N,EAAQma,EAAMN,EAAK4B,cAAgB5B,EAAK6B,WAAY,GACxDC,EAAKvB,EAAO,IAAM,IAClBlK,EAAIlQ,EAAQma,EAAMN,EAAK+B,aAAe/B,EAAKgC,gBAAiB,GAC5D3e,EAAI,IAAM8C,EAAQma,EAAMN,EAAKiC,gBAAkBjC,EAAKkC,aAAc,GAClE9C,EAAI,IAAMjZ,EAAQma,EAAMN,EAAKmC,qBAAuBnC,EAAKoC,kBAAmB,GAC5EC,EAAc/B,EAAM,EAAIN,EAAKsC,oBAC7BC,EAAI/B,EAAO,IACf,KAAO6B,EAAc,EAAI,IAAM,KAAOlc,EAAQK,KAAK4B,MAAM5B,KAAKiG,IAAI4V,GAAe,IAAK,GAAKlc,EAAQK,KAAK4B,MAAM5B,KAAKiG,IAAI4V,GAAe,IAAK,GAC7I,IAAIG,EAAU,GAAG3O,KAAKwC,IAWtB,OATK+J,IACHoC,GAAWnf;AAETod,IACF+B,GAAWpD,GAERiB,IACHmC,GAAWD,GAETpC,EACKqC,EAEAnB,EAAUS,EAAIU,CACzB,sMA6L+B7e,EAAgBoF,EAAQ0Z,GACrD,IAAI/a,EAAS/D,EAAIsG,IAAIlB,GAWrB,YATe7D,IAAXwC,IAEAA,EADE4B,EAAWmZ,GACJA,IAEAA,EAEX9e,EAAIiD,IAAImC,EAAKrB,IAGRA,CACT,wBAEOoG,eAAmCnK,EAAgBoF,EAAQJ,GAChE,IAAIjB,EAAS/D,EAAIsG,IAAIlB,GAOrB,YALe7D,IAAXwC,IACFA,QAAeiB,IACfhF,EAAIiD,IAAImC,EAAKrB,IAGRA,CACT,4BElKyBgb,EAAsBtD,EAAWC,GACxD,GAAID,EAAI,GAAKC,EAAI,GAAKD,GAAKsD,EAAUpP,OAAS+L,GAAKqD,EAAUnP,OAC3D,OAAO,EAET,MAAMsL,EAAqC,GAA3BQ,EAAIqD,EAAUpP,MAAQ8L;CAEtC,OAAQsD,EAAUtO,KAAKyK,IAAe,GAC9B6D,EAAUtO,KAAKyK,EAAS,IAAO,EAC/B6D,EAAUtO,KAAKyK,EAAS,GACxB6D,EAAUtO,KAAKyK,EAAS,IAAM,EACxC,oLHwEM,SAA8Bxb,GAClC,QAASA,GAAKV,EAAgB2C,KAAKjC,EAAEqC,QAAQhD,EAAkB,IACjE,gFCqFM,SAAmBqB,GACvB,MAAoB,iBAANA,CAChB;0CDgNM,SAAkBW,GAGtB,OAFAA,EAAKA,GAAIC,OAAO,GAET9B,EAAayC,KAAKZ,MAASsC,EAAYtC,EAChD,uEChFM,SAAUie,EAAQ5e,EAAQC,EAAQic,GAAoC,EAAOlX,GAOjF,IAAI6Z,EAEJ,GARIvZ,EAAU4W,KACZA,EAAU,CAAE4C,gBAAiB5C,IAE3BjX,EAAQiX,GAAS6C,gBACnB7C,EAAQ6C,aAAe,IAAIjd,IAAIoa,EAAQ6C,eAIrC7C,EAAQ8C,cAAmD7d,KAAvC0d,EAAO3C,EAAQ8C,QAAQhf,EAAGC,EAAG+E,IACnD,OAAO6Z,EACJ,GAAI7Z,GAAOkX,EAAQ6C,cAAgB7C,EAAQ6C,aAAa9Y,IAAIjB,GAC/D,OAAO,EACJ,GAAIhF,IAAMC,GAAK4E,OAAOoa,GAAGjf,EAAGC,GAC/B,OAAO,EACJ,UAAWD,UAAaC,GAAKgF,EAAQjF,KAAOiF,EAAQhF,IAAOgF,EAAQjF,IAAMA,EAAEN,SAAWO,EAAEP,OAC3F,OAAO;CACJ,GAAIwc,EAAQ4C,mBAAqB9e,EAAE0F,cAAiBzF,EAAEyF,aAAe1F,EAAE0F,cAAgBzF,EAAEyF,aAC5F,OAAO,EACJ,IAAKX,EAAS/E,KAAO+E,EAAS9E,GACjC,OAAO,EACJ,CACH,MAAM6E,EAAO2C,QAAQC,QAAQ1H,GACvBkf,EAAQ,IAAIpd,IAAI2F,QAAQC,QAAQzH,IAEtC,IAAK,MAAM+E,KAAOF,EAGhB,GAFAoa,EAAMC,OAAOna,KAETkX,GAAS6C,cAAgB7C,EAAQ6C,aAAa9Y,IAAIjB,IAGjD/E,EAAEmf,eAAepa,IAAS4Z,EAAQ5e,EAAEgF,GAAM/E,EAAE+E,GAAMkX,EAASlX,IAC9D,OAAO,EAMX,GAHIka,EAAM9N,KAAO,GAAK8K,GAAS6C,cAC7B7C,EAAQ6C,aAAapc,QAAQqC,GAAOka,EAAMC,OAAOna,IAE/Cka,EAAM9N,KAAO,EACf,OAAO,CACV,CAED,OAAO,CACT;wHArKM,SAA8BpR,GAClC,QAASA,GAAkB,iBAANA,CACvB,2IAUM,SAAmBA,GACvB,MAAoB,iBAANA,CAChB,mBAEM,SAAmBA,GACvB,MAAoB,iBAANA,CAChB,sBAsMM,SAAsBV,GAC1B,IAEE,OADA+f,KAAKC,MAAMhgB,IACJ,CACR,CACD,MAAM,CAEN,OAAO,CACT;iBAEM,SAAmBqF,GACvB,OAAOA,EAAM8C,QAAQC,QAAQ/C,GAAKjF,OAAS,CAC7C,eAlUM,SAAkBmb,EAAwC3W,GAC9D,OAAIiB,EAAY0V,IAAUA,EAAMnb,OAAS,EAChCmb,EAAMA,EAAMnb,OAAS,GAErBwE,CACX,8DDhCkC5E,EAAWgB,GAAc,GACzD,OAAIhB,EACKe,EAAef,EAAGgB,GAAaS,cAE/BzB,CACX,qCAZkCA,EAAWgB,GAAc,GACzD,OAAIhB,EACKe,EAAef,EAAGgB,GAAamB,cAE/BnC,CACX,cCkEM,SAAiBub,GACrB,OAAIA,GAAS5V,EAAQ4V,IAAUA,EAAMnb,OAAS,EACrCmb,EAEA,IACX,eAwQoB,IAAI0E,4BAzTD1E,EAAwCxY,EAAW6B,GACxE,OAAIiB,EAAY0V,IAAUA,EAAMnb,QAAU2C,EAAI,EAAI,EAAI,GAAKI,KAAKiG,IAAIrG,GAC3DA,EAAI,EAAIwY,EAAMA,EAAMnb,OAAS2C,GAAKwY,EAAMxY,GAExC6B,CACX;gBAtIM,SAAkBlE,EAAQC,GAC9B,OAAOwE,EAASzE,GAAKyE,EAASxE,EAChC,kBD+MM,SAAkByG,EAAuBhH,EAAgB8f,EAAU,KACvE,IAAIC,EAAO,IAEN,OAAOle,KAAKie,IAA4B,iBAAT9Y,GAAqBA,EAAO,GAAiB,MAAZ8Y,IACnEC,EAAO,IACP/Y,GAAQA,IACNhH,GAGJ,IAAIiE,EAAS3E,OAAO0H,GAEpB,KAAO/C,EAAOjE,OAASA,GACrBiE,EAAS6b,EAAU7b,EAErB,OAAO8b,EAAO9b,CAChB,4BAKyB+C,EAAchH,EAAgB8f,GAIrD,IAHKA,IACHA,EAAU,KAEL9Y,EAAKhH,OAASA,GACnBgH,GAAQ8Y,EAEV,OAAO9Y,CACT,yDC7UE,GAA2B,oBAAhBgZ,YACT,OAAOA,YAAYC,MAChB,GAAuB,oBAAZC,QAAyB,CACvC,GAAKA,QAAQC,OAAeC,OAC1B,OAAOtb,OAAQob,QAAQC,OAAeC,UAAY,IAC/C;AACH,MAAMC,EAAOH,QAAQC,SAErB,OAAiB,IAAVE,EAAK,GAAYA,EAAK,GAAK,GACnC,CACF,CAEC,OAAOzZ,KAAKqZ,KAChB,qDAkOwB9E,KAAkChJ,GAKxD,OAJKgJ,IACHA,EAAQ,IAEVA,EAAMzZ,QAAQyQ,GACPgJ,CACT,iBAEM,SAAoBmF,EAAoBnF,KAAkChJ,GAO9E,OANKgJ,IACHA,EAAQ,IAENmF,GACFnF,EAAMzZ,QAAQyQ,GAETgJ,CACT,gBA8SM,SAAgBoF,EAA4BC,GAChD,MAAMC,EAAQ9gB,EAAQ4gB,EAAK7gB,IAAI,IAAI,GAAM,GAAMghB,OAAOvgB,IAASA,EAAK8S,WAAW,OAAO/S,IAAIC,GAAQA,EAAK8B,QAAQ,cAAe,KAE9H,OAAO,IAAIxC,OAAOghB,EAAM9e,KAAK,IAAK6e,EACpC,uCArBsB,CAAC7d,EAAWge,KAAmC,KAAOhe,KAAM,GAAGge,EAAEhe,oBD7MjF,SAAkBie,EAAaC,EAAmBC,EAAoBC,GAAkB,GAI5F,OAFAF,EAAYxd,EAAYwd;AAEjBD,EAAI3e,QAAQ,IAAIxC,OAAOohB,EAAW,KAAOE,EAAkB,IAAM,KAAMD,EAChF,uBGzMM,SAAuB9G,EAAegH,GAC1C,MAAMC,EAAOlH,GAAWC,GAExB,OAAOrB,GAAasI,EAAKrI,EAAGqI,EAAKpI,EAAGoI,EAAK1gB,EAAGygB,EAC9C,uDF3CM,SAAyB1gB,EAAQC,GACrC,OAAOwE,EAASxE,GAAKwE,EAASzE,EAChC,mGEuDM,SAAmB2e,EAAsBtD,EAAWC,EAAWsF,GACnE,GAAIvF,EAAI,GAAKC,EAAI,GAAKD,GAAKsD,EAAUpP,OAAS+L,GAAKqD,EAAUnP,OAC3D,OAEF,MAAMsL,EAAqC,GAA3BQ,EAAIqD,EAAUpP,MAAQ8L,GAEtCsD,EAAUtO,KAAKyK,IAAwB,SAAR8F,IAAuB,GACtDjC,EAAUtO,KAAKyK,EAAS,IAAe,MAAR8F,IAAwB,EACvDjC,EAAUtO,KAAKyK,EAAS,GAAe,IAAR8F,EAC/BjC,EAAUtO,KAAKyK,EAAS,IAAe,WAAR8F,IAAuB,GAAM,GAC9D;cFxJM,SAAgBC,GACpB,OAAO,IAAI7W,QAAQC,GAAW3B,WAAW2B,EAAS4W,GACpD,4BAofM,SAA+Blc,EAAQmc,EAAyCC,GAAU,GAC9F,MAAMC,EAASzb,EAAWub,GAAmBA,OAAkB3f,EAC/D,IAAIwC,EAAY,CAAA,EAEhB,MAAM6C,EAAU3B,OAAO2B,QAAQ7B,GAa/B,OAXAoc,EAAUzb,EAAUwb,GAAmBA,EAAkBC,EACzDva,EAAQya,KAAKD,GAAUnZ,GAEnBkZ,IAEFlc,OAAOC,KAAKH,GAAKhC,QAAQqC,UAAeL,EAAYK,IACpDrB,EAASgB,GAGX6B,EAAQ7D,QAAQ8D,GAAU9C,EAAe8C,EAAM,IAAMA,EAAM,IAEpD9C,CACT,2DD1HM,SAA+BrE,GACnC,OAAIA,EACK4C,EAAkB5C,GAAGyB,cAErBzB,CACX,+BAZM,SAA+BA,GACnC,OAAIA,EACK4C,EAAkB5C,GAAGmC,cAErBnC,CACX;kCAnBM,SAAoCA,GACxC,OAAIA,EACK2C,EAAuB3C,GAAGyB,cAE1BzB,CACX,oCAZM,SAAoCA,GACxC,OAAIA,EACK2C,EAAuB3C,GAAGmC,cAE1BnC,CACX,uBG7NM,SAAuBmQ,EAAmCmJ,EAAYC,EAAYqI,GACtFzR,EAAQwJ,YACRxJ,EAAQ2J,IAAIR,EAAIC,EAAIqI,EAAQ,EAAa,EAAVze,KAAK4W,IAAQ,GAC5C5J,EAAQ0R,SACR1R,EAAQ6J,WACV,wBAEM,SAAwB7J,EAAmCmJ,EAAYC,EAAYC,EAAYC,GACnGtJ,EAAQuJ,OACRvJ,EAAQwJ,YAERxJ,EAAQyJ,UAAUN,EAAKE,EAAID,EAAKE,GAChCtJ,EAAQ0J,MAAML,EAAIC,GAClBtJ,EAAQ2J,IAAI,EAAG,EAAG,EAAG,EAAa,EAAV3W,KAAK4W,IAAQ,GAErC5J,EAAQ8J,UACR9J,EAAQ0R,SACR1R,EAAQ6J,WACV,qBAEM,SAAqB7J,EAAmC2R,EAAYC,EAAYC,EAAYC,GAChG9R,EAAQwJ,YACRxJ,EAAQ+R,OAAOJ,EAAIC,GACnB5R,EAAQgS,OAAOH,EAAIC;AACnB9R,EAAQ0R,SACR1R,EAAQ6J,WACV,4BF6dmDvR,EAAeC,EAASpD,GAEzE,MAAMmZ,EAAI,IAAIjW,EAAUC,EAAOC,EAAMpD,GAIrC,OAFCmZ,EAAEpV,UAAkBE,OAASkV,EAAElV,OAEzBkV,EAAEpV,SACX,oBAjjBM,SAAuB1E,EAAYC,GAA4B,EAAOwd,GAAmB,GAC7F,GAAqB,kBAAVzd,EACT,OAAOA,EACJ,GAAa,MAATA,EACP,OAAOC,EACJ,GAAqB,iBAAVD,EACd,OAAOE,MAAMF,GAASC,EAAyB,IAAVD,EAClC,GAAqB,iBAAVA,EACd,QAASA,EACN,GAAIyd,GAA8B,KAAVzd,EAC3B,OAAO,EACJ,GAAI,oBAAoB1C,KAAK0C,IAAWC,GAA0B,KAAVD,EAC3D,OAAO,EACJ,GAAI,oBAAoB1C,KAAK0C,GAChC,OAAO,EAET,MAAM5B,EAAImC,OAAOP,GAEjB,OAAOE,MAAM9B,GAAK6B,EAAqB,IAAN7B,CACnC,wCAjCqCA,EAAWsf,EAAwBC,GACtE,MAAM1F,EAAe,CAAA;CAQrB,YANsB/a,IAAlBwgB,IACFzF,EAAQ2F,sBAAwBF,QAEZxgB,IAAlBygB,IACF1F,EAAQ4F,sBAAwBF,GAE3Bvf,EAAE0f,oBAAe5gB,EAAW+a,EACrC,qCDsaM,SAAqB7Z,EAAWyf,EAA+BE,EAAiBC,GAAc,GAClG,OAAO,IAAIC,KAAKC,aAAaH,GAAU,QAAS,CAAEF,wBAAuBG,gBAAeG,OAAO/f,EACjG,2BAEM,SAA2BA,EAAWggB,EAAkCL,EAAwBC,GAAc,GAClH,OAAO,IAAIC,KAAKC,aAAaH,GAAU,QAAS,CAAEK,2BAA0BJ,gBAAeG,OAAO/f,EACpG,sBAvTM,SAAsB/C,GAC1B,OAAOA,EAAEqC,QAAQ9C,EAAa+D,GAAQtB,EAAsBsB,GAC9D;oBAeM,SAAsBtD,EAAW4c,GACrCA,EAAUA,GAAW,CAAA,EAErB,IAAIoG,EAAczgB,EACd0gB,EAAWxgB,EACf,MAAMygB,EAAsB,OAAO9T,KAAKpP,GAAK,IAAII,OAC3C+iB,EAAoBnjB,EAAEI,QAAW,OAAOgP,KAAKpP,GAAK,IAAII,QAAU,GA2CtE,OAzCIwc,EAAQwG,aACVJ,EAAc,IAAIxgB,IAAIwgB,GACtBpG,EAAQwG,WAAW/f,QAAQC,IACrBA,EAAK+P,WAAW,KAClB2P,EAAYnD,OAAOvc,EAAKpB,UAAU,IAElC8gB,EAAY3b,IAAI/D,MAIlBsZ,EAAQyG,UACVJ,EAAW,IAAIvgB,IAAIugB,GACnBrG,EAAQyG,QAAQhgB,QAAQC,IACtB,MAAMggB,EAASlhB,EAAqBkB,GAEhCA,EAAK+P,WAAW,KAClB4P,EAASpD,OAAOyD,EAAOphB,UAAU,IAEjC+gB,EAAS1f,IAAI+f,EAAQhgB,MAuBpBtD,EAAEqC,QAAQ9C,EAnBG,CAAC+D,EAAckY,KACjC,GAAIoB,GAAS2G,aAAejhB,EAAegB,GACzC,OAAOA,EAET,MAAMggB,EAASlhB,EAAqBkB,GAEpC,GAAI2f,EAAStc,IAAI2c,GACf,OAAOL,EAASrc,IAAI0c,GAEtBhgB,EAAOtB,EAAsBsB;CAO7B,QALsBkY,IAAW0H,GAAsB1H,IAAW2H,EAAoB7f,EAAKlD,SAEtE4iB,EAAYrc,IAAI2c,KACnChgB,EAAOA,EAAKnB,eAEPmB,GAIX,qBCvHM,SAAqBqB,EAAYC,EAAe,EAAGH,EAAQ,IAC/D,MAAqB,iBAAVE,IAAuBE,MAAMF,IAAWG,SAASH,GAGnDD,EAAMC,EAAOC,EAAcH,GAF3BG,CAGX,iCA2B8BD,EAAYC,EAAe,GACvD,MAAqB,iBAAVD,IAAuBE,MAAMF,IAAWG,SAASH,GAGnDQ,EAASR,EAAOC,GAFhBA,CAGX,2EA4DM,SAAiB2W,GACrB,OAAIA,GAAS5V,EAAQ4V,IAAUA,EAAMnb,OAAS,EACrCmb,OAEP,CACJ"}