{"version":3,"file":"login.js","sources":["../../Script/base/Store.ts","../../Script/Login/main.ts","../../Script/Shared/Helpers.ts"],"sourcesContent":["export interface UserLinking {\n d: number,\n u: number\n}\n\ninterface StorageItem {\n e: number\n d: T\n}\n\ninterface ExpiryInfo {\n k: string,\n l: number,\n e: number\n}\n\ntype NestedGetDataFunction = (key: TKey, parentKey: TParentKey, ...args: any[]) => Promise\nexport class NestedPageCache {\n private readonly c: PageCache>;\n\n constructor(getData: NestedGetDataFunction) {\n this.c = new PageCache>(key => new PageCacheAsync(getData));\n }\n\n public get(parentKey: TParentKey, key: TKey, ...args: any[]) {\n return this.c.get(parentKey).get(key, parentKey, args);\n }\n}\n\ntype GetDataFunction = (key: TKey) => TValue;\nexport class PageCache {\n public readonly c: Map;\n private readonly g: GetDataFunction;\n\n public constructor(getData: GetDataFunction) {\n this.c = new Map();\n this.g = getData;\n }\n\n public get(key: TKey) {\n const cache = this.c;\n let value = cache.get(key)\n if (value !== undefined) {\n return value;\n }\n\n value = this.g(key);\n cache.set(key, value);\n return value;\n }\n}\n\ntype GetDataPromiseFunction = (key: TKey, other: TInfo, ...args: any[]) => Promise;\nexport class PageCacheAsync {\n public readonly c: Map>;\n private readonly g: GetDataPromiseFunction;\n\n public constructor(getData: GetDataPromiseFunction) {\n this.c = new Map();\n this.g = getData;\n }\n\n public get(key: TKey, other: TInfo, ...args: any[]) {\n const cache = this.c;\n const value = cache.get(key)\n if (value) {\n return value;\n }\n\n const promise = this.g(key, other, args);\n cache.set(key, promise);\n promise.catch(_ => cache.delete(key)); // If there is an error, delete the key so we don't cache the error forever\n return promise;\n }\n}\n\nconst enum Constants {\n LINK_KEY = \"link\",\n PREFIX = \"sc|\",\n NEWSFEED = \"sc|nf|\"\n}\nexport abstract class Store {\n private static pre: string\n private static maxE: number\n\n private static map: Map>\n // Hack because Apple doens't support static constructors\n static #init = (() => {\n Store.map = new Map();\n Store.maxE = Math.floor(8.64e15 / 60000);\n const currentLink = localStorage.getItem(Constants.LINK_KEY);\n if (currentLink) {\n Store.pre = Constants.PREFIX + currentLink + \":\"\n }\n })()\n\n public static setLink(dbId: number, userLinkId: number): void {\n const linkValue = buildLinkValue(dbId, userLinkId);\n // When a new link is set we update the prefix with the new linkValue.\n // This ends up changing cache buckets, and caching can be maintained across linking\n const newPre = Constants.PREFIX + linkValue + \":\";\n if (Store.pre && newPre !== Store.pre) {\n // If the new prefix is not the same as the old prefix, clear out the per page cache.\n Store.map.clear();\n }\n\n Store.pre = newPre;\n Store.setLocalStorage(Constants.LINK_KEY, linkValue);\n }\n\n public static linkMatches(dbId: number, userLinkId: number) {\n const link = localStorage.getItem(Constants.LINK_KEY);\n return link && link == buildLinkValue(dbId, userLinkId);\n }\n\n public static getLink(): UserLinking | undefined {\n return getLink();\n }\n\n public static persist(key: string, data: T) {\n // The expiry gets set to be the max possible ES date (epoch + 1e8 days)\n const storageItem = {\n e: Store.maxE,\n d: data\n };\n\n // The data is not being set into the per page cache, because this is long term storage and reading it out again on the same page is unlikely\n // Doing so would end up getting it from localStorage anyways.\n Store.setLocalStorage(Store.pre + key, JSON.stringify(storageItem));\n }\n\n public static set_nf(key: string) {\n // Set to last one month\n Store.setLocalStorage(Constants.NEWSFEED + key, '{\"e\":' + (getCurrentTime() + 44640) + '}')\n }\n\n public static set(key: string, data: T, expiryInMinutes: number) {\n const storageItem = {\n e: getCurrentTime() + expiryInMinutes,\n d: data\n };\n\n Store.map.set(key, storageItem);\n Store.setLocalStorage(Store.pre + key, JSON.stringify(storageItem));\n }\n\n public static get_nf(key: string): boolean {\n const json = localStorage.getItem(Constants.NEWSFEED + key);\n if (json) {\n return Store.jsonParse(json) !== undefined;\n }\n\n return false;\n }\n\n public static get(key: string): T | undefined {\n let storageItem = Store.map.get(key);\n if (storageItem) {\n if (Store.expired(storageItem)) {\n Store.remove(key);\n return;\n }\n\n return storageItem.d;\n }\n\n const json = localStorage.getItem(Store.pre + key);\n if (!json) {\n return;\n }\n\n const value = Store.jsonParse(json);\n if (!value) {\n // If value is null that means it had expired.\n // Since it has expired we should remove it from cache so clean up space\n Store.remove(key);\n return;\n }\n\n // A value was returned, store it in the local map to save deserialization on repeated lookup\n Store.map.set(key, value);\n return value.d;\n }\n\n public static expire(): void {\n runOnKeys(key => {\n const json = localStorage.getItem(key) as string;\n if (!Store.jsonParse(json)) {\n Store.removeByCacheKey(key);\n }\n });\n }\n\n public static clear(): void {\n Store.map.clear();\n const eKey = '{\"e\":' + Store.maxE; + \",\";\n\n runOnKeys(key => {\n if (!key.startsWith(Constants.NEWSFEED)) {\n const json = localStorage.getItem(key) as string;\n if (!json.startsWith(eKey)) {\n localStorage.removeItem(key);\n }\n }\n });\n\n // Parsing it as just is multiple times slower, but it is more robust. We could always switch back to that if for some reason we need to use a very specific key...\n /*runOnKeys(key => {\n const json = localStorage.getItem(key) as string;\n const item = JSON.parse(json) as StorageItem;\n if (item.e != Storage.maxE) {\n localStorage.removeItem(key);\n }\n });*/\n }\n\n public static clearLink(): void {\n Store.map.clear();\n const key = Constants.PREFIX + localStorage.getItem(Constants.LINK_KEY);\n runOnKeys(key => {\n if (key.startsWith(key)) {\n localStorage.removeItem(key);\n }\n });\n }\n\n public static clearAll(): void {\n Store.map.clear();\n runOnKeys(key => {\n localStorage.removeItem(key);\n });\n }\n\n public static remove(key: string) {\n Store.map.delete(key);\n localStorage.removeItem(Store.pre + key);\n }\n\n // ----------\n // Private\n // ----------\n\n private static jsonParse(item: string): StorageItem | undefined {\n const json = JSON.parse(item) as StorageItem;\n if (!this.expired(json)) {\n return json;\n }\n }\n\n private static expired(item: StorageItem): boolean {\n return getCurrentTime() >= item.e;\n }\n\n private static removeByCacheKey(key: string) {\n localStorage.removeItem(key);\n const index = key.indexOf(\":\");\n if (index >= 0) {\n Store.map.delete(key.substr(index + 1));\n }\n }\n\n private static setLocalStorage(key: string, value: string): boolean {\n try {\n localStorage.setItem(key, value);\n } catch (e) {\n // Check for the localStorage being full\n // If localStorage is full get a list of all items in the storage, and remove one that is closest to expiry until we have enough space to fit the new key\n if (e.name === 'QUOTA_EXCEEDED_ERR' ||\n e.name === 'NS_ERROR_DOM_QUOTA_REACHED' ||\n e.name === 'QuotaExceededError') {\n const expiryItems: Array = [];\n runOnKeys(key => {\n const item = localStorage.getItem(key) as string;\n\n expiryItems.push({\n k: key,\n l: item.length,\n e: (JSON.parse(item) as StorageItem).e\n })\n })\n\n expiryItems.sort((a, b) => b.e - a.e);\n\n let sizeRequired = value.length;\n let info: ExpiryInfo | undefined;\n while ((info = expiryItems.pop()) && sizeRequired > 0) {\n localStorage.removeItem(info.k);\n sizeRequired -= info.l;\n }\n\n try {\n localStorage.setItem(key, value);\n return true;\n } catch {\n // If we should have space and we still are not able to fit, we have an issue, just return that it was a failure.\n }\n }\n return false;\n }\n return true;\n }\n}\n\nfunction buildLinkValue(dbId: number, linkId: number) {\n return dbId + \"|\" + linkId;\n}\n\nfunction runOnKeys(func: (string) => void): void {\n for (var i = localStorage.length - 1; i >= 0; --i) {\n const key = localStorage.key(i);\n if (key?.startsWith(Constants.PREFIX)) {\n func(key);\n }\n }\n}\n\nfunction getCurrentTime(): number {\n // 60000 is the resolution in milliseconds.\n // This truncates the timestamp to have a resolution of 1 minute.\n return Math.floor((new Date().getTime()) / 60000);\n}\n\nexport function getLink() {\n const link = localStorage.getItem(Constants.LINK_KEY);\n if (link) {\n const sepIndex = link.indexOf(\"|\");\n return {\n d: parseInt(link.substr(0, sepIndex)),\n u: parseInt(link.substr(sepIndex + 1))\n }\n }\n}\n","import { Store } from \"../base/Store\"\nimport { getFirstFromClassName } from \"@s/Helpers\";\n\nvar uri = window.location.href;\nvar qs = uri.indexOf('?');\nvar path = \"\";\nif (qs > 0) {\n path = uri.substring(qs)\n window.history.replaceState({}, document.title, uri.substring(0, qs));\n}\n\nconst button = document.getElementById(\"login-button\") as HTMLButtonElement;\nif (storageAvailable()) {\n button.disabled = false;\n Store.clear();\n let sso = localStorage.getItem(\"sso\");\n if (sso) {\n const user = Store.getLink();\n if (user && sessionStorage.getItem(\"in\") === \"1\") {\n path += path.length === 0 ? \"?\" : \"&\"\n path += \"L=\" + user.u + \"&D=\" + user.d;\n }\n window.location.href = \"/Saml/Login/\" + sso + path;\n }\n} else {\n const storage = getFirstFromClassName(\"storage\") as HTMLSpanElement;\n storage.classList.remove(\"storage\");\n}\n\nfunction storageAvailable() {\n try {\n const t = \"__test__\";\n localStorage.setItem(t, t)\n localStorage.removeItem(t)\n return true;\n }\n catch (e) {\n return e instanceof DOMException && (\n // everything except Firefox\n e.code === 22 ||\n // Firefox\n e.code === 1014 ||\n // test name field too, because code might not be present\n // everything except Firefox\n e.name === 'QuotaExceededError' ||\n // Firefox\n e.name === 'NS_ERROR_DOM_QUOTA_REACHED') &&\n // acknowledge QuotaExceededError only if there's something already stored\n (localStorage && localStorage.length !== 0);\n }\n}","import { KEYCODES } from \"./Keycodes\";\n\nexport function appendElement(parent: Element | DocumentFragment, tag: K) {\n const element = document.createElement(tag)\n parent.appendChild(element);\n return element\n}\n\nexport function appendElementWithClass(parent: Element | DocumentFragment, tag: K, className: string) {\n const element = document.createElement(tag)\n element.className = className;\n parent.appendChild(element);\n return element\n}\n\ninterface LoadingElement extends Element {\n load: boolean;\n}\nexport function bindLoadingButton(btn: HTMLButtonElement, onClick: (btn: HTMLButtonElement, e: MouseEvent) => Promise) {\n btn.addEventListener(\"click\", createLoadingButtonEvent(onClick));\n}\n\nexport function bindSharedLoadingButton(btn: HTMLButtonElement, loadingContext: ButtonLoadingContext, onClick: (btn: HTMLButtonElement, e: MouseEvent) => Promise) {\n (btn).cb = onClick;\n btn.addEventListener(\"click\", loadingContext.m);\n}\n\nexport function createLoadingButtonEvent(onClick: (btn: HTMLButtonElement, e: MouseEvent) => Promise): (e: MouseEvent) => void {\n return (e: MouseEvent) => {\n const btn = e.target as LoadingElement & HTMLButtonElement;\n if (!btn.load) {\n btn.load = true;\n loadPromise(btn, onClick(btn, e)).finally(() => {\n btn.load = false\n });\n }\n };\n}\n\nexport function addClick(element: Element, event: (target: HTMLElement) => void, stopPropagation?: boolean) {\n element.addEventListener(\"click\", (e: MouseEvent) => {\n event(e.target as HTMLElement)\n if (stopPropagation) {\n e.stopPropagation();\n }\n });\n element.addEventListener(\"keyup\", (e: KeyboardEvent) => {\n if (e.keyCode == KEYCODES.ENTER) {\n event(e.target as HTMLElement);\n }\n if (stopPropagation) {\n e.stopPropagation();\n }\n });\n}\n\nexport function loadPromise(element: Element, promise: Promise) {\n element.classList.add(\"c-loading\");\n return promise.finally(() => element.classList.remove(\"c-loading\"));\n}\n\nexport function removeElementWithClass(element: Element, className: string) {\n const matching = element.getElementsByClassName(className);\n for (var i = 0; i < matching.length; i++) {\n matching[i].remove();\n }\n}\n\nexport function removeFromParent(element: Element): void {\n const parent = element.parentElement;\n if (parent) {\n parent.removeChild(element);\n }\n}\n\nexport function createDiv(className: string): HTMLDivElement {\n const div = document.createElement(\"div\");\n div.className = className;\n return div;\n}\n\nexport function createSpan(className: string): HTMLSpanElement {\n const span = document.createElement(\"span\");\n span.className = className;\n return span;\n}\n\nexport function createLabel(className: string): HTMLLabelElement {\n const span = document.createElement(\"label\");\n span.className = className;\n return span;\n}\n\nexport function createButton(text: string, func: (target: HTMLElement) => void): HTMLButtonElement {\n var button = document.createElement(\"button\");\n button.className = \"c-button\";\n button.textContent = text;\n addClick(button, func);\n return button;\n}\n\nexport function createLoadingButton(text: string, onClick: (btn: HTMLButtonElement, e: MouseEvent) => Promise): HTMLButtonElement {\n var button = document.createElement(\"button\");\n button.className = \"c-button\";\n button.textContent = text;\n bindLoadingButton(button, onClick);\n return button;\n}\n\ninterface ButtonLoadingContext {\n l?: boolean\n m: (e: MouseEvent) => void\n}\n\ninterface LoadingContextButton extends HTMLButtonElement {\n lc: ButtonLoadingContext\n cb: (btn: HTMLElement, e: MouseEvent) => Promise\n}\n\nexport function createLoadingContextForButton(): ButtonLoadingContext {\n const context: ButtonLoadingContext = {\n m: (e: MouseEvent) => {\n const btn = e.target as LoadingContextButton;\n if (!context.l) {\n context.l = true;\n loadPromise(btn, btn.cb(btn, e)).finally(() => context.l = false);\n }\n }\n }\n return context;\n}\n\nexport function createSharedLoadingButton(text: string, loadingContext: ButtonLoadingContext, onClick: (btn: HTMLButtonElement, e: MouseEvent) => Promise): HTMLButtonElement {\n const button = document.createElement(\"button\");\n button.className = \"c-button\";\n button.textContent = text;\n bindSharedLoadingButton(button, loadingContext, onClick);\n return button;\n}\n\nexport function getFirstFromClassName(className: string): T | undefined {\n const searchResult = document.getElementsByClassName(className) as HTMLCollectionOf;\n if (searchResult.length > 0) {\n return searchResult[0];\n }\n}\n\nexport function getFirstInParentFromClassName(parent: Element, className: string): T | undefined {\n const searchResult = parent.getElementsByClassName(className) as HTMLCollectionOf;\n if (searchResult.length > 0) {\n return searchResult[0];\n }\n}\n\nexport function getFirstInParentFromTagName(parent: Element, tagName: string): Element | undefined {\n const searchResult = parent.getElementsByTagName(tagName);\n if (searchResult.length > 0) {\n return searchResult[0];\n }\n}\n\nexport function createTd(tr: HTMLTableRowElement, content: string): HTMLTableCellElement {\n const td = document.createElement(\"td\");\n tr.appendChild(td);\n td.textContent = content;\n return td;\n}\n\nexport function createTh(tr: HTMLTableRowElement, content: string): HTMLTableCellElement {\n const th = document.createElement(\"th\");\n tr.appendChild(th);\n th.textContent = content;\n return th;\n}\n\nexport function createClassTd(tr: HTMLTableRowElement, content: string, className: string): HTMLTableCellElement {\n const td = document.createElement(\"td\");\n td.className = className\n tr.appendChild(td);\n td.textContent = content;\n return td;\n}\n\nexport function createClassContentTd(tr: HTMLTableRowElement, content: Element | DocumentFragment, className: string): HTMLTableCellElement {\n const td = document.createElement(\"td\");\n td.className = className\n tr.appendChild(td);\n td.appendChild(content);\n return td;\n}\n\nexport function createCheckbox(container: Element, labelText: string, id: string): HTMLInputElement {\n const input = document.createElement(\"input\");\n input.type = \"checkbox\";\n input.id = id;\n input.className = \"c-checkbox\";\n container.appendChild(input);\n\n const label = document.createElement(\"label\");\n label.textContent = labelText;\n label.htmlFor = id;\n container.appendChild(label);\n\n return input;\n}\n\nexport function createTr(section: HTMLTableSectionElement): HTMLTableRowElement {\n const row = document.createElement(\"tr\");\n section.appendChild(row);\n return row;\n}\n\nexport function parseDatasetToId(element: HTMLElement, attribute: string): number {\n return parseInt(parseDataset(element, attribute));\n}\n\nexport function parseDataset(element: HTMLElement, attribute: string): string {\n const value = element.dataset[attribute] as string;\n delete element.dataset[attribute];\n return value;\n}\n\nexport function parseDatasetAsJson(element: HTMLElement, attribute: string) {\n const value = element.dataset[attribute] as string;\n delete element.dataset[attribute];\n return JSON.parse(value) as T;\n}\n\nexport function parseDateToLocalTime(date: string): Date {\n return new Date(date + \" 00:00:00\");\n}\n\nexport function parseDateToUtc(date: string): Date {\n return new Date(date + \" 00:00:00Z\");\n}\n"],"names":["Store","static","map","Map","maxE","Math","floor","currentLink","localStorage","getItem","pre","dbId","userLinkId","linkValue","buildLinkValue","newPre","clear","setLocalStorage","link","sepIndex","indexOf","d","parseInt","substr","u","getLink","key","data","storageItem","e","JSON","stringify","getCurrentTime","expiryInMinutes","set","json","undefined","jsonParse","get","expired","remove","value","runOnKeys","removeByCacheKey","eKey","startsWith","removeItem","delete","item","parse","this","index","setItem","name","expiryItems","push","k","l","length","sort","a","b","info","sizeRequired","pop","linkId","func","i","Date","getTime","uri","window","location","href","qs","path","substring","history","replaceState","document","title","button","getElementById","t","DOMException","code","storageAvailable","disabled","sso","user","sessionStorage","className","searchResult","getElementsByClassName","getFirstFromClassName","classList"],"mappings":"yBAiFA,MAAsBA,EACVC,WACAA,YAEAA,WAERA,SAAe,MACXD,EAAME,IAAM,IAAIC,IAChBH,EAAMI,KAAOC,KAAKC,MAAM,OACxB,MAAMC,EAAcC,aAAaC,gBAC7BF,IACAP,EAAMU,IAAM,MAAmBH,EAAc,IAEpD,EAPc,GASRN,eAAeU,EAAcC,GAChC,MAAMC,EAAYC,EAAeH,EAAMC,GAGjCG,EAAS,MAAmBF,EAAY,IAC1Cb,EAAMU,KAAOK,IAAWf,EAAMU,KAE9BV,EAAME,IAAIc,QAGdhB,EAAMU,IAAMK,EACZf,EAAMiB,gBAAoC,OAAAJ,EAC7C,CAEMZ,mBAAmBU,EAAcC,GACpC,MAAMM,EAAOV,aAAaC,gBAC1B,OAAOS,GAAQA,GAAQJ,EAAeH,EAAMC,EAC/C,CAEMX,iBACH,kBA+MJ,MAAMiB,EAAOV,aAAaC,gBAC1B,GAAIS,EAAM,CACN,MAAMC,EAAWD,EAAKE,QAAQ,KAC9B,MAAO,CACHC,EAAGC,SAASJ,EAAKK,OAAO,EAAGJ,IAC3BK,EAAGF,SAASJ,EAAKK,OAAOJ,EAAW,IAE1C,CACL,CAvNeM,EACV,CAEMxB,eAAkByB,EAAaC,GAElC,MAAMC,EAAc,CAChBC,EAAG7B,EAAMI,KACTiB,EAAGM,GAKP3B,EAAMiB,gBAAgBjB,EAAMU,IAAMgB,EAAKI,KAAKC,UAAUH,GACzD,CAEM3B,cAAcyB,GAEjB1B,EAAMiB,gBAAgB,SAAqBS,EAAK,SAAWM,IAAmB,OAAS,IAC1F,CAEM/B,WAAcyB,EAAaC,EAASM,GACvC,MAAML,EAAc,CAChBC,EAAGG,IAAmBC,EACtBZ,EAAGM,GAGP3B,EAAME,IAAIgC,IAAIR,EAAKE,GACnB5B,EAAMiB,gBAAgBjB,EAAMU,IAAMgB,EAAKI,KAAKC,UAAUH,GACzD,CAEM3B,cAAcyB,GACjB,MAAMS,EAAO3B,aAAaC,QAAQ,SAAqBiB,GACvD,QAAIS,QACiCC,IAA1BpC,EAAMqC,UAAUF,EAI9B,CAEMlC,WAAcyB,GACjB,IAAIE,EAAc5B,EAAME,IAAIoC,IAAIZ,GAChC,GAAIE,EACA,OAAI5B,EAAMuC,QAAQX,QACd5B,EAAMwC,OAAOd,GAIVE,EAAYP,EAGvB,MAAMc,EAAO3B,aAAaC,QAAQT,EAAMU,IAAMgB,GAC9C,IAAKS,EACD,OAGJ,MAAMM,EAAQzC,EAAMqC,UAAaF,GACjC,GAAKM,EASL,OADAzC,EAAME,IAAIgC,IAAIR,EAAKe,GACZA,EAAMpB,EANTrB,EAAMwC,OAAOd,EAOpB,CAEMzB,gBACHyC,GAAUhB,IACN,MAAMS,EAAO3B,aAAaC,QAAQiB,GAC7B1B,EAAMqC,UAAUF,IACjBnC,EAAM2C,iBAAiBjB,EAC1B,GAER,CAEMzB,eACHD,EAAME,IAAIc,QACV,MAAM4B,EAAO,QAAU5C,EAAMI,KAE7BsC,GAAUhB,IACN,IAAKA,EAAImB,qBAAgC,CACxBrC,aAAaC,QAAQiB,GACxBmB,WAAWD,IACjBpC,aAAasC,WAAWpB,EAE/B,IAWR,CAEMzB,mBACHD,EAAME,IAAIc,QACqBR,aAAaC,gBAC5CiC,GAAUhB,IACFA,EAAImB,WAAWnB,IACflB,aAAasC,WAAWpB,EAC3B,GAER,CAEMzB,kBACHD,EAAME,IAAIc,QACV0B,GAAUhB,IACNlB,aAAasC,WAAWpB,EAAI,GAEnC,CAEMzB,cAAcyB,GACjB1B,EAAME,IAAI6C,OAAOrB,GACjBlB,aAAasC,WAAW9C,EAAMU,IAAMgB,EACvC,CAMOzB,iBAAoB+C,GACxB,MAAMb,EAAOL,KAAKmB,MAAMD,GACxB,IAAKE,KAAKX,QAAQJ,GACd,OAAOA,CAEd,CAEOlC,eAAkB+C,GACtB,OAAOhB,KAAoBgB,EAAKnB,CACnC,CAEO5B,wBAAwByB,GAC5BlB,aAAasC,WAAWpB,GACxB,MAAMyB,EAAQzB,EAAIN,QAAQ,KACtB+B,GAAS,GACTnD,EAAME,IAAI6C,OAAOrB,EAAIH,OAAO4B,EAAQ,GAE3C,CAEOlD,uBAAuByB,EAAae,GACxC,IACIjC,aAAa4C,QAAQ1B,EAAKe,EAC7B,CAAC,MAAOZ,GAGL,GAAe,uBAAXA,EAAEwB,MACS,+BAAXxB,EAAEwB,MACS,uBAAXxB,EAAEwB,KAA+B,CACjC,MAAMC,EAAiC,GACvCZ,GAAUhB,IACN,MAAMsB,EAAOxC,aAAaC,QAAQiB,GAElC4B,EAAYC,KAAK,CACbC,EAAG9B,EACH+B,EAAGT,EAAKU,OACR7B,EAAIC,KAAKmB,MAAMD,GAA2BnB,GAC5C,IAGNyB,EAAYK,MAAK,CAACC,EAAGC,IAAMA,EAAEhC,EAAI+B,EAAE/B,IAEnC,IACIiC,EADAC,EAAetB,EAAMiB,OAEzB,MAAQI,EAAOR,EAAYU,QAAUD,EAAe,GAChDvD,aAAasC,WAAWgB,EAAKN,GAC7BO,GAAgBD,EAAKL,EAGzB,IAEI,OADAjD,aAAa4C,QAAQ1B,EAAKe,IACnB,CACV,CAAC,MAED,CACJ,CACD,OAAO,CACV,CACD,OAAO,CACV,EAGL,SAAS3B,EAAeH,EAAcsD,GAClC,OAAOtD,EAAO,IAAMsD,CACxB,CAEA,SAASvB,EAAUwB,GACf,IAAK,IAAIC,EAAI3D,aAAakD,OAAS,EAAGS,GAAK,IAAKA,EAAG,CAC/C,MAAMzC,EAAMlB,aAAakB,IAAIyC,GACzBzC,GAAKmB,WAAU,QACfqB,EAAKxC,EAEZ,CACL,CAEA,SAASM,IAGL,OAAO3B,KAAKC,OAAO,IAAI8D,MAAOC,UAAa,IAC/C,CC7TA,IAAIC,EAAMC,OAAOC,SAASC,KACtBC,EAAKJ,EAAIlD,QAAQ,KACjBuD,EAAO,GACPD,EAAK,IACLC,EAAOL,EAAIM,UAAUF,GACrBH,OAAOM,QAAQC,aAAa,CAAA,EAAIC,SAASC,MAAOV,EAAIM,UAAU,EAAGF,KAGrE,MAAMO,EAASF,SAASG,eAAe,gBACvC,GAiBA,WACI,IACI,MAAMC,EAAI,WAGV,OAFA3E,aAAa4C,QAAQ+B,EAAGA,GACxB3E,aAAasC,WAAWqC,IACjB,CACV,CACD,MAAOtD,GACH,OAAOA,aAAauD,eAEL,KAAXvD,EAAEwD,MAES,OAAXxD,EAAEwD,MAGS,uBAAXxD,EAAEwB,MAES,+BAAXxB,EAAEwB,OAED7C,cAAwC,IAAxBA,aAAakD,MACrC,CACL,CAtCI4B,GAAoB,CACpBL,EAAOM,UAAW,EAClBvF,EAAMgB,QACN,IAAIwE,EAAMhF,aAAaC,QAAQ,OAC/B,GAAI+E,EAAK,CACL,MAAMC,EAAOzF,EAAMyB,UACfgE,GAAyC,MAAjCC,eAAejF,QAAQ,QAC/BkE,GAAwB,IAAhBA,EAAKjB,OAAe,IAAM,IAClCiB,GAAQ,KAAOc,EAAKjE,EAAI,MAAQiE,EAAKpE,GAEzCkD,OAAOC,SAASC,KAAO,eAAiBe,EAAMb,CACjD,CACJ,KAAM,ECoHD,SAAmDgB,GACrD,MAAMC,EAAeb,SAASc,uBAAuBF,GACrD,GAAIC,EAAalC,OAAS,EACtB,OAAOkC,EAAa,EAE5B,EDxHoBE,CAAsB,WAC9BC,UAAUvD,OAAO,UAC5B"}