wiki-saikou
Version:
The library provides the out of box accessing to MediaWiki API in both browsers & Node.js, and the syntax is very similar to vanilla `new mw.Api()`. TypeScript definition included~
1 lines • 16.8 kB
Source Map (JSON)
{"version":3,"file":"node.mjs","sources":["../src/node.ts"],"sourcesContent":["import type { FexiosConfigs, FexiosContext, FexiosFinalContext } from 'fexios'\nimport { WikiSaikouCore, WikiSaikouInitConfig } from './WikiSaikou.js'\nimport { CookieJar, type CookieJarItem, pluginCookieJar } from 'fexios/plugins'\nimport { resolveLegacyCtor } from './utils/resolveLegacyCtor.js'\nimport { MwApiParams, MwApiResponse } from './types.js'\nimport {\n MediaWikiApiError,\n WikiSaikouError,\n WikiSaikouErrorCode,\n} from './models/errors.js'\nimport { FexiosHookHandler } from 'fexios/types'\n\n// re-export for library users\nexport * from './WikiSaikou.js'\nexport { CookieJar, CookieJarItem }\n\n/**\n * WikiSaikou\n * @description Standalone MediaWiki API SDK with `mw.Api`-like API in any environments\n * @author Dragon-Fish <dragon-fish@qq.com>\n * @license MIT\n */\nexport class MediaWikiApi extends WikiSaikouCore {\n private autoReloginEnabled = false\n private loginCredentials?: {\n lgname: string\n lgpassword: string\n username: string\n autoReloginRetries: number\n }\n\n constructor(config?: WikiSaikouInitConfig)\n /** @deprecated Use `new MediaWikiApi(config)` instead */\n constructor(\n baseURL: string,\n options?: Partial<FexiosConfigs>,\n defaultParams?: MwApiParams\n )\n constructor(\n configOrBaseURL?: WikiSaikouInitConfig | string,\n defaultOptions?: Partial<FexiosConfigs>,\n defaultParams?: MwApiParams\n ) {\n const config = resolveLegacyCtor(\n configOrBaseURL,\n defaultOptions,\n defaultParams\n )\n super(config)\n this.request.plugin(pluginCookieJar)\n this.request.on('beforeRequest', (ctx) => this.handleBeforeRequest(ctx))\n this.request.on('afterResponse', (ctx) => this.handleAfterResponse(ctx))\n }\n\n private canAutoRelogin() {\n return Boolean(this.autoReloginEnabled && this.loginCredentials?.username)\n }\n\n private getAssertUser() {\n return this.loginCredentials?.username\n }\n\n private getAutoReloginRetries() {\n return this.loginCredentials?.autoReloginRetries ?? 3\n }\n\n private getParam(data: any, key: string): unknown {\n if (!data) return undefined\n if (data instanceof URLSearchParams) {\n return data.get(key)\n }\n if (typeof FormData !== 'undefined' && data instanceof FormData) {\n return data.get(key)\n }\n return data[key]\n }\n\n private hasParam(data: any, key: string): boolean {\n if (!data) return false\n if (data instanceof URLSearchParams) {\n return data.has(key)\n }\n if (typeof FormData !== 'undefined' && data instanceof FormData) {\n return data.has(key)\n }\n return data[key] !== undefined\n }\n\n private setParam(data: any, key: string, value: string): void {\n if (data instanceof URLSearchParams) {\n data.set(key, value)\n } else if (typeof FormData !== 'undefined' && data instanceof FormData) {\n data.set(key, value)\n } else {\n data[key] = value\n }\n }\n\n private getAction(query?: unknown, body?: unknown) {\n const action =\n this.getParam(query, 'action') ?? this.getParam(body, 'action')\n return action === undefined ? undefined : String(action)\n }\n\n private toStringArray(value: unknown): string[] {\n if (value === undefined || value === null) return []\n if (Array.isArray(value)) {\n return value.map((item) => String(item)).filter(Boolean)\n }\n return String(value)\n .split('|')\n .map((item) => item.trim())\n .filter(Boolean)\n }\n\n private isLoginTokenRequest(query?: unknown, body?: unknown): boolean {\n const check = (data: unknown) => {\n if (!data) return false\n const action = this.getParam(data, 'action')\n // action=query is required for meta=tokens\n if (action && String(action) !== 'query') return false\n // If action is implicit (undefined), we assume it's NOT query-like enough for this check?\n // MediaWiki requires action=query for tokens.\n if (!action) return false\n\n const meta = this.toStringArray(this.getParam(data, 'meta'))\n if (!meta.includes('tokens')) return false\n\n const types = this.toStringArray(this.getParam(data, 'type'))\n return types.includes('login')\n }\n\n return check(query) || check(body)\n }\n\n private shouldSkipAutoRelogin(query?: unknown, body?: unknown) {\n const action = this.getAction(query, body)\n if (action === 'login') return true\n if (this.isLoginTokenRequest(query, body)) {\n return true\n }\n return false\n }\n\n private isAssertUserFailed(data: any) {\n const isAssertFailedCode = (code: string) =>\n code === 'assertuserfailed' || code === 'assertnameduserfailed'\n if (MediaWikiApiError.is(data)) {\n return data.errors.some((error) => isAssertFailedCode(error.code))\n }\n return WikiSaikouError.extractMediaWikiApiErrors(data).some((error) =>\n isAssertFailedCode(error.code)\n )\n }\n\n private async reloginIfNeeded() {\n if (!this.canAutoRelogin() || !this.loginCredentials) return\n await this.login(\n this.loginCredentials.lgname,\n this.loginCredentials.lgpassword,\n void 0,\n {\n autoRelogin: true,\n autoReloginRetries: this.loginCredentials.autoReloginRetries,\n }\n )\n }\n\n get cookieJar() {\n return this.request.cookieJar!\n }\n\n private handleBeforeRequest(\n ctx: FexiosContext\n ): ReturnType<FexiosHookHandler<'beforeRequest'>> {\n if (!this.canAutoRelogin()) return ctx\n const { query, body } = ctx.request\n\n if (this.shouldSkipAutoRelogin(query, body)) return ctx\n\n if (\n this.hasParam(query, 'assertuser') ||\n this.hasParam(body, 'assertuser')\n ) {\n return ctx\n }\n\n const assertUser = this.getAssertUser()!\n\n if (body !== undefined && body !== null) {\n this.setParam(body, 'assertuser', assertUser)\n } else {\n if (!ctx.request.query) {\n ctx.request.query = {}\n }\n this.setParam(ctx.request.query, 'assertuser', assertUser)\n }\n return ctx\n }\n\n private async handleAfterResponse<T>(\n ctx: FexiosFinalContext<MwApiResponse<T>>\n ): Promise<FexiosFinalContext<MwApiResponse<T>> | Response> {\n if (!this.canAutoRelogin()) return ctx\n const { query, body } = ctx.request\n if (this.shouldSkipAutoRelogin(query, body)) {\n return ctx\n }\n if (\n !this.hasParam(query, 'assertuser') &&\n !this.hasParam(body, 'assertuser')\n ) {\n return ctx\n }\n if (!this.isAssertUserFailed(ctx.data)) return ctx\n\n const attempt = Number(ctx.runtime.customEnv?.autoReloginAttempt ?? 0)\n const maxAttempts = this.getAutoReloginRetries()\n if (attempt >= maxAttempts) return ctx\n\n await this.reloginIfNeeded()\n\n const { rawRequest, ...requestOptions } = ctx.request as any\n const nextEnv = {\n ...ctx.runtime.customEnv,\n autoReloginAttempt: attempt + 1,\n }\n\n const retryResponse = await this.request.request({\n ...requestOptions,\n url: ctx.request.url,\n customEnv: nextEnv,\n })\n\n return retryResponse ?? ctx\n }\n\n async login(\n lgname: string,\n lgpassword: string,\n params?: MwApiParams,\n postOptions?: {\n retry?: number\n noCache?: boolean\n autoRelogin?: boolean\n autoReloginRetries?: number\n }\n ): Promise<{\n result: 'Success' | 'NeedToken' | 'WrongToken' | 'Failed'\n token?: string\n reason?: {\n code: string\n text: string\n }\n lguserid: number\n lgusername: string\n }> {\n this.config.fexiosConfigs.credentials = 'include'\n\n const {\n autoRelogin = true,\n autoReloginRetries = 3,\n ...tokenOptions\n } = postOptions || {}\n if (tokenOptions.noCache === undefined) {\n tokenOptions.noCache = true\n }\n const res = await this.postWithToken(\n 'login',\n {\n action: 'login',\n lgname,\n lgpassword,\n ...params,\n },\n {\n tokenName: 'lgtoken',\n ...tokenOptions,\n }\n )\n\n const data = res?.data\n if (data?.login?.result !== 'Success') {\n throw new WikiSaikouError(\n WikiSaikouErrorCode.LOGIN_FAILED,\n data?.login?.reason?.text ||\n data?.login?.result ||\n 'Login failed with unknown reason',\n data\n )\n }\n\n if (autoRelogin === true) {\n this.autoReloginEnabled = true\n this.loginCredentials = {\n lgname,\n lgpassword,\n username: data?.login?.lgusername,\n autoReloginRetries:\n Number.isFinite(autoReloginRetries) && autoReloginRetries >= 0\n ? Math.floor(autoReloginRetries)\n : 3,\n }\n } else if (autoRelogin === false) {\n this.autoReloginEnabled = false\n this.loginCredentials = undefined\n }\n return data.login\n }\n\n async logout(): Promise<void> {\n this.autoReloginEnabled = false\n this.loginCredentials = undefined\n // optional, tell MediaWiki server to drop the session\n await this.postWithToken('csrf', {\n action: 'logout',\n }).catch(() => {\n // ignore logout errors\n })\n this.tokens.clear()\n this.request.cookieJar?.clear()\n }\n}\n\n// alias\nexport { MediaWikiApi as MwApi, MediaWikiApi as MediaWikiNodeClient }\n"],"names":[],"mappings":";;;;;;AAgBA;AAAA;AAAA;AAAA;AAAA;AAAA;AAMO,MAAM,qBAAqB,cAAA,CAAe;AAAA,EACvC,kBAAA,GAAqB,KAAA;AAAA,EACrB,gBAAA;AAAA,EAcR,WAAA,CACE,eAAA,EACA,cAAA,EACA,aAAA,EACA;AACA,IAAA,MAAM,MAAA,GAAS,iBAAA;AAAA,MACb,eAAA;AAAA,MACA,cAAA;AAAA,MACA;AAAA,KACF;AACA,IAAA,KAAA,CAAM,MAAM,CAAA;AACZ,IAAA,IAAA,CAAK,OAAA,CAAQ,OAAO,eAAe,CAAA;AACnC,IAAA,IAAA,CAAK,OAAA,CAAQ,GAAG,eAAA,EAAiB,CAAC,QAAQ,IAAA,CAAK,mBAAA,CAAoB,GAAG,CAAC,CAAA;AACvE,IAAA,IAAA,CAAK,OAAA,CAAQ,GAAG,eAAA,EAAiB,CAAC,QAAQ,IAAA,CAAK,mBAAA,CAAoB,GAAG,CAAC,CAAA;AAAA,EACzE;AAAA,EAEQ,cAAA,GAAiB;AACvB,IAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,kBAAA,IAAsB,IAAA,CAAK,kBAAkB,QAAQ,CAAA;AAAA,EAC3E;AAAA,EAEQ,aAAA,GAAgB;AACtB,IAAA,OAAO,KAAK,gBAAA,EAAkB,QAAA;AAAA,EAChC;AAAA,EAEQ,qBAAA,GAAwB;AAC9B,IAAA,OAAO,IAAA,CAAK,kBAAkB,kBAAA,IAAsB,CAAA;AAAA,EACtD;AAAA,EAEQ,QAAA,CAAS,MAAW,GAAA,EAAsB;AAChD,IAAA,IAAI,CAAC,MAAM,OAAO,MAAA;AAClB,IAAA,IAAI,gBAAgB,eAAA,EAAiB;AACnC,MAAA,OAAO,IAAA,CAAK,IAAI,GAAG,CAAA;AAAA,IACrB;AACA,IAAA,IAAI,OAAO,QAAA,KAAa,WAAA,IAAe,IAAA,YAAgB,QAAA,EAAU;AAC/D,MAAA,OAAO,IAAA,CAAK,IAAI,GAAG,CAAA;AAAA,IACrB;AACA,IAAA,OAAO,KAAK,GAAG,CAAA;AAAA,EACjB;AAAA,EAEQ,QAAA,CAAS,MAAW,GAAA,EAAsB;AAChD,IAAA,IAAI,CAAC,MAAM,OAAO,KAAA;AAClB,IAAA,IAAI,gBAAgB,eAAA,EAAiB;AACnC,MAAA,OAAO,IAAA,CAAK,IAAI,GAAG,CAAA;AAAA,IACrB;AACA,IAAA,IAAI,OAAO,QAAA,KAAa,WAAA,IAAe,IAAA,YAAgB,QAAA,EAAU;AAC/D,MAAA,OAAO,IAAA,CAAK,IAAI,GAAG,CAAA;AAAA,IACrB;AACA,IAAA,OAAO,IAAA,CAAK,GAAG,CAAA,KAAM,MAAA;AAAA,EACvB;AAAA,EAEQ,QAAA,CAAS,IAAA,EAAW,GAAA,EAAa,KAAA,EAAqB;AAC5D,IAAA,IAAI,gBAAgB,eAAA,EAAiB;AACnC,MAAA,IAAA,CAAK,GAAA,CAAI,KAAK,KAAK,CAAA;AAAA,IACrB,CAAA,MAAA,IAAW,OAAO,QAAA,KAAa,WAAA,IAAe,gBAAgB,QAAA,EAAU;AACtE,MAAA,IAAA,CAAK,GAAA,CAAI,KAAK,KAAK,CAAA;AAAA,IACrB,CAAA,MAAO;AACL,MAAA,IAAA,CAAK,GAAG,CAAA,GAAI,KAAA;AAAA,IACd;AAAA,EACF;AAAA,EAEQ,SAAA,CAAU,OAAiB,IAAA,EAAgB;AACjD,IAAA,MAAM,MAAA,GACJ,KAAK,QAAA,CAAS,KAAA,EAAO,QAAQ,CAAA,IAAK,IAAA,CAAK,QAAA,CAAS,IAAA,EAAM,QAAQ,CAAA;AAChE,IAAA,OAAO,MAAA,KAAW,MAAA,GAAY,MAAA,GAAY,MAAA,CAAO,MAAM,CAAA;AAAA,EACzD;AAAA,EAEQ,cAAc,KAAA,EAA0B;AAC9C,IAAA,IAAI,KAAA,KAAU,MAAA,IAAa,KAAA,KAAU,IAAA,SAAa,EAAC;AACnD,IAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG;AACxB,MAAA,OAAO,KAAA,CAAM,IAAI,CAAC,IAAA,KAAS,OAAO,IAAI,CAAC,CAAA,CAAE,MAAA,CAAO,OAAO,CAAA;AAAA,IACzD;AACA,IAAA,OAAO,MAAA,CAAO,KAAK,CAAA,CAChB,KAAA,CAAM,GAAG,CAAA,CACT,GAAA,CAAI,CAAC,IAAA,KAAS,IAAA,CAAK,IAAA,EAAM,CAAA,CACzB,OAAO,OAAO,CAAA;AAAA,EACnB;AAAA,EAEQ,mBAAA,CAAoB,OAAiB,IAAA,EAAyB;AACpE,IAAA,MAAM,KAAA,GAAQ,CAAC,IAAA,KAAkB;AAC/B,MAAA,IAAI,CAAC,MAAM,OAAO,KAAA;AAClB,MAAA,MAAM,MAAA,GAAS,IAAA,CAAK,QAAA,CAAS,IAAA,EAAM,QAAQ,CAAA;AAE3C,MAAA,IAAI,MAAA,IAAU,MAAA,CAAO,MAAM,CAAA,KAAM,SAAS,OAAO,KAAA;AAGjD,MAAA,IAAI,CAAC,QAAQ,OAAO,KAAA;AAEpB,MAAA,MAAM,OAAO,IAAA,CAAK,aAAA,CAAc,KAAK,QAAA,CAAS,IAAA,EAAM,MAAM,CAAC,CAAA;AAC3D,MAAA,IAAI,CAAC,IAAA,CAAK,QAAA,CAAS,QAAQ,GAAG,OAAO,KAAA;AAErC,MAAA,MAAM,QAAQ,IAAA,CAAK,aAAA,CAAc,KAAK,QAAA,CAAS,IAAA,EAAM,MAAM,CAAC,CAAA;AAC5D,MAAA,OAAO,KAAA,CAAM,SAAS,OAAO,CAAA;AAAA,IAC/B,CAAA;AAEA,IAAA,OAAO,KAAA,CAAM,KAAK,CAAA,IAAK,KAAA,CAAM,IAAI,CAAA;AAAA,EACnC;AAAA,EAEQ,qBAAA,CAAsB,OAAiB,IAAA,EAAgB;AAC7D,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,SAAA,CAAU,KAAA,EAAO,IAAI,CAAA;AACzC,IAAA,IAAI,MAAA,KAAW,SAAS,OAAO,IAAA;AAC/B,IAAA,IAAI,IAAA,CAAK,mBAAA,CAAoB,KAAA,EAAO,IAAI,CAAA,EAAG;AACzC,MAAA,OAAO,IAAA;AAAA,IACT;AACA,IAAA,OAAO,KAAA;AAAA,EACT;AAAA,EAEQ,mBAAmB,IAAA,EAAW;AACpC,IAAA,MAAM,kBAAA,GAAqB,CAAC,IAAA,KAC1B,IAAA,KAAS,sBAAsB,IAAA,KAAS,uBAAA;AAC1C,IAAA,IAAI,iBAAA,CAAkB,EAAA,CAAG,IAAI,CAAA,EAAG;AAC9B,MAAA,OAAO,IAAA,CAAK,OAAO,IAAA,CAAK,CAAC,UAAU,kBAAA,CAAmB,KAAA,CAAM,IAAI,CAAC,CAAA;AAAA,IACnE;AACA,IAAA,OAAO,eAAA,CAAgB,yBAAA,CAA0B,IAAI,CAAA,CAAE,IAAA;AAAA,MAAK,CAAC,KAAA,KAC3D,kBAAA,CAAmB,KAAA,CAAM,IAAI;AAAA,KAC/B;AAAA,EACF;AAAA,EAEA,MAAc,eAAA,GAAkB;AAC9B,IAAA,IAAI,CAAC,IAAA,CAAK,cAAA,EAAe,IAAK,CAAC,KAAK,gBAAA,EAAkB;AACtD,IAAA,MAAM,IAAA,CAAK,KAAA;AAAA,MACT,KAAK,gBAAA,CAAiB,MAAA;AAAA,MACtB,KAAK,gBAAA,CAAiB,UAAA;AAAA,MACtB,MAAA;AAAA,MACA;AAAA,QACE,WAAA,EAAa,IAAA;AAAA,QACb,kBAAA,EAAoB,KAAK,gBAAA,CAAiB;AAAA;AAC5C,KACF;AAAA,EACF;AAAA,EAEA,IAAI,SAAA,GAAY;AACd,IAAA,OAAO,KAAK,OAAA,CAAQ,SAAA;AAAA,EACtB;AAAA,EAEQ,oBACN,GAAA,EACgD;AAChD,IAAA,IAAI,CAAC,IAAA,CAAK,cAAA,EAAe,EAAG,OAAO,GAAA;AACnC,IAAA,MAAM,EAAE,KAAA,EAAO,IAAA,EAAK,GAAI,GAAA,CAAI,OAAA;AAE5B,IAAA,IAAI,IAAA,CAAK,qBAAA,CAAsB,KAAA,EAAO,IAAI,GAAG,OAAO,GAAA;AAEpD,IAAA,IACE,IAAA,CAAK,SAAS,KAAA,EAAO,YAAY,KACjC,IAAA,CAAK,QAAA,CAAS,IAAA,EAAM,YAAY,CAAA,EAChC;AACA,MAAA,OAAO,GAAA;AAAA,IACT;AAEA,IAAA,MAAM,UAAA,GAAa,KAAK,aAAA,EAAc;AAEtC,IAAA,IAAI,IAAA,KAAS,MAAA,IAAa,IAAA,KAAS,IAAA,EAAM;AACvC,MAAA,IAAA,CAAK,QAAA,CAAS,IAAA,EAAM,YAAA,EAAc,UAAU,CAAA;AAAA,IAC9C,CAAA,MAAO;AACL,MAAA,IAAI,CAAC,GAAA,CAAI,OAAA,CAAQ,KAAA,EAAO;AACtB,QAAA,GAAA,CAAI,OAAA,CAAQ,QAAQ,EAAC;AAAA,MACvB;AACA,MAAA,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,OAAA,CAAQ,KAAA,EAAO,cAAc,UAAU,CAAA;AAAA,IAC3D;AACA,IAAA,OAAO,GAAA;AAAA,EACT;AAAA,EAEA,MAAc,oBACZ,GAAA,EAC0D;AAC1D,IAAA,IAAI,CAAC,IAAA,CAAK,cAAA,EAAe,EAAG,OAAO,GAAA;AACnC,IAAA,MAAM,EAAE,KAAA,EAAO,IAAA,EAAK,GAAI,GAAA,CAAI,OAAA;AAC5B,IAAA,IAAI,IAAA,CAAK,qBAAA,CAAsB,KAAA,EAAO,IAAI,CAAA,EAAG;AAC3C,MAAA,OAAO,GAAA;AAAA,IACT;AACA,IAAA,IACE,CAAC,IAAA,CAAK,QAAA,CAAS,KAAA,EAAO,YAAY,CAAA,IAClC,CAAC,IAAA,CAAK,QAAA,CAAS,IAAA,EAAM,YAAY,CAAA,EACjC;AACA,MAAA,OAAO,GAAA;AAAA,IACT;AACA,IAAA,IAAI,CAAC,IAAA,CAAK,kBAAA,CAAmB,GAAA,CAAI,IAAI,GAAG,OAAO,GAAA;AAE/C,IAAA,MAAM,UAAU,MAAA,CAAO,GAAA,CAAI,OAAA,CAAQ,SAAA,EAAW,sBAAsB,CAAC,CAAA;AACrE,IAAA,MAAM,WAAA,GAAc,KAAK,qBAAA,EAAsB;AAC/C,IAAA,IAAI,OAAA,IAAW,aAAa,OAAO,GAAA;AAEnC,IAAA,MAAM,KAAK,eAAA,EAAgB;AAE3B,IAAA,MAAM,EAAE,UAAA,EAAY,GAAG,cAAA,KAAmB,GAAA,CAAI,OAAA;AAC9C,IAAA,MAAM,OAAA,GAAU;AAAA,MACd,GAAG,IAAI,OAAA,CAAQ,SAAA;AAAA,MACf,oBAAoB,OAAA,GAAU;AAAA,KAChC;AAEA,IAAA,MAAM,aAAA,GAAgB,MAAM,IAAA,CAAK,OAAA,CAAQ,OAAA,CAAQ;AAAA,MAC/C,GAAG,cAAA;AAAA,MACH,GAAA,EAAK,IAAI,OAAA,CAAQ,GAAA;AAAA,MACjB,SAAA,EAAW;AAAA,KACZ,CAAA;AAED,IAAA,OAAO,aAAA,IAAiB,GAAA;AAAA,EAC1B;AAAA,EAEA,MAAM,KAAA,CACJ,MAAA,EACA,UAAA,EACA,QACA,WAAA,EAeC;AACD,IAAA,IAAA,CAAK,MAAA,CAAO,cAAc,WAAA,GAAc,SAAA;AAExC,IAAA,MAAM;AAAA,MACJ,WAAA,GAAc,IAAA;AAAA,MACd,kBAAA,GAAqB,CAAA;AAAA,MACrB,GAAG;AAAA,KACL,GAAI,eAAe,EAAC;AACpB,IAAA,IAAI,YAAA,CAAa,YAAY,MAAA,EAAW;AACtC,MAAA,YAAA,CAAa,OAAA,GAAU,IAAA;AAAA,IACzB;AACA,IAAA,MAAM,GAAA,GAAM,MAAM,IAAA,CAAK,aAAA;AAAA,MACrB,OAAA;AAAA,MACA;AAAA,QACE,MAAA,EAAQ,OAAA;AAAA,QACR,MAAA;AAAA,QACA,UAAA;AAAA,QACA,GAAG;AAAA,OACL;AAAA,MACA;AAAA,QACE,SAAA,EAAW,SAAA;AAAA,QACX,GAAG;AAAA;AACL,KACF;AAEA,IAAA,MAAM,OAAO,GAAA,EAAK,IAAA;AAClB,IAAA,IAAI,IAAA,EAAM,KAAA,EAAO,MAAA,KAAW,SAAA,EAAW;AACrC,MAAA,MAAM,IAAI,eAAA;AAAA,QACR,mBAAA,CAAoB,YAAA;AAAA,QACpB,MAAM,KAAA,EAAO,MAAA,EAAQ,IAAA,IACnB,IAAA,EAAM,OAAO,MAAA,IACb,kCAAA;AAAA,QACF;AAAA,OACF;AAAA,IACF;AAEA,IAAA,IAAI,gBAAgB,IAAA,EAAM;AACxB,MAAA,IAAA,CAAK,kBAAA,GAAqB,IAAA;AAC1B,MAAA,IAAA,CAAK,gBAAA,GAAmB;AAAA,QACtB,MAAA;AAAA,QACA,UAAA;AAAA,QACA,QAAA,EAAU,MAAM,KAAA,EAAO,UAAA;AAAA,QACvB,kBAAA,EACE,MAAA,CAAO,QAAA,CAAS,kBAAkB,CAAA,IAAK,sBAAsB,CAAA,GACzD,IAAA,CAAK,KAAA,CAAM,kBAAkB,CAAA,GAC7B;AAAA,OACR;AAAA,IACF,CAAA,MAAA,IAAW,gBAAgB,KAAA,EAAO;AAChC,MAAA,IAAA,CAAK,kBAAA,GAAqB,KAAA;AAC1B,MAAA,IAAA,CAAK,gBAAA,GAAmB,MAAA;AAAA,IAC1B;AACA,IAAA,OAAO,IAAA,CAAK,KAAA;AAAA,EACd;AAAA,EAEA,MAAM,MAAA,GAAwB;AAC5B,IAAA,IAAA,CAAK,kBAAA,GAAqB,KAAA;AAC1B,IAAA,IAAA,CAAK,gBAAA,GAAmB,MAAA;AAExB,IAAA,MAAM,IAAA,CAAK,cAAc,MAAA,EAAQ;AAAA,MAC/B,MAAA,EAAQ;AAAA,KACT,CAAA,CAAE,KAAA,CAAM,MAAM;AAAA,IAEf,CAAC,CAAA;AACD,IAAA,IAAA,CAAK,OAAO,KAAA,EAAM;AAClB,IAAA,IAAA,CAAK,OAAA,CAAQ,WAAW,KAAA,EAAM;AAAA,EAChC;AACF;;;;"}