get-it
Version:
Generic HTTP request library for node, browsers and workers
1 lines • 26.3 kB
Source Map (JSON)
{"version":3,"file":"index.browser.cjs","sources":["../src/util/middlewareReducer.ts","../src/createRequester.ts","../src/util/pubsub.ts","../node_modules/parse-headers/parse-headers.js","../src/request/browser/fetchXhr.ts","../src/request/browser-request.ts","../src/index.browser.ts"],"sourcesContent":["import type {ApplyMiddleware, MiddlewareReducer} from 'get-it'\n\nexport const middlewareReducer = (middleware: MiddlewareReducer) =>\n function applyMiddleware(hook, defaultValue, ...args) {\n const bailEarly = hook === 'onError'\n\n let value = defaultValue\n for (let i = 0; i < middleware[hook].length; i++) {\n const handler = middleware[hook][i]\n // @ts-expect-error -- find a better way to deal with argument tuples\n value = handler(value, ...args)\n\n if (bailEarly && !value) {\n break\n }\n }\n\n return value\n } as ApplyMiddleware\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport {processOptions} from './middleware/defaultOptionsProcessor'\nimport {validateOptions} from './middleware/defaultOptionsValidator'\nimport type {\n HttpContext,\n HttpRequest,\n HttpRequestOngoing,\n Middleware,\n MiddlewareChannels,\n MiddlewareHooks,\n MiddlewareReducer,\n MiddlewareResponse,\n Middlewares,\n Requester,\n RequestOptions,\n} from './types'\nimport {middlewareReducer} from './util/middlewareReducer'\nimport {createPubSub} from './util/pubsub'\n\nconst channelNames = [\n 'request',\n 'response',\n 'progress',\n 'error',\n 'abort',\n] satisfies (keyof MiddlewareChannels)[]\nconst middlehooks = [\n 'processOptions',\n 'validateOptions',\n 'interceptRequest',\n 'finalizeOptions',\n 'onRequest',\n 'onResponse',\n 'onError',\n 'onReturn',\n 'onHeaders',\n] satisfies (keyof MiddlewareHooks)[]\n\n/** @public */\nexport function createRequester(initMiddleware: Middlewares, httpRequest: HttpRequest): Requester {\n const loadedMiddleware: Middlewares = []\n const middleware: MiddlewareReducer = middlehooks.reduce(\n (ware, name) => {\n ware[name] = ware[name] || []\n return ware\n },\n {\n processOptions: [processOptions],\n validateOptions: [validateOptions],\n } as any,\n )\n\n function request(opts: RequestOptions | string) {\n const onResponse = (reqErr: Error | null, res: MiddlewareResponse, ctx: HttpContext) => {\n let error = reqErr\n let response: MiddlewareResponse | null = res\n\n // We're processing non-errors first, in case a middleware converts the\n // response into an error (for instance, status >= 400 == HttpError)\n if (!error) {\n try {\n response = applyMiddleware('onResponse', res, ctx)\n } catch (err: any) {\n response = null\n error = err\n }\n }\n\n // Apply error middleware - if middleware return the same (or a different) error,\n // publish as an error event. If we *don't* return an error, assume it has been handled\n error = error && applyMiddleware('onError', error, ctx)\n\n // Figure out if we should publish on error/response channels\n if (error) {\n channels.error.publish(error)\n } else if (response) {\n channels.response.publish(response)\n }\n }\n\n const channels: MiddlewareChannels = channelNames.reduce((target, name) => {\n target[name] = createPubSub() as MiddlewareChannels[typeof name]\n return target\n }, {} as any)\n\n // Prepare a middleware reducer that can be reused throughout the lifecycle\n const applyMiddleware = middlewareReducer(middleware)\n\n // Parse the passed options\n const options = applyMiddleware('processOptions', opts as RequestOptions)\n\n // Validate the options\n applyMiddleware('validateOptions', options)\n\n // Build a context object we can pass to child handlers\n const context = {options, channels, applyMiddleware}\n\n // We need to hold a reference to the current, ongoing request,\n // in order to allow cancellation. In the case of the retry middleware,\n // a new request might be triggered\n let ongoingRequest: HttpRequestOngoing | undefined\n const unsubscribe = channels.request.subscribe((ctx) => {\n // Let request adapters (node/browser) perform the actual request\n ongoingRequest = httpRequest(ctx, (err, res) => onResponse(err, res!, ctx))\n })\n\n // If we abort the request, prevent further requests from happening,\n // and be sure to cancel any ongoing request (obviously)\n channels.abort.subscribe(() => {\n unsubscribe()\n if (ongoingRequest) {\n ongoingRequest.abort()\n }\n })\n\n // See if any middleware wants to modify the return value - for instance\n // the promise or observable middlewares\n const returnValue = applyMiddleware('onReturn', channels, context)\n\n // If return value has been modified by a middleware, we expect the middleware\n // to publish on the 'request' channel. If it hasn't been modified, we want to\n // trigger it right away\n if (returnValue === channels) {\n channels.request.publish(context)\n }\n\n return returnValue\n }\n\n request.use = function use(newMiddleware: Middleware) {\n if (!newMiddleware) {\n throw new Error('Tried to add middleware that resolved to falsey value')\n }\n\n if (typeof newMiddleware === 'function') {\n throw new Error(\n 'Tried to add middleware that was a function. It probably expects you to pass options to it.',\n )\n }\n\n if (newMiddleware.onReturn && middleware.onReturn.length > 0) {\n throw new Error(\n 'Tried to add new middleware with `onReturn` handler, but another handler has already been registered for this event',\n )\n }\n\n middlehooks.forEach((key) => {\n if (newMiddleware[key]) {\n middleware[key].push(newMiddleware[key] as any)\n }\n })\n\n loadedMiddleware.push(newMiddleware)\n return request\n }\n\n request.clone = () => createRequester(loadedMiddleware, httpRequest)\n\n initMiddleware.forEach(request.use)\n\n return request\n}\n","// Code borrowed from https://github.com/bjoerge/nano-pubsub\n\nimport type {PubSub, Subscriber} from 'get-it'\n\nexport function createPubSub<Message = void>(): PubSub<Message> {\n const subscribers: {[id: string]: Subscriber<Message>} = Object.create(null)\n let nextId = 0\n function subscribe(subscriber: Subscriber<Message>) {\n const id = nextId++\n subscribers[id] = subscriber\n return function unsubscribe() {\n delete subscribers[id]\n }\n }\n\n function publish(event: Message) {\n for (const id in subscribers) {\n subscribers[id](event)\n }\n }\n\n return {\n publish,\n subscribe,\n }\n}\n","var trim = function(string) {\n return string.replace(/^\\s+|\\s+$/g, '');\n}\n , isArray = function(arg) {\n return Object.prototype.toString.call(arg) === '[object Array]';\n }\n\nmodule.exports = function (headers) {\n if (!headers)\n return {}\n\n var result = Object.create(null);\n\n var headersArr = trim(headers).split('\\n')\n\n for (var i = 0; i < headersArr.length; i++) {\n var row = headersArr[i]\n var index = row.indexOf(':')\n , key = trim(row.slice(0, index)).toLowerCase()\n , value = trim(row.slice(index + 1))\n\n if (typeof(result[key]) === 'undefined') {\n result[key] = value\n } else if (isArray(result[key])) {\n result[key].push(value)\n } else {\n result[key] = [ result[key], value ]\n }\n }\n\n return result\n}\n","/**\n * Mimicks the XMLHttpRequest API with only the parts needed for get-it's XHR adapter\n */\nexport class FetchXhr\n implements Pick<XMLHttpRequest, 'open' | 'abort' | 'getAllResponseHeaders' | 'setRequestHeader'>\n{\n /**\n * Public interface, interop with real XMLHttpRequest\n */\n onabort: (() => void) | undefined\n onerror: ((error?: any) => void) | undefined\n onreadystatechange: (() => void) | undefined\n ontimeout: XMLHttpRequest['ontimeout'] | undefined\n /**\n * https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/readyState\n */\n readyState: 0 | 1 | 2 | 3 | 4 = 0\n response: XMLHttpRequest['response']\n responseText: XMLHttpRequest['responseText'] = ''\n responseType: XMLHttpRequest['responseType'] = ''\n status: XMLHttpRequest['status'] | undefined\n statusText: XMLHttpRequest['statusText'] | undefined\n withCredentials: XMLHttpRequest['withCredentials'] | undefined\n\n /**\n * Private implementation details\n */\n #method!: string\n #url!: string\n #resHeaders!: string\n #headers: Record<string, string> = {}\n #controller?: AbortController\n #init: RequestInit = {}\n #useAbortSignal?: boolean\n // eslint-disable-next-line @typescript-eslint/no-unused-vars -- _async is only declared for typings compatibility\n open(method: string, url: string, _async?: boolean) {\n this.#method = method\n this.#url = url\n this.#resHeaders = ''\n this.readyState = 1 // Open\n this.onreadystatechange?.()\n this.#controller = undefined\n }\n abort() {\n if (this.#controller) {\n this.#controller.abort()\n }\n }\n getAllResponseHeaders() {\n return this.#resHeaders\n }\n setRequestHeader(name: string, value: string) {\n this.#headers[name] = value\n }\n // Allow setting extra fetch init options, needed for runtimes such as Vercel Edge to set `cache` and other options in React Server Components\n setInit(init: RequestInit, useAbortSignal = true) {\n this.#init = init\n this.#useAbortSignal = useAbortSignal\n }\n send(body: BodyInit) {\n const textBody = this.responseType !== 'arraybuffer'\n const options: RequestInit = {\n ...this.#init,\n method: this.#method,\n headers: this.#headers,\n body,\n }\n if (typeof AbortController === 'function' && this.#useAbortSignal) {\n this.#controller = new AbortController()\n // The instanceof check ensures environments like Edge Runtime, Node 18 with built-in fetch\n // and more don't throw if `signal` doesn't implement`EventTarget`\n // Native browser AbortSignal implements EventTarget, so we can use it\n if (typeof EventTarget !== 'undefined' && this.#controller.signal instanceof EventTarget) {\n options.signal = this.#controller.signal\n }\n }\n\n // Some environments (like CloudFlare workers) don't support credentials in\n // RequestInitDict, and there doesn't seem to be any easy way to check for it,\n // so for now let's just make do with a document check :/\n if (typeof document !== 'undefined') {\n options.credentials = this.withCredentials ? 'include' : 'omit'\n }\n\n fetch(this.#url, options)\n .then((res): Promise<string | ArrayBuffer> => {\n res.headers.forEach((value: any, key: any) => {\n this.#resHeaders += `${key}: ${value}\\r\\n`\n })\n this.status = res.status\n this.statusText = res.statusText\n this.readyState = 3 // Loading\n this.onreadystatechange?.()\n return textBody ? res.text() : res.arrayBuffer()\n })\n .then((resBody) => {\n if (typeof resBody === 'string') {\n this.responseText = resBody\n } else {\n this.response = resBody\n }\n this.readyState = 4 // Done\n this.onreadystatechange?.()\n })\n .catch((err: Error) => {\n if (err.name === 'AbortError') {\n this.onabort?.()\n return\n }\n\n this.onerror?.(err)\n })\n }\n}\n","import type {HttpRequest, MiddlewareResponse, RequestOptions} from 'get-it'\nimport parseHeaders from 'parse-headers'\nimport type {RequestAdapter} from '../types'\n\nimport {FetchXhr} from './browser/fetchXhr'\n\n/**\n * Use fetch if it's available, non-browser environments such as Deno, Edge Runtime and more provide fetch as a global but doesn't provide xhr\n * @public\n */\nexport const adapter = (\n typeof XMLHttpRequest === 'function' ? ('xhr' as const) : ('fetch' as const)\n) satisfies RequestAdapter\n\n// Fallback to fetch-based XHR polyfill for non-browser environments like Workers\nconst XmlHttpRequest = adapter === 'xhr' ? XMLHttpRequest : FetchXhr\n\nexport const httpRequester: HttpRequest = (context, callback) => {\n const opts = context.options\n const options = context.applyMiddleware('finalizeOptions', opts) as RequestOptions\n const timers: any = {}\n\n // Allow middleware to inject a response, for instance in the case of caching or mocking\n const injectedResponse = context.applyMiddleware('interceptRequest', undefined, {\n adapter,\n context,\n })\n\n // If middleware injected a response, treat it as we normally would and return it\n // Do note that the injected response has to be reduced to a cross-environment friendly response\n if (injectedResponse) {\n const cbTimer = setTimeout(callback, 0, null, injectedResponse)\n const cancel = () => clearTimeout(cbTimer)\n return {abort: cancel}\n }\n\n // We'll want to null out the request on success/failure\n let xhr = new XmlHttpRequest()\n\n if (xhr instanceof FetchXhr && typeof options.fetch === 'object') {\n xhr.setInit(options.fetch, options.useAbortSignal ?? true)\n }\n\n const headers = options.headers\n const delays = options.timeout\n\n // Request state\n let aborted = false\n let loaded = false\n let timedOut = false\n\n // Apply event handlers\n xhr.onerror = (event: ProgressEvent) => {\n // If fetch is used then rethrow the original error\n if (xhr instanceof FetchXhr) {\n onError(\n event instanceof Error\n ? event\n : new Error(`Request error while attempting to reach is ${options.url}`, {cause: event}),\n )\n } else {\n onError(\n new Error(\n `Request error while attempting to reach is ${options.url}${\n event.lengthComputable ? `(${event.loaded} of ${event.total} bytes transferred)` : ''\n }`,\n ),\n )\n }\n }\n xhr.ontimeout = (event: ProgressEvent) => {\n onError(\n new Error(\n `Request timeout while attempting to reach ${options.url}${\n event.lengthComputable ? `(${event.loaded} of ${event.total} bytes transferred)` : ''\n }`,\n ),\n )\n }\n xhr.onabort = () => {\n stopTimers(true)\n aborted = true\n }\n\n xhr.onreadystatechange = function () {\n // Prevent request from timing out\n resetTimers()\n\n if (aborted || !xhr || xhr.readyState !== 4) {\n return\n }\n\n // Will be handled by onError\n if (xhr.status === 0) {\n return\n }\n\n onLoad()\n }\n\n // @todo two last options to open() is username/password\n xhr.open(\n options.method!,\n options.url,\n true, // Always async\n )\n\n // Some options need to be applied after open\n xhr.withCredentials = !!options.withCredentials\n\n // Set headers\n if (headers && xhr.setRequestHeader) {\n for (const key in headers) {\n // eslint-disable-next-line no-prototype-builtins\n if (headers.hasOwnProperty(key)) {\n xhr.setRequestHeader(key, headers[key])\n }\n }\n }\n\n if (options.rawBody) {\n xhr.responseType = 'arraybuffer'\n }\n\n // Let middleware know we're about to do a request\n context.applyMiddleware('onRequest', {options, adapter, request: xhr, context})\n\n xhr.send(options.body || null)\n\n // Figure out which timeouts to use (if any)\n if (delays) {\n timers.connect = setTimeout(() => timeoutRequest('ETIMEDOUT'), delays.connect)\n }\n\n return {abort}\n\n function abort() {\n aborted = true\n\n if (xhr) {\n xhr.abort()\n }\n }\n\n function timeoutRequest(code: any) {\n timedOut = true\n xhr.abort()\n const error: any = new Error(\n code === 'ESOCKETTIMEDOUT'\n ? `Socket timed out on request to ${options.url}`\n : `Connection timed out on request to ${options.url}`,\n )\n error.code = code\n context.channels.error.publish(error)\n }\n\n function resetTimers() {\n if (!delays) {\n return\n }\n\n stopTimers()\n timers.socket = setTimeout(() => timeoutRequest('ESOCKETTIMEDOUT'), delays.socket)\n }\n\n function stopTimers(force?: boolean) {\n // Only clear the connect timeout if we've got a connection\n if (force || aborted || (xhr && xhr.readyState >= 2 && timers.connect)) {\n clearTimeout(timers.connect)\n }\n\n if (timers.socket) {\n clearTimeout(timers.socket)\n }\n }\n\n function onError(error: Error) {\n if (loaded) {\n return\n }\n\n // Clean up\n stopTimers(true)\n loaded = true\n ;(xhr as any) = null\n\n // Annoyingly, details are extremely scarce and hidden from us.\n // We only really know that it is a network error\n const err = (error ||\n new Error(`Network error while attempting to reach ${options.url}`)) as Error & {\n isNetworkError: boolean\n request?: typeof options\n }\n err.isNetworkError = true\n err.request = options\n callback(err)\n }\n\n function reduceResponse(): MiddlewareResponse {\n return {\n body:\n xhr.response ||\n (xhr.responseType === '' || xhr.responseType === 'text' ? xhr.responseText : ''),\n url: options.url,\n method: options.method!,\n headers: parseHeaders(xhr.getAllResponseHeaders()),\n statusCode: xhr.status!,\n statusMessage: xhr.statusText!,\n }\n }\n\n function onLoad() {\n if (aborted || loaded || timedOut) {\n return\n }\n\n if (xhr.status === 0) {\n onError(new Error('Unknown XHR error'))\n return\n }\n\n // Prevent being called twice\n stopTimers()\n loaded = true\n callback(null, reduceResponse())\n }\n}\n","import {createRequester} from './createRequester'\nimport {httpRequester} from './request/browser-request'\nimport type {ExportEnv, HttpRequest, Middlewares, Requester} from './types'\n\nexport type * from './types'\n\n/** @public */\nexport const getIt = (\n initMiddleware: Middlewares = [],\n httpRequest: HttpRequest = httpRequester,\n): Requester => createRequester(initMiddleware, httpRequest)\n\n/** @public */\nexport const environment = 'browser' satisfies ExportEnv\n\n/** @public */\nexport {adapter} from './request/browser-request'\n"],"names":["Object","defineProperty","exports","value","_commonjsHelpers","require","channelNames","middlehooks","createRequester","initMiddleware","httpRequest","loadedMiddleware","middleware","reduce","ware","name","processOptions","validateOptions","request","opts","channels","target","subscribers","create","nextId","publish","event","id","subscribe","subscriber","createPubSub","applyMiddleware","hook","defaultValue","args","bailEarly","i","length","handler","middlewareReducer","options","context","ongoingRequest","unsubscribe","ctx","err","res","reqErr","error","response","onResponse","abort","returnValue","use","newMiddleware","Error","onReturn","forEach","key","push","clone","trim","string","replace","isArray","arg","prototype","toString","call","parseHeaders","headers","result","headersArr","split","row","index","indexOf","slice","toLowerCase","g","parseHeadersExports","FetchXhr","onabort","onerror","onreadystatechange","ontimeout","readyState","responseText","responseType","status","statusText","withCredentials","method","url","resHeaders","controller","init","useAbortSignal","open","_async","this","getAllResponseHeaders","setRequestHeader","setInit","send","body","textBody","AbortController","EventTarget","signal","document","credentials","fetch","then","text","arrayBuffer","resBody","catch","adapter","XMLHttpRequest","XmlHttpRequest","httpRequester","callback","timers","injectedResponse","cbTimer","setTimeout","clearTimeout","xhr","delays","timeout","aborted","loaded","timedOut","onError","cause","lengthComputable","total","stopTimers","socket","timeoutRequest","statusCode","statusMessage","onLoad","hasOwnProperty","rawBody","connect","code","force","isNetworkError","environment","getIt"],"mappings":"aAEOA,OAAAC,eAAAC,QAAA,aAAA,CAAAC,OAAA,IAAA,IAAAC,EAAAC,QAAA,sCCiBP,MAAMC,EAAe,CACnB,UACA,WACA,WACA,QACA,SAEIC,EAAc,CAClB,iBACA,kBACA,mBACA,kBACA,YACA,aACA,UACA,WACA,aAIK,SAASC,EAAgBC,EAA6BC,GAC3D,MAAMC,EAAgC,GAChCC,EAAgCL,EAAYM,OAChD,CAACC,EAAMC,KACLD,EAAKC,GAAQD,EAAKC,IAAS,GACpBD,GAET,CACEE,eAAgB,CAACA,EAAAA,GACjBC,gBAAiB,CAACA,EAAAA,KAItB,SAASC,EAAQC,GACf,MA2BMC,EAA+Bd,EAAaO,OAAO,CAACQ,EAAQN,KAChEM,EAAON,GC7EN,WACL,MAAMO,iBAAmDtB,OAAOuB,OAAO,MACvE,IAAIC,EAAS,EAeb,MAAO,CACLC,QAPF,SAAiBC,GACf,IAAA,MAAWC,KAAML,EACfA,EAAYK,GAAID,EAAK,EAMvBE,UAhBF,SAAmBC,GACjB,MAAMF,EAAKH,IACX,OAAAF,EAAYK,GAAME,EACX,kBACEP,EAAYK,EAAE,CACvB,EAaJ,CDwDqBG,GACRT,GACN,CAAA,GAGGU,EDpFuB,CAACnB,GAChC,SAAyBoB,EAAMC,KAAiBC,GAC9C,MAAMC,EAAqB,YAATH,EAElB,IAAI7B,EAAQ8B,EACZ,IAAA,IAASG,EAAI,EAAGA,EAAIxB,EAAWoB,GAAMK,SAGnClC,GAAQmC,EAFQ1B,EAAWoB,GAAMI,IAEjBjC,KAAU+B,IAEtBC,GAAchC,GALyBiC,KAU7C,OAAOjC,CACT,ECoE0BoC,CAAkB3B,GAGpC4B,EAAUT,EAAgB,iBAAkBZ,GAGlDY,EAAgB,kBAAmBS,GAGnC,MAAMC,EAAU,CAACD,UAASpB,WAAUW,mBAKpC,IAAIW,EACJ,MAAMC,EAAcvB,EAASF,QAAQU,UAAWgB,IAE9CF,EAAiBhC,EAAYkC,EAAK,CAACC,EAAKC,IAlDvB,EAACC,EAAsBD,EAAyBF,KACjE,IAAII,EAAQD,EACRE,EAAsCH,EAI1C,IAAKE,EACH,IACEC,EAAWlB,EAAgB,aAAce,EAAKF,EAAG,OAC1CC,GACPI,EAAW,KACXD,EAAQH,CAAA,CAMZG,EAAQA,GAASjB,EAAgB,UAAWiB,EAAOJ,GAG/CI,EACF5B,EAAS4B,MAAMvB,QAAQuB,GACdC,GACT7B,EAAS6B,SAASxB,QAAQwB,IA2BoBC,CAAWL,EAAKC,EAAMF,MAKxExB,EAAS+B,MAAMvB,UAAU,KACvBe,IACID,GACFA,EAAeS,UAMnB,MAAMC,EAAcrB,EAAgB,WAAYX,EAAUqB,GAK1D,OAAIW,IAAgBhC,GAClBA,EAASF,QAAQO,QAAQgB,GAGpBW,CAAA,CAGT,OAAAlC,EAAQmC,IAAM,SAAaC,GACzB,IAAKA,EACH,MAAM,IAAIC,MAAM,yDAGlB,GAA6B,mBAAlBD,EACT,MAAM,IAAIC,MACR,+FAIJ,GAAID,EAAcE,UAAY5C,EAAW4C,SAASnB,OAAS,EACzD,MAAM,IAAIkB,MACR,uHAIJ,OAAAhD,EAAYkD,QAASC,IACfJ,EAAcI,IAChB9C,EAAW8C,GAAKC,KAAKL,EAAcI,MAIvC/C,EAAiBgD,KAAKL,GACfpC,CAAA,EAGTA,EAAQ0C,MAAQ,IAAMpD,EAAgBG,EAAkBD,GAExDD,EAAegD,QAAQvC,EAAQmC,KAExBnC,CACT,wCEjKA,IAAI2C,EAAO,SAASC,GAClB,OAAOA,EAAOC,QAAQ,aAAc,GACtC,EACIC,EAAU,SAASC,GACjB,MAA+C,mBAAxCjE,OAAOkE,UAAUC,SAASC,KAAKH,EAC5C,EAEAI,OAAAA,EAAiB,SAAUC,GACzB,IAAKA,EACH,MAAO,CAAA,EAMT,IAAA,IAJIC,wBAAgBhD,OAAO,MAEvBiD,EAAaX,EAAKS,GAASG,MAAM,MAE5BrC,EAAI,EAAGA,EAAIoC,EAAWnC,OAAQD,IAAK,CAC1C,IAAIsC,EAAMF,EAAWpC,GACjBuC,EAAQD,EAAIE,QAAQ,KACtBlB,EAAMG,EAAKa,EAAIG,MAAM,EAAGF,IAAQG,cAChC3E,EAAQ0D,EAAKa,EAAIG,MAAMF,EAAQ,WAEtBJ,EAAOb,GAAU,IAC1Ba,EAAOb,GAAOvD,EACL6D,EAAQO,EAAOb,IACxBa,EAAOb,GAAKC,KAAKxD,GAEjBoE,EAAOb,GAAO,CAAEa,EAAOb,GAAMvD,EAEnC,CAEE,OAAOoE,CACT,KC5BOF,iBAAAjE,EAAA2E,EAAAC,GAAA,MAAMC,EAMXC,QACAC,QACAC,mBACAC,UAIAC,WAAgC,EAChCrC,SACAsC,aAA+C,GAC/CC,aAA+C,GAC/CC,OACAC,WACAC,gBAKAC,GACAC,GACAC,GACAxB,GAAmC,CAAA,EACnCyB,GACAC,GAAqB,CAAA,EACrBC,GAEA,IAAAC,CAAKN,EAAgBC,EAAaM,GAChCC,MAAKR,EAAUA,EACfQ,MAAKP,EAAOA,EACZO,MAAKN,EAAc,GACnBM,KAAKd,WAAa,EAClBc,KAAKhB,uBACLgB,MAAKL,OAAc,CAAA,CAErB,KAAA5C,GACMiD,MAAKL,GACPK,MAAKL,EAAY5C,OAAM,CAG3B,qBAAAkD,GACE,OAAOD,MAAKN,CAAA,CAEd,gBAAAQ,CAAiBvF,EAAcZ,GAC7BiG,MAAK9B,EAASvD,GAAQZ,CAAA,CAGxB,OAAAoG,CAAQP,EAAmBC,GAAiB,GAC1CG,MAAKJ,EAAQA,EACbI,MAAKH,EAAkBA,CAAA,CAEzB,IAAAO,CAAKC,GACH,MAAMC,EAAiC,gBAAtBN,KAAKZ,aAChBhD,EAAuB,IACxB4D,MAAKJ,EACRJ,OAAQQ,MAAKR,EACbtB,QAAS8B,MAAK9B,EACdmC,QAE6B,mBAApBE,iBAAkCP,MAAKH,IAChDG,MAAKL,EAAc,IAAIY,uBAIZC,YAAgB,KAAeR,MAAKL,EAAYc,kBAAkBD,cAC3EpE,EAAQqE,OAAST,MAAKL,EAAYc,gBAO3BC,SAAa,MACtBtE,EAAQuE,YAAcX,KAAKT,gBAAkB,UAAY,QAG3DqB,MAAMZ,MAAKP,EAAMrD,GACdyE,KAAMnE,IACLA,EAAIwB,QAAQb,QAAQ,CAACtD,EAAYuD,KAC/B0C,MAAKN,GAAe,GAAGpC,MAAQvD,UAEjCiG,KAAKX,OAAS3C,EAAI2C,OAClBW,KAAKV,WAAa5C,EAAI4C,WACtBU,KAAKd,WAAa,EAClBc,KAAKhB,uBACEsB,EAAW5D,EAAIoE,OAASpE,EAAIqE,gBAEpCF,KAAMG,IACkB,iBAAZA,EACThB,KAAKb,aAAe6B,EAEpBhB,KAAKnD,SAAWmE,EAElBhB,KAAKd,WAAa,EAClBc,KAAKhB,yBAENiC,MAAOxE,IACW,eAAbA,EAAI9B,KAKRqF,KAAKjB,UAAUtC,GAJbuD,KAAKlB,aAKR,ECrGA,MAAMoC,EACe,mBAAnBC,eAAiC,MAAmB,QAIvDC,EAA6B,QAAZF,EAAoBC,eAAiBtC,EAE/CwC,EAA6B,CAAChF,EAASiF,KAClD,MAAMvG,EAAOsB,EAAQD,QACfA,EAAUC,EAAQV,gBAAgB,kBAAmBZ,GACrDwG,EAAc,CAAA,EAGdC,EAAmBnF,EAAQV,gBAAgB,wBAAoB,EAAW,CAC9EuF,UACA7E,YAKF,GAAImF,EAAkB,CACpB,MAAMC,EAAUC,WAAWJ,EAAU,EAAG,KAAME,GAE9C,MAAO,CAACzE,MADO,IAAM4E,aAAaF,GACb,CAIvB,IAAIG,EAAM,IAAIR,EAEVQ,aAAe/C,GAAqC,iBAAlBzC,EAAQwE,OAC5CgB,EAAIzB,QAAQ/D,EAAQwE,MAAOxE,EAAQyD,iBAAkB,GAGvD,MAAM3B,EAAU9B,EAAQ8B,QAClB2D,EAASzF,EAAQ0F,QAGvB,IAAIC,GAAU,EACVC,GAAS,EACTC,GAAW,EA8Df,GA3DAL,EAAI7C,QAAWzD,IAGX4G,EADEN,aAAe/C,EAEfvD,aAAiB6B,MACb7B,EACA,IAAI6B,MAAM,8CAA8Cf,EAAQqD,MAAO,CAAC0C,MAAO7G,IAInF,IAAI6B,MACF,8CAA8Cf,EAAQqD,MACpDnE,EAAM8G,iBAAmB,IAAI9G,EAAM0G,aAAa1G,EAAM+G,2BAA6B,QAM7FT,EAAI3C,UAAa3D,IACf4G,EACE,IAAI/E,MACF,6CAA6Cf,EAAQqD,MACnDnE,EAAM8G,iBAAmB,IAAI9G,EAAM0G,aAAa1G,EAAM+G,2BAA6B,QAK3FT,EAAI9C,QAAU,KACZwD,GAAW,GACXP,GAAU,GAGZH,EAAI5C,mBAAqB,WAyElB6C,IAILS,IACAf,EAAOgB,OAASb,WAAW,IAAMc,EAAe,mBAAoBX,EAAOU,UA1EvER,GAAYH,GAA0B,IAAnBA,EAAI1C,YAKR,IAAf0C,EAAIvC,QAsHV,WACE,KAAI0C,GAAWC,GAAUC,GAIzB,CAAA,GAAmB,IAAfL,EAAIvC,OAEN,YADA6C,EAAQ,IAAI/E,MAAM,sBAKpBmF,IACAN,GAAS,EACTV,EAAS,KAzBF,CACLjB,KACEuB,EAAI/E,WACkB,KAArB+E,EAAIxC,cAA4C,SAArBwC,EAAIxC,aAA0BwC,EAAIzC,aAAe,IAC/EM,IAAKrD,EAAQqD,IACbD,OAAQpD,EAAQoD,OAChBtB,QAASD,EAAa2D,EAAI3B,yBAC1BwC,WAAYb,EAAIvC,OAChBqD,cAAed,EAAItC,YAiBU,CAAA,CA/H/BqD,EAAO,EAITf,EAAI9B,KACF1D,EAAQoD,OACRpD,EAAQqD,KACR,GAIFmC,EAAIrC,kBAAoBnD,EAAQmD,gBAG5BrB,GAAW0D,EAAI1B,iBACjB,IAAA,MAAW5C,KAAOY,EAEZA,EAAQ0E,eAAetF,IACzBsE,EAAI1B,iBAAiB5C,EAAKY,EAAQZ,IAKxC,OAAIlB,EAAQyG,UACVjB,EAAIxC,aAAe,eAIrB/C,EAAQV,gBAAgB,YAAa,CAACS,UAAS8E,UAASpG,QAAS8G,EAAKvF,YAEtEuF,EAAIxB,KAAKhE,EAAQiE,MAAQ,MAGrBwB,IACFN,EAAOuB,QAAUpB,WAAW,IAAMc,EAAe,aAAcX,EAAOiB,UAGjE,CAAC/F,MAER,WACEgF,GAAU,EAENH,GACFA,EAAI7E,OAAM,GAId,SAASyF,EAAeO,GACtBd,GAAW,EACXL,EAAI7E,QACJ,MAAMH,EAAa,IAAIO,MACZ,oBAAT4F,EACI,kCAAkC3G,EAAQqD,MAC1C,sCAAsCrD,EAAQqD,OAEpD7C,EAAMmG,KAAOA,EACb1G,EAAQrB,SAAS4B,MAAMvB,QAAQuB,EAAK,CAYtC,SAAS0F,EAAWU,IAEdA,GAASjB,GAAYH,GAAOA,EAAI1C,YAAc,GAAKqC,EAAOuB,UAC5DnB,aAAaJ,EAAOuB,SAGlBvB,EAAOgB,QACTZ,aAAaJ,EAAOgB,OAAM,CAI9B,SAASL,EAAQtF,GACf,GAAIoF,EACF,OAIFM,GAAW,GACXN,GAAS,EACPJ,EAAc,KAIhB,MAAMnF,EAAOG,GACX,IAAIO,MAAM,2CAA2Cf,EAAQqD,OAI/DhD,EAAIwG,gBAAiB,EACrBxG,EAAI3B,QAAUsB,EACdkF,EAAS7E,EAAG,GCtLW3C,QAAAoH,QAAAA,EAAApH,QAAAoJ,YAAA,UAAApJ,QAAAqJ,MANN,CACnB9I,EAA8B,GAC9BC,EAA2B+G,IACbjH,EAAgBC,EAAgBC","x_google_ignoreList":[3]}