wretch
Version:
A tiny wrapper built around fetch with an intuitive syntax.
1 lines • 20.8 kB
Source Map (JSON)
{"version":3,"file":"wretch.min.mjs","sources":["../../src/constants.ts","../../src/utils.ts","../../src/config.ts","../../src/resolver.ts","../../src/middleware.ts","../../src/core.ts","../../src/index.ts"],"sourcesContent":["export const JSON_MIME = \"application/json\"\nexport const CONTENT_TYPE_HEADER = \"Content-Type\"\nexport const FETCH_ERROR = Symbol()","import { CONTENT_TYPE_HEADER } from \"./constants.js\"\n\nexport function extractContentType(headers: HeadersInit = {}): string | undefined {\n return Object.entries(headers).find(([k]) =>\n k.toLowerCase() === CONTENT_TYPE_HEADER.toLowerCase()\n )?.[1]\n}\n\nexport function isLikelyJsonMime(value: string): boolean {\n return /^application\\/.*json.*/.test(value)\n}\n\nexport const mix = function (one: object, two: object, mergeArrays: boolean = false) {\n return Object.entries(two).reduce((acc, [key, newValue]) => {\n const value = one[key]\n if (Array.isArray(value) && Array.isArray(newValue)) {\n acc[key] = mergeArrays ? [...value, ...newValue] : newValue\n } else if (typeof value === \"object\" && typeof newValue === \"object\") {\n acc[key] = mix(value, newValue, mergeArrays)\n } else {\n acc[key] = newValue\n }\n\n return acc\n }, { ...one })\n}\n","import { mix } from \"./utils.js\"\nimport type { Config } from \"./types.js\"\n\ndeclare const global\n\nconst config: Config = {\n // Default options\n options: {},\n // Error type\n errorType: \"text\",\n // Polyfills\n polyfills: {\n // fetch: null,\n // FormData: null,\n // URLSearchParams: null,\n // performance: null,\n // PerformanceObserver: null,\n // AbortController: null\n },\n polyfill(p: string, doThrow: boolean = true, instance: boolean = false, ...args: any[]) {\n const res = this.polyfills[p] ||\n (typeof self !== \"undefined\" ? self[p] : null) ||\n (typeof global !== \"undefined\" ? global[p] : null)\n if (doThrow && !res) throw new Error(p + \" is not defined\")\n return instance && res ? new res(...args) : res\n }\n}\n\n/**\n * Sets the default fetch options that will be stored internally when instantiating wretch objects.\n *\n * ```js\n * import wretch from \"wretch\"\n *\n * wretch.options({ headers: { \"Accept\": \"application/json\" } });\n *\n * // The fetch request is sent with both headers.\n * wretch(\"...\", { headers: { \"X-Custom\": \"Header\" } }).get().res();\n * ```\n *\n * @param options Default options\n * @param replace If true, completely replaces the existing options instead of mixing in\n */\nexport function setOptions(options: object, replace = false) {\n config.options = replace ? options : mix(config.options, options)\n}\n\n/**\n * Sets the default polyfills that will be stored internally when instantiating wretch objects.\n * Useful for browserless environments like `node.js`.\n *\n * Needed for libraries like [fetch-ponyfill](https://github.com/qubyte/fetch-ponyfill).\n *\n * ```js\n * import wretch from \"wretch\"\n *\n * wretch.polyfills({\n * fetch: require(\"node-fetch\"),\n * FormData: require(\"form-data\"),\n * URLSearchParams: require(\"url\").URLSearchParams,\n * });\n *\n * // Uses the above polyfills.\n * wretch(\"...\").get().res();\n * ```\n *\n * @param polyfills An object containing the polyfills\n * @param replace If true, replaces the current polyfills instead of mixing in\n */\nexport function setPolyfills(polyfills: object, replace = false) {\n config.polyfills = replace ? polyfills : mix(config.polyfills, polyfills)\n}\n\n/**\n * Sets the default method (text, json, …) used to parse the data contained in the response body in case of an HTTP error.\n * As with other static methods, it will affect wretch instances created after calling this function.\n *\n * ```js\n * import wretch from \"wretch\"\n *\n * wretch.errorType(\"json\")\n *\n * wretch(\"http://server/which/returns/an/error/with/a/json/body\")\n * .get()\n * .res()\n * .catch(error => {\n * // error[errorType] (here, json) contains the parsed body\n * console.log(error.json)\n * })\n * ```\n *\n * If null, defaults to \"text\".\n */\nexport function setErrorType(errorType: string) {\n config.errorType = errorType\n}\n\nexport default config\n","import { middlewareHelper } from \"./middleware.js\"\nimport { mix } from \"./utils.js\"\nimport type { Wretch, WretchResponse, WretchResponseChain, WretchError as WretchErrorType } from \"./types.js\"\nimport { FETCH_ERROR } from \"./constants.js\"\n\n/**\n * This class inheriting from Error is thrown when the fetch response is not \"ok\".\n * It extends Error and adds status, text and body fields.\n */\nexport class WretchError extends Error implements WretchErrorType {\n status: number\n response: WretchResponse\n text?: string\n json?: any\n}\n\nexport const resolver = <T, Chain, R>(wretch: T & Wretch<T, Chain, R>) => {\n const {\n _url: url,\n _options: opts,\n _config: config,\n _catchers: _catchers,\n _resolvers: resolvers,\n _middlewares: middlewares,\n _addons: addons\n } = wretch\n\n const catchers = new Map(_catchers)\n const finalOptions = mix(config.options, opts)\n addons.forEach(addon => addon.beforeRequest && addon.beforeRequest(wretch, finalOptions))\n // The generated fetch request\n const _fetchReq = middlewareHelper(middlewares)(config.polyfill(\"fetch\"))(url, finalOptions)\n // Throws on an http error\n const referenceError = new Error()\n const throwingPromise: Promise<void | WretchResponse> = _fetchReq\n .catch(error => {\n throw { __wrap: error }\n })\n .then(response => {\n if (!response.ok) {\n const err = new WretchError()\n // Enhance the error object\n err[\"cause\"] = referenceError\n err.stack = err.stack + \"\\nCAUSE: \" + referenceError.stack\n err.response = response\n if (response.type === \"opaque\") {\n throw err\n }\n return response[config.errorType]().then((body: string) => {\n err.message = body\n err[config.errorType] = body\n err[\"status\"] = response.status\n throw err\n })\n }\n return response\n })\n // Wraps the Promise in order to dispatch the error to a matching catcher\n const catchersWrapper = <T>(promise: Promise<T>): Promise<void | T> => {\n return promise.catch(err => {\n const error = err.__wrap || err\n\n const catcher =\n err.__wrap && catchers.has(FETCH_ERROR) ? catchers.get(FETCH_ERROR) :\n (catchers.get(error.status) || catchers.get(error.name))\n\n if (catcher)\n return catcher(error, wretch)\n\n throw error\n })\n }\n // Enforces the proper promise type when a body parsing method is called.\n type BodyParser = <Type>(funName: string | null) => <Result = void>(cb?: (type: Type) => Result) => Promise<Awaited<Result>>\n const bodyParser: BodyParser = funName => cb => funName ?\n // If a callback is provided, then callback with the body result otherwise return the parsed body itself.\n catchersWrapper(throwingPromise.then(_ => _ && _[funName]()).then(_ => cb ? cb(_) : _)) :\n // No body parsing method - return the response\n catchersWrapper(throwingPromise.then(_ => cb ? cb(_ as any) : _))\n\n const responseChain: WretchResponseChain<T, Chain, R> = {\n _wretchReq: wretch,\n _fetchReq,\n res: bodyParser<WretchResponse>(null),\n json: bodyParser<any>(\"json\"),\n blob: bodyParser<Blob>(\"blob\"),\n formData: bodyParser<FormData>(\"formData\"),\n arrayBuffer: bodyParser<ArrayBuffer>(\"arrayBuffer\"),\n text: bodyParser<string>(\"text\"),\n error(errorId, cb) {\n catchers.set(errorId, cb)\n return this\n },\n badRequest(cb) { return this.error(400, cb) },\n unauthorized(cb) { return this.error(401, cb) },\n forbidden(cb) { return this.error(403, cb) },\n notFound(cb) { return this.error(404, cb) },\n timeout(cb) { return this.error(408, cb) },\n internalError(cb) { return this.error(500, cb) },\n fetchError(cb) { return this.error(FETCH_ERROR, cb) },\n }\n\n const enhancedResponseChain: R extends undefined ? Chain & WretchResponseChain<T, Chain, undefined> : R = addons.reduce((chain, addon) => ({\n ...chain,\n ...(addon.resolver as any)\n }), responseChain)\n\n return resolvers.reduce((chain, r) => r(chain, wretch), enhancedResponseChain)\n}\n","import type { ConfiguredMiddleware, FetchLike } from \"./types.js\"\n\n/**\n * @private @internal\n */\nexport const middlewareHelper = (middlewares: ConfiguredMiddleware[]) => (fetchFunction: FetchLike): FetchLike => {\n return middlewares.reduceRight((acc, curr) => curr(acc), fetchFunction) || fetchFunction\n}\n","import { mix, extractContentType, isLikelyJsonMime } from \"./utils.js\"\nimport { JSON_MIME, CONTENT_TYPE_HEADER } from \"./constants.js\"\nimport { resolver } from \"./resolver.js\"\nimport config from \"./config.js\"\nimport type { Wretch } from \"./types.js\"\n\nexport const core: Wretch = {\n _url: \"\",\n _options: {},\n _config: config,\n _catchers: new Map(),\n _resolvers: [],\n _deferred: [],\n _middlewares: [],\n _addons: [],\n addon(addon) {\n return { ...this, _addons: [...this._addons, addon], ...addon.wretch }\n },\n errorType(errorType: string) {\n return {\n ...this,\n _config: {\n ...this._config,\n errorType\n }\n }\n },\n polyfills(polyfills, replace = false) {\n return {\n ...this,\n _config: {\n ...this._config,\n polyfills: replace ? polyfills : mix(this._config.polyfills, polyfills)\n }\n }\n },\n url(_url, replace = false) {\n if (replace)\n return { ...this, _url }\n const split = this._url.split(\"?\")\n return {\n ...this,\n _url: split.length > 1 ?\n split[0] + _url + \"?\" + split[1] :\n this._url + _url\n }\n },\n options(options, replace = false) {\n return { ...this, _options: replace ? options : mix(this._options, options) }\n },\n headers(headerValues) {\n return { ...this, _options: mix(this._options, { headers: headerValues || {} }) }\n },\n accept(headerValue) {\n return this.headers({ Accept: headerValue })\n },\n content(headerValue) {\n return this.headers({ [CONTENT_TYPE_HEADER]: headerValue })\n },\n auth(headerValue) {\n return this.headers({ Authorization: headerValue })\n },\n catcher(errorId, catcher) {\n const newMap = new Map(this._catchers)\n newMap.set(errorId, catcher)\n return { ...this, _catchers: newMap }\n },\n resolve<R = unknown>(resolver, clear: boolean = false) {\n return { ...this, _resolvers: clear ? [resolver] : [...this._resolvers, resolver] }\n },\n defer(callback, clear: boolean = false) {\n return {\n ...this,\n _deferred: clear ? [callback] : [...this._deferred, callback]\n }\n },\n middlewares(middlewares, clear = false) {\n return {\n ...this,\n _middlewares: clear ? middlewares : [...this._middlewares, ...middlewares]\n }\n },\n fetch(method: string = this._options.method, url = \"\", body = null) {\n let base = this.url(url).options({ method })\n // \"Jsonify\" the body if it is an object and if it is likely that the content type targets json.\n const contentType = extractContentType(base._options.headers)\n const jsonify = typeof body === \"object\" && (!base._options.headers || !contentType || isLikelyJsonMime(contentType))\n base =\n !body ? base :\n jsonify ? base.json(body, contentType) :\n base.body(body)\n return resolver(\n base\n ._deferred\n .reduce((acc: Wretch, curr) => curr(acc, acc._url, acc._options), base)\n )\n },\n get(url = \"\") {\n return this.fetch(\"GET\", url)\n },\n delete(url = \"\") {\n return this.fetch(\"DELETE\", url)\n },\n put(body, url = \"\") {\n return this.fetch(\"PUT\", url, body)\n },\n post(body, url = \"\") {\n return this.fetch(\"POST\", url, body)\n },\n patch(body, url = \"\") {\n return this.fetch(\"PATCH\", url, body)\n },\n head(url = \"\") {\n return this.fetch(\"HEAD\", url)\n },\n opts(url = \"\") {\n return this.fetch(\"OPTIONS\", url)\n },\n body(contents) {\n return { ...this, _options: { ...this._options, body: contents } }\n },\n json(jsObject, contentType) {\n const currentContentType = extractContentType(this._options.headers)\n return this.content(\n contentType ||\n isLikelyJsonMime(currentContentType) && currentContentType ||\n JSON_MIME\n ).body(JSON.stringify(jsObject))\n }\n}\n","import { setOptions, setErrorType, setPolyfills } from \"./config.js\"\nimport { core } from \"./core.js\"\nimport { WretchError } from \"./resolver.js\"\nimport type { Wretch } from \"./types.js\"\n\nexport type {\n Wretch,\n Config,\n ConfiguredMiddleware,\n FetchLike,\n Middleware,\n WretchResponseChain,\n WretchOptions,\n WretchError,\n WretchErrorCallback,\n WretchResponse,\n WretchDeferredCallback,\n WretchAddon\n} from \"./types.js\"\n\n/**\n * Creates a new wretch instance with a base url and base\n * [fetch options](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch).\n *\n * ```ts\n * import wretch from \"wretch\"\n *\n * // Reusable instance\n * const w = wretch(\"https://domain.com\", { mode: \"cors\" })\n * ```\n *\n * @param _url The base url\n * @param _options The base fetch options\n * @returns A fresh wretch instance\n */\nfunction factory(_url = \"\", _options = {}): Wretch {\n return { ...core, _url, _options }\n}\n\nfactory[\"default\"] = factory\n/** {@inheritDoc setOptions} */\nfactory.options = setOptions\n/** {@inheritDoc setErrorType} */\nfactory.errorType = setErrorType\n/** {@inheritDoc setPolyfills} */\nfactory.polyfills = setPolyfills\nfactory.WretchError = WretchError\n\nexport default factory\n"],"names":["FETCH_ERROR","Symbol","extractContentType","headers","_a","Object","entries","find","k","toLowerCase","isLikelyJsonMime","value","test","mix","one","two","mergeArrays","reduce","acc","key","newValue","Array","isArray","config","options","errorType","polyfills","polyfill","p","doThrow","instance","args","res","this","self","global","Error","WretchError","resolver","wretch","_url","url","_options","opts","_config","_catchers","_resolvers","resolvers","_middlewares","middlewares","_addons","addons","catchers","Map","finalOptions","forEach","addon","beforeRequest","_fetchReq","fetchFunction","reduceRight","curr","middlewareHelper","referenceError","throwingPromise","catch","error","__wrap","then","response","ok","err","stack","type","body","message","status","bodyParser","funName","cb","_","catcher","has","get","name","responseChain","_wretchReq","json","blob","formData","arrayBuffer","text","errorId","set","badRequest","unauthorized","forbidden","notFound","timeout","internalError","fetchError","enhancedResponseChain","chain","r","core","_deferred","replace","split","length","headerValues","accept","headerValue","Accept","content","auth","Authorization","newMap","resolve","clear","defer","callback","fetch","method","base","contentType","jsonify","delete","put","post","patch","head","contents","jsObject","currentContentType","JSON","stringify","factory"],"mappings":"AAAO,MAEMA,EAAcC,SCAX,SAAAC,EAAmBC,EAAuB,UACxD,OAEI,QAFGC,EAAAC,OAAOC,QAAQH,GAASI,MAAK,EAAEC,KACpCA,EAAEC,gBDH6B,eCGSA,uBACtC,IAAAL,OAAA,EAAAA,EAAA,EACN,CAEM,SAAUM,EAAiBC,GAC/B,MAAO,yBAAyBC,KAAKD,EACvC,CAEO,MAAME,EAAM,SAAUC,EAAaC,EAAaC,EAAuB,GAC5E,OAAOX,OAAOC,QAAQS,GAAKE,QAAO,CAACC,GAAMC,EAAKC,MAC5C,MAAMT,EAAQG,EAAIK,GASlB,OARIE,MAAMC,QAAQX,IAAUU,MAAMC,QAAQF,GACxCF,EAAIC,GAAOH,EAAc,IAAIL,KAAUS,GAAYA,EAEnDF,EAAIC,GADsB,iBAAVR,GAA0C,iBAAbS,EAClCP,EAAIF,EAAOS,EAAUJ,GAErBI,EAGNF,CAAG,GACT,IAAKJ,GACV,ECpBMS,EAAiB,CAErBC,QAAS,CAAE,EAEXC,UAAW,OAEXC,UAAW,CAOV,EACDC,SAASC,EAAWC,EAAmB,EAAMC,EAAoB,KAAUC,GACzE,MAAMC,EAAMC,KAAKP,UAAUE,KACR,oBAATM,KAAuBA,KAAKN,GAAK,QACtB,oBAAXO,OAAyBA,OAAOP,GAAK,MAC/C,GAAIC,IAAYG,EAAK,MAAM,IAAII,MAAMR,EAAI,mBACzC,OAAOE,GAAYE,EAAM,IAAIA,KAAOD,GAAQC,CAC7C,GChBG,MAAOK,UAAoBD,OAO1B,MAAME,EAAyBC,IACpC,MACEC,KAAMC,EACNC,SAAUC,EACVC,QAASrB,EACTsB,UAAWA,EACXC,WAAYC,EACZC,aAAcC,EACdC,QAASC,GACPZ,EAEEa,EAAW,IAAIC,IAAIR,GACnBS,EAAezC,EAAIU,EAAOC,QAASmB,GACzCQ,EAAOI,SAAQC,GAASA,EAAMC,eAAiBD,EAAMC,cAAclB,EAAQe,KAE3E,MAAMI,EC1BwB,CAACT,GAAyCU,GACjEV,EAAYW,aAAY,CAAC1C,EAAK2C,IAASA,EAAK3C,IAAMyC,IAAkBA,EDyBzDG,CAAiBb,EAAjBa,CAA8BvC,EAAOI,SAAS,SAA9CmC,CAAwDrB,EAAKa,GAEzES,EAAiB,IAAI3B,MACrB4B,EAAkDN,EACrDO,OAAMC,IACL,KAAM,CAAEC,OAAQD,EAAO,IAExBE,MAAKC,IACJ,IAAKA,EAASC,GAAI,CAChB,MAAMC,EAAM,IAAIlC,EAKhB,GAHAkC,EAAW,MAAIR,EACfQ,EAAIC,MAAQD,EAAIC,MAAQ,YAAcT,EAAeS,MACrDD,EAAIF,SAAWA,EACO,WAAlBA,EAASI,KACX,MAAMF,EAER,OAAOF,EAAS9C,EAAOE,aAAa2C,MAAMM,IAIxC,MAHAH,EAAII,QAAUD,EACdH,EAAIhD,EAAOE,WAAaiD,EACxBH,EAAY,OAAIF,EAASO,OACnBL,CAAG,GAEZ,CACD,OAAOF,CAAQ,IAmBbQ,EAAyBC,GAAWC,IAAMD,EAE9Bd,EAAgBI,MAAKY,GAAKA,GAAKA,EAAEF,OAAYV,MAAKY,GAAKD,EAAKA,EAAGC,GAAKA,IAEpEhB,EAAgBI,MAAKY,GAAKD,EAAKA,EAAGC,GAAYA,KAnB/Cf,OAAMM,IACnB,MAAML,EAAQK,EAAIJ,QAAUI,EAEtBU,EACJV,EAAIJ,QAAUf,EAAS8B,IAAIlF,GAAeoD,EAAS+B,IAAInF,GACpDoD,EAAS+B,IAAIjB,EAAMU,SAAWxB,EAAS+B,IAAIjB,EAAMkB,MAEtD,GAAIH,EACF,OAAOA,EAAQf,EAAO3B,GAExB,MAAM2B,CAAK,IAWTmB,EAAkD,CACtDC,WAAY/C,EACZmB,YACA1B,IAAK6C,EAA2B,MAChCU,KAAMV,EAAgB,QACtBW,KAAMX,EAAiB,QACvBY,SAAUZ,EAAqB,YAC/Ba,YAAab,EAAwB,eACrCc,KAAMd,EAAmB,QACzBX,MAAM0B,EAASb,GAEb,OADA3B,EAASyC,IAAID,EAASb,GACf9C,IACR,EACD6D,WAAWf,GAAM,OAAO9C,KAAKiC,MAAM,IAAKa,EAAK,EAC7CgB,aAAahB,GAAM,OAAO9C,KAAKiC,MAAM,IAAKa,EAAK,EAC/CiB,UAAUjB,GAAM,OAAO9C,KAAKiC,MAAM,IAAKa,EAAK,EAC5CkB,SAASlB,GAAM,OAAO9C,KAAKiC,MAAM,IAAKa,EAAK,EAC3CmB,QAAQnB,GAAM,OAAO9C,KAAKiC,MAAM,IAAKa,EAAK,EAC1CoB,cAAcpB,GAAM,OAAO9C,KAAKiC,MAAM,IAAKa,EAAK,EAChDqB,WAAWrB,GAAM,OAAO9C,KAAKiC,MAAMlE,EAAa+E,EAAK,GAGjDsB,EAAoGlD,EAAOlC,QAAO,CAACqF,EAAO9C,KAAW,IACtI8C,KACC9C,EAAMlB,YACR+C,GAEJ,OAAOtC,EAAU9B,QAAO,CAACqF,EAAOC,IAAMA,EAAED,EAAO/D,IAAS8D,EAAsB,EErGnEG,EAAe,CAC1BhE,KAAM,GACNE,SAAU,CAAE,EACZE,QAASrB,EACTsB,UAAW,IAAIQ,IACfP,WAAY,GACZ2D,UAAW,GACXzD,aAAc,GACdE,QAAS,GACTM,MAAMA,GACJ,MAAO,IAAKvB,KAAMiB,QAAS,IAAIjB,KAAKiB,QAASM,MAAWA,EAAMjB,OAC/D,EACDd,UAAUA,GACR,MAAO,IACFQ,KACHW,QAAS,IACJX,KAAKW,QACRnB,aAGL,EACDC,UAAUA,EAAWgF,EAAU,GAC7B,MAAO,IACFzE,KACHW,QAAS,IACJX,KAAKW,QACRlB,UAAWgF,EAAUhF,EAAYb,EAAIoB,KAAKW,QAAQlB,UAAWA,IAGlE,EACDe,IAAID,EAAMkE,EAAU,GAClB,GAAIA,EACF,MAAO,IAAKzE,KAAMO,QACpB,MAAMmE,EAAQ1E,KAAKO,KAAKmE,MAAM,KAC9B,MAAO,IACF1E,KACHO,KAAMmE,EAAMC,OAAS,EACnBD,EAAM,GAAKnE,EAAO,IAAMmE,EAAM,GAC9B1E,KAAKO,KAAOA,EAEjB,EACDhB,QAAQA,EAASkF,EAAU,GACzB,MAAO,IAAKzE,KAAMS,SAAUgE,EAAUlF,EAAUX,EAAIoB,KAAKS,SAAUlB,GACpE,EACDrB,QAAQ0G,GACN,MAAO,IAAK5E,KAAMS,SAAU7B,EAAIoB,KAAKS,SAAU,CAAEvC,QAAS0G,GAAgB,CAAE,IAC7E,EACDC,OAAOC,GACL,OAAO9E,KAAK9B,QAAQ,CAAE6G,OAAQD,GAC/B,EACDE,QAAQF,GACN,OAAO9E,KAAK9B,QAAQ,CAAE,eAAuB4G,GAC9C,EACDG,KAAKH,GACH,OAAO9E,KAAK9B,QAAQ,CAAEgH,cAAeJ,GACtC,EACD9B,QAAQW,EAASX,GACf,MAAMmC,EAAS,IAAI/D,IAAIpB,KAAKY,WAE5B,OADAuE,EAAOvB,IAAID,EAASX,GACb,IAAKhD,KAAMY,UAAWuE,EAC9B,EACDC,QAAqB/E,EAAUgF,EAAiB,GAC9C,MAAO,IAAKrF,KAAMa,WAAYwE,EAAQ,CAAChF,GAAY,IAAIL,KAAKa,WAAYR,GACzE,EACDiF,MAAMC,EAAUF,EAAiB,GAC/B,MAAO,IACFrF,KACHwE,UAAWa,EAAQ,CAACE,GAAY,IAAIvF,KAAKwE,UAAWe,GAEvD,EACDvE,YAAYA,EAAaqE,EAAQ,GAC/B,MAAO,IACFrF,KACHe,aAAcsE,EAAQrE,EAAc,IAAIhB,KAAKe,gBAAiBC,GAEjE,EACDwE,MAAMC,EAAiBzF,KAAKS,SAASgF,OAAQjF,EAAM,GAAIiC,EAAO,MAC5D,IAAIiD,EAAO1F,KAAKQ,IAAIA,GAAKjB,QAAQ,CAAEkG,WAEnC,MAAME,EAAc1H,EAAmByH,EAAKjF,SAASvC,SAC/C0H,EAA0B,iBAATnD,KAAuBiD,EAAKjF,SAASvC,UAAYyH,GAAelH,EAAiBkH,IAKxG,OAJAD,EACGjD,EACCmD,EAAUF,EAAKpC,KAAKb,EAAMkD,GACxBD,EAAKjD,KAAKA,GAFNiD,EAGHrF,EACLqF,EACGlB,UACAxF,QAAO,CAACC,EAAa2C,IAASA,EAAK3C,EAAKA,EAAIsB,KAAMtB,EAAIwB,WAAWiF,GAEvE,EACDxC,IAAI1C,EAAM,IACR,OAAOR,KAAKwF,MAAM,MAAOhF,EAC1B,EACDqF,OAAOrF,EAAM,IACX,OAAOR,KAAKwF,MAAM,SAAUhF,EAC7B,EACDsF,IAAIrD,EAAMjC,EAAM,IACd,OAAOR,KAAKwF,MAAM,MAAOhF,EAAKiC,EAC/B,EACDsD,KAAKtD,EAAMjC,EAAM,IACf,OAAOR,KAAKwF,MAAM,OAAQhF,EAAKiC,EAChC,EACDuD,MAAMvD,EAAMjC,EAAM,IAChB,OAAOR,KAAKwF,MAAM,QAAShF,EAAKiC,EACjC,EACDwD,KAAKzF,EAAM,IACT,OAAOR,KAAKwF,MAAM,OAAQhF,EAC3B,EACDE,KAAKF,EAAM,IACT,OAAOR,KAAKwF,MAAM,UAAWhF,EAC9B,EACDiC,KAAKyD,GACH,MAAO,IAAKlG,KAAMS,SAAU,IAAKT,KAAKS,SAAUgC,KAAMyD,GACvD,EACD5C,KAAK6C,EAAUR,GACb,MAAMS,EAAqBnI,EAAmB+B,KAAKS,SAASvC,SAC5D,OAAO8B,KAAKgF,QACVW,GACAlH,EAAiB2H,IAAuBA,GL7HrB,oBK+HnB3D,KAAK4D,KAAKC,UAAUH,GACvB,GC7FH,SAASI,EAAQhG,EAAO,GAAIE,EAAW,CAAA,GACrC,MAAO,IAAK8D,EAAMhE,OAAME,WAC1B,CAEA8F,EAAiB,QAAIA,EAErBA,EAAQhH,iBJEmBA,EAAiBkF,EAAU,GACpDnF,EAAOC,QAAUkF,EAAUlF,EAAUX,EAAIU,EAAOC,QAASA,EAC3D,EIFAgH,EAAQ/G,UJkDF,SAAuBA,GAC3BF,EAAOE,UAAYA,CACrB,EIlDA+G,EAAQ9G,mBJwBqBA,EAAmBgF,EAAU,GACxDnF,EAAOG,UAAYgF,EAAUhF,EAAYb,EAAIU,EAAOG,UAAWA,EACjE,EIzBA8G,EAAQnG,YAAcA"}