UNPKG

@cervello/react

Version:

🤯 Simple, reactive, tiny and performant state-management library

1 lines • 28.5 kB
{"version":3,"file":"cervello.cjs","sources":["../src/types/shared.ts","../src/lib/utils/object.ts","../src/lib/helpers/new-proxify-store.ts","../src/lib/store/new-index.ts","../src/lib/utils/subject.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/ban-types */\nexport type WithoutType<T, V, WithNever = {\n [K in keyof T]: Exclude<T[K], undefined> extends V\n ? never\n : (T[K] extends Record<string, unknown>\n ? WithoutType<T[K], V>\n : T[K])\n}> = Pick<WithNever, {\n [K in keyof WithNever]: WithNever[K] extends never ? never : K\n}[keyof WithNever]>\n\n\n\nexport type ObjectFromAttributes<T, Attributes extends Array< keyof WithoutType<T, Function> > > = {\n [k in Attributes[number]]: T[k]\n}\n\nexport type Maybe<T> = T | undefined\n\n\n\nexport type UseSelector<T> = <Attributes extends Array< Exclude<keyof WithoutType<T, Function>, '$value'> >>(\n selectors: Attributes,\n isEqualFunction?: (previousState: ObjectFromAttributes<T, Attributes>, currentState: ObjectFromAttributes<T, Attributes>) => boolean,\n) => T\n\nexport type FieldPath<T extends Record<string, any>> = {\n [K in keyof Required<T>]: T[K] extends Record<string, any>\n ? K extends string\n\n ? T[K] extends Function\n ? never\n : T[K] extends Array<any>\n ? K\n : `${K}.*` | `${K}.${FieldPath<T[K]>}`\n : never\n : K extends string\n ? K\n : never\n}[keyof T]\n\nexport const nonReactiveObjectSymbol = Symbol('nonReactiveObject')\nexport type StoreChange<T extends Record<string, any>> = {\n change: {\n fieldPath: FieldPath<T>\n newValue: any\n previousValue: any\n }\n storeValue: T\n}\n","/* eslint-disable no-cond-assign */\n\nimport { INTERNAL_VALUE_PROP } from '../helpers/constants'\n\n\n/**\n * Clones all the provided object and nested properties and it also\n * iterates nested arrays to deepClone them\n *\n * @param obj - base object to be cloned\n * @returns new cloned object with new reference\n */\nexport function deepClone2 <T> (obj: T): T {\n if (!obj || typeof obj !== 'object')\n return obj\n\n let newObj = {} as any\n\n if (Array.isArray(obj)) {\n newObj = obj.map(item => deepClone(item))\n // eslint-disable-next-line no-prototype-builtins\n } else if (!obj.hasOwnProperty('$$typeof')) {\n Object.entries(obj).forEach(([key, value]) => {\n newObj[key] = deepClone(value)\n })\n Object.getOwnPropertySymbols(obj).forEach((symbol) => {\n newObj[symbol] = (obj as any)[symbol]\n })\n } else {\n newObj = obj\n }\n\n return newObj as T\n}\n\n// function copyBuffer (cur: ArrayBufferView) {\n// if (cur instanceof Buffer)\n// return Buffer.from(cur)\n//\n//\n// return new cur.constructor(cur.buffer.slice(), cur.byteOffset, cur.length)\n// }\n\n\n// INFO: From `rfdc` (really-fast-deep-clone) package for faster cloning taking care of circular references\nexport function deepClone <T> (obj: T): T {\n const refs: Array<any> = []\n const refsNew: Array<any> = []\n\n const constructorHandlers = new Map()\n\n constructorHandlers.set(Date, (o: string | number | Date) => new Date(o))\n constructorHandlers.set(Map, (o: Iterable<unknown> | ArrayLike<unknown>, fn: any) => new Map(cloneArray(Array.from(o), fn)))\n constructorHandlers.set(Set, (o: Iterable<unknown> | ArrayLike<unknown>, fn: any) => new Set(cloneArray(Array.from(o), fn)))\n\n let handler = null\n\n return clone(obj)\n\n function cloneArray (a: any, fn: any): any {\n const keys = Object.keys(a)\n const a2 = new Array(keys.length) as any\n\n for (let i = 0; i < keys.length; i++) {\n const k = keys[i]\n const cur = a[k]\n\n if (typeof cur !== 'object' || cur === null) {\n a2[k] = cur\n } else if (cur.constructor !== Object && (handler = constructorHandlers.get(cur.constructor))) {\n a2[k] = handler(cur, fn)\n // } else if (ArrayBuffer.isView(cur)) {\n // a2[k] = copyBuffer(cur)\n } else {\n const index = refs.indexOf(cur)\n\n if (index !== -1)\n a2[k] = refsNew[index]\n else\n a2[k] = fn(cur)\n }\n }\n\n return a2\n }\n\n function clone (o: any): any {\n if (typeof o !== 'object' || o === null) return o\n if (Array.isArray(o)) return cloneArray(o, clone)\n if (o.constructor !== Object && (handler = constructorHandlers.get(o.constructor)))\n return handler(o, clone)\n\n const o2 = {} as any\n\n refs.push(o)\n refsNew.push(o2)\n\n\n Object.getOwnPropertySymbols(o).forEach((symbol) => {\n o2[symbol] = (o)[symbol]\n })\n\n for (const k in o) {\n if (!Object.hasOwnProperty.call(o, k)) continue\n const cur = o[k]\n\n\n if (typeof cur !== 'object' || cur === null) {\n o2[k] = cur\n } else if (cur.constructor !== Object && (handler = constructorHandlers.get(cur.constructor))) {\n o2[k] = handler(cur, clone)\n // } else if (ArrayBuffer.isView(cur)) {\n // o2[k] = copyBuffer(cur)\n } else {\n const i = refs.indexOf(cur)\n\n if (i !== -1)\n o2[k] = refsNew[i]\n else\n o2[k] = clone(cur)\n }\n }\n refs.pop()\n refsNew.pop()\n\n\n return o2\n }\n}\n\n/**\n * Guard to check is variable is an object\n * @param obj - variable to be checked\n * @returns boolean\n */\nexport const isObject = (obj: unknown): obj is Record<string | symbol, unknown> => (\n obj !== null\n && typeof obj === 'object'\n && !Array.isArray(obj)\n)\n\n\n\n\n/**\n * Returns the actual target value instead of root\n * object with internals props like $$value$$\n *\n * @param target - object from subscription or proxy\n * @returns actual value\n */\nexport const okTarget = (target: any): any => target[INTERNAL_VALUE_PROP] ?? target\n\n\n\n\n/**\n * Gets an object with just the properties requested\n * instead of the full object\n *\n * @param properties - object properties\n * @param obj - target to get the properties\n * @returns New object with just the requested properties\n */\nexport function getPartialObjectFromProperties<T> (properties: Array<keyof T>, obj: T): any {\n return properties.reduce<any>((acc, curr) => {\n acc[curr] = obj[curr]\n\n return acc\n }, {})\n}\n\n\n\nconst stringify = (obj: any): string => JSON.stringify(obj)\n\n/**\n * Compare 2 provided objects by stringing them\n * @param a - first object\n * @param b - second object\n * @returns boolean\n */\nexport const contentComparer = (a: any, b: any): boolean => stringify(a) === stringify(b)\n","import { isValidElement } from 'react'\n\nimport { nonReactiveObjectSymbol } from '../../types/shared'\nimport { isObject } from '../utils/object'\n\nimport type { StoreChange } from '../../types/shared'\nimport type { CacheableSubject } from '../utils/subject'\n\n\n\n// @ts-expect-error - Object.hasOwn is not defined in older Safari's browsers\n('hasOwn' in Object) || (Object.hasOwn = Object.call.bind(Object.hasOwnProperty))\n\nconst ROOT_VALUE = Symbol('value')\n\n\nexport function proxifyStore <T extends Record<string | symbol, any>> (\n store$$: CacheableSubject<StoreChange<T>>,\n objectToProxify: T,\n opts: {\n nestedFieldPath?: string\n parentObjectToProxify?: any\n // beforeChange?: (storeChange: StoreChange<T>) => any\n afterChange?: (storeChange: Array<StoreChange<T>>) => void\n } = {},\n): T {\n const fieldPath = opts.nestedFieldPath ?? 'root'\n\n const objectWithRootValue = {\n [ROOT_VALUE]: objectToProxify,\n } as unknown as T\n\n const rootFunctions = fieldPath === 'root'\n ? Object.fromEntries(Object.entries(objectToProxify).filter(([,v]) => typeof v === 'function'))\n : {}\n\n return new Proxy(objectWithRootValue, {\n get (targetObject, propName, receiver) {\n if (propName === '_$fieldPath') return fieldPath\n\n const isRootTarget = Object.hasOwn(targetObject, ROOT_VALUE)\n const target = isRootTarget ? targetObject[ROOT_VALUE] : targetObject\n\n if (propName === 'toJSON') {\n return () => {\n // Remove circular references before stringifying\n // to prevent JSON.stringify(storeProxy) from failing\n return removeCircularReferences(target)\n }\n }\n\n if (propName === '$value') {\n // return deepClone(target)\n // return getUnproxiedObject(target)\n return target\n }\n\n const propertyValue = Reflect.get(target, propName, receiver)\n\n if (typeof propName === 'symbol') return propertyValue\n\n\n if (typeof propertyValue === 'function')\n return (propertyValue as () => any).bind(receiver)\n\n\n // Check if it's correct to be a reactive object\n // & is not a circular reference or the same object\n if (isValidReactiveObject(propertyValue) && propertyValue !== target) {\n const newNestedFieldPath = `${fieldPath}.${propName}`\n\n\n if (propertyValue._$fieldPath === newNestedFieldPath) return propertyValue\n\n const proxiedNestedObject = proxifyStore(\n store$$ as any,\n propertyValue,\n {\n nestedFieldPath: newNestedFieldPath,\n parentObjectToProxify: opts.parentObjectToProxify ?? target,\n // beforeChange: opts.beforeChange,\n afterChange: opts.afterChange,\n },\n )\n\n return target[propName] = proxiedNestedObject\n }\n\n return propertyValue\n },\n\n\n set (parentObject, key, newValue, receiver) {\n if (typeof key === 'symbol') return true\n\n const value = newValue\n const isRootTarget = Object.hasOwn(parentObject, ROOT_VALUE)\n\n // INFO: Internal only.\n // This is used to set the value of the store without notifying the store\n if (isRootTarget && key === '$$value') {\n (parentObject as any)[ROOT_VALUE] = value\n\n return true\n }\n\n if (isRootTarget && key === '$value') {\n const previousValue = parentObject[ROOT_VALUE]\n\n if (value === previousValue) return true\n\n if (safeStringify(value) === safeStringify(previousValue)) return true\n // if (JSON.stringify(value) === JSON.stringify(previousValue)) return true\n\n if (fieldPath !== 'root') {\n (parentObject as any)[ROOT_VALUE] = value\n } else {\n (parentObject as any)[ROOT_VALUE] = {\n ...rootFunctions,\n ...value,\n }\n store$$.next({\n // To be disabled for performance and send same store reference\n // storeValue: JSON.parse(JSON.stringify(targetObject[ROOT_VALUE])),\n storeValue: parentObject[ROOT_VALUE],\n change: {\n fieldPath: 'root' as any,\n newValue: value,\n previousValue,\n },\n })\n }\n\n return true\n }\n\n const realInnerObject = isRootTarget ? parentObject[ROOT_VALUE] : parentObject\n const previousValue = Reflect.get(realInnerObject, key, receiver)\n\n\n if (previousValue === value) return true\n\n\n // New object values, check if the field has already a proxy created to use it instead of reacreating a new instance\n if (isObject(value) && !isValidElement(value) && !value[nonReactiveObjectSymbol] && previousValue?._$fieldPath)\n previousValue.$value = value\n else\n Reflect.set(realInnerObject, key, value, realInnerObject)\n\n\n const nextStoreChange = {\n // To be disabled for performance and send same store reference\n // storeValue: JSON.parse(JSON.stringify(opts?.parentObjectToProxify ?? target)),\n storeValue: opts?.parentObjectToProxify ?? realInnerObject,\n change: {\n fieldPath: `${fieldPath}.${key}`.replace('root.', '') as any,\n newValue: value,\n previousValue,\n },\n }\n\n store$$.next(nextStoreChange)\n opts.afterChange?.([nextStoreChange])\n\n return true\n },\n\n has (t, p) {\n return Reflect.has(t[ROOT_VALUE], p)\n },\n\n ownKeys (t) {\n return Reflect.ownKeys(t[ROOT_VALUE])\n },\n\n getOwnPropertyDescriptor (t, p) {\n return Reflect.getOwnPropertyDescriptor(t[ROOT_VALUE], p)\n },\n\n })\n}\n\n//\n// function getUnproxiedObject (obj: any): any {\n// if (obj && typeof obj === 'object') {\n// if (obj[ROOT_VALUE]?.[ROOT_VALUE]) return '[Circular reference]'\n//\n// // Check if the object is a proxy\n// if (obj[ROOT_VALUE])\n// return getUnproxiedObject(obj[ROOT_VALUE])\n//\n//\n// // If it's not a proxy, return the object itself\n// return obj\n// }\n//\n// // If it's not an object, return it as is\n// return obj\n// }\n\n\n\nfunction isValidReactiveObject <T extends Record<string, any>> (value: T): boolean {\n return isObject(value) && !isValidElement(value) && !(value as any)[nonReactiveObjectSymbol]\n}\n\nfunction safeStringify (obj: any): string {\n // use removeCircularReferences to avoid circular references\n const cleanedObj = removeCircularReferences(obj)\n\n return JSON.stringify(\n cleanedObj,\n (_key, value) => {\n if (isValidElement(value))\n return { props: safeStringify(value.props), type: value.type }\n\n return value\n })\n}\n\nfunction removeCircularReferences (obj: any): any {\n const seen = new WeakSet()\n\n function traverse (value: any): any {\n if (value && typeof value === 'object') {\n // If the object has already been seen, it's a circular reference\n if (seen.has(value))\n return null\n\n seen.add(value)\n\n if (Array.isArray(value))\n return value.map(traverse)\n\n\n const result: any = {}\n\n for (const key in value) {\n if (Object.prototype.hasOwnProperty.call(value, key))\n result[key] = traverse(value[key])\n }\n\n return result\n }\n\n // Return primitive values as-is\n return value\n }\n\n return traverse(obj)\n}\n","\nimport { useLayoutEffect, useRef, useSyncExternalStore } from 'react'\n\nimport { nonReactiveObjectSymbol } from '../../types/shared'\nimport { proxifyStore } from '../helpers/new-proxify-store'\nimport { deepClone } from '../utils/object'\nimport { createCacheableSubject } from '../utils/subject'\n\nimport type { FieldPath, StoreChange } from '../../types/shared'\n\n\n\n\n// export type CervelloOptions<StoreValue extends Record<string, any>> = {\n// beforeChange?: (storeChange: StoreChange<StoreValue>) => unknown | undefined\n// afterChange?: (storeChange: Array<StoreChange<StoreValue>>) => void\n// }\n\nexport type CervelloOptions<StoreValue extends Record<string, any>> = {\n afterChange?: (storeChange: Array<StoreChange<StoreValue>>) => void\n}\n\nexport type CervelloUseStoreOptions<StoreValue extends Record<string, any>> = {\n initialValue?: (currentStore: StoreValue) => StoreValue,\n setValueOnMount?: (currentStore: StoreValue) => Promise<StoreValue>,\n select?:\n | Array<FieldPath<StoreValue>>\n | (() => Array<FieldPath<StoreValue>>)\n onChange?: (storeChange: Array<StoreChange<StoreValue>>) => void\n}\n\ntype MutableStoreValue<T extends Record<string, any>> = {\n $value: T\n} & T\n\n\n\n\n\n\n\n\nexport function nonReactive <T extends Record<string, any>> (initialValue: T): T {\n Object.defineProperty(initialValue, nonReactiveObjectSymbol, {\n value: true,\n enumerable: false,\n writable: false,\n configurable: false,\n })\n\n return initialValue\n}\n\n\nexport function cervello <StoreValue extends Record<PropertyKey, any>> (\n initialValue: StoreValue,\n options?: CervelloOptions<StoreValue>,\n): {\n store: MutableStoreValue<StoreValue>,\n reset: () => void,\n useStore: (options?: CervelloUseStoreOptions<StoreValue>) => MutableStoreValue<StoreValue>\n } {\n const {\n // beforeChange,\n afterChange,\n } = options ?? {}\n\n const clonedInitialValue = (initialValue)\n const store$$ = createCacheableSubject<StoreChange<StoreValue>>(clonedInitialValue as any)\n\n const proxiedStore = proxifyStore(\n store$$ as any,\n clonedInitialValue,\n // { beforeChange, afterChange },\n { afterChange },\n ) as MutableStoreValue<StoreValue>\n\n\n return {\n store: proxiedStore,\n reset: () => {\n proxiedStore.$value = deepClone(initialValue)\n },\n useStore: (options) => {\n const initialValue = options?.initialValue?.(proxiedStore.$value)\n const isInitialValueSet = useRef(false)\n\n if (!isInitialValueSet.current && initialValue && initialValue !== proxiedStore) {\n isInitialValueSet.current = true;\n (proxiedStore as any).$value = initialValue\n }\n\n const selectFieldPaths = useRef(\n (typeof options?.select === 'function'\n ? options?.select?.()\n : options?.select)\n ?? [],\n )\n\n const selectedFieldPathsForNestedObjects = useRef(\n selectFieldPaths.current\n .filter(fp => fp.includes('.*'))\n .map(fp => fp.replace('.*', '')),\n )\n\n\n useLayoutEffect(() => {\n if (options?.setValueOnMount) {\n void options.setValueOnMount(proxiedStore.$value).then((value) => {\n proxiedStore.$value = value\n }).catch((err) => {\n console.error('Error setting initial value on mount', err)\n })\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n\n useSyncExternalStore(\n (onStoreChange) => {\n const subscription = store$$.subscribe({\n next: (sc) => {\n const storeChanges = Array.isArray(sc)\n ? sc as Array<StoreChange<StoreValue>>\n : [sc]\n\n if (!options?.select) {\n onStoreChange()\n options?.onChange?.(storeChanges)\n\n return\n }\n\n if (storeChanges.some(nextChange => (\n nextChange.change.fieldPath === 'root'\n || selectFieldPaths.current.includes(nextChange.change.fieldPath))\n || selectedFieldPathsForNestedObjects.current.find(fp => nextChange.change.fieldPath.startsWith(fp)),\n )) {\n onStoreChange()\n options?.onChange?.(storeChanges)\n }\n },\n })\n\n return () => {\n subscription.unsubscribe()\n }\n },\n () => store$$.getValue(),\n () => store$$.getValue(),\n )\n\n return proxiedStore\n },\n }\n}\n","\nexport type Noop = () => void\n\n\nexport type Observer<T> = {\n next: (value: T) => void\n}\n\nexport type Subscription = {\n unsubscribe: Noop\n}\n\nexport type CacheableSubject<T> = {\n getValue: () => T\n subscribe: (value: Observer<T>) => Subscription\n unSubscribeAll: Noop\n} & Observer<T>\n\n\nconst WITH_FLUSHING = true\n\nexport function createCacheableSubject<T> (defaultValue: T, getValueOnSubscribe = false): CacheableSubject<T> {\n let isFlushing = false\n let itemsToFlush: Array<T> = []\n\n let observerList: Array<Observer<T>> = []\n let value = defaultValue\n\n const getValue = (): T => value\n\n const next = (newValue: T): void => {\n value = newValue\n\n if (!WITH_FLUSHING) {\n observerList.forEach((o) => { o.next(newValue) })\n\n return\n }\n\n itemsToFlush.push(newValue)\n // observerList.forEach((o) => { o.next(newValue) })\n\n if (!isFlushing) {\n isFlushing = true\n void Promise.resolve().then(() => {\n observerList.forEach((o) => { o.next(itemsToFlush as T) })\n itemsToFlush = []\n isFlushing = false\n })\n }\n }\n\n const subscribe = (observer: Observer<T>): Subscription => {\n // Push cached value on subscribe\n if (getValueOnSubscribe) observer.next(value)\n // Store the observer to be notified\n observerList.push(observer)\n\n return {\n unsubscribe: () => {\n observerList = observerList.filter(o => o !== observer)\n },\n }\n }\n\n const unSubscribeAll = (): void => {\n observerList = []\n }\n\n return {\n getValue,\n next,\n subscribe,\n unSubscribeAll,\n }\n}\n\n"],"names":["nonReactiveObjectSymbol","Symbol","obj","Array","isArray","Object","hasOwn","call","bind","hasOwnProperty","ROOT_VALUE","proxifyStore","store$$","objectToProxify","opts","_opts$nestedFieldPath","_objectWithRootValue","fieldPath","nestedFieldPath","objectWithRootValue","rootFunctions","fromEntries","entries","filter","_ref","Proxy","get","targetObject","propName","receiver","removeCircularReferences","target","value","propertyValue","Reflect","isObject","isValidElement","_opts$parentObjectToP","newNestedFieldPath","_$fieldPath","parentObjectToProxify","afterChange","proxiedNestedObject","set","parentObject","key","newValue","_opts$parentObjectToP2","_opts","isRootTarget","previousValue","safeStringify","_extends","next","storeValue","change","realInnerObject","$value","nextStoreChange","replace","has","t","p","ownKeys","getOwnPropertyDescriptor","cleanedObj","JSON","stringify","_key","props","type","seen","WeakSet","traverse","add","map","result","prototype","initialValue","options","clonedInitialValue","createCacheableSubject","defaultValue","getValueOnSubscribe","isFlushing","observerList","getValue","itemsToFlush","push","resolve","then","forEach","o","subscribe","observer","unsubscribe","unSubscribeAll","proxiedStore","store","reset","deepClone","refs","refsNew","constructorHandlers","Map","Date","fn","cloneArray","from","Set","clone","constructor","handler","o2","getOwnPropertySymbols","symbol","k","cur","i","indexOf","pop","a","keys","length","a2","index","useStore","_ref2","isInitialValueSet","useRef","current","selectFieldPaths","select","selectedFieldPathsForNestedObjects","fp","includes","useLayoutEffect","setValueOnMount","err","console","error","useSyncExternalStore","onStoreChange","subscription","sc","storeChanges","onChange","some","nextChange","find","startsWith","nonReactive","defineProperty","enumerable","writable","configurable"],"mappings":"uBAyCoCA,EAAGC,OAAO,yPC8FvC,MAAiB,SAACC,UACf,OAALA,GACe,qBACdC,MAAMC,QAAQF,EAAI,EC/HvB,WAAYG,SAAYA,OAAOC,OAASD,OAAOE,KAAKC,KAAKH,OAAOI,iBAEjE,IAAgBC,EAAGT,OAAO,kBAGEU,EAC1BC,EACAC,EACAC,GAKM,IAAAC,EAAAC,OALNF,IAAAA,IAAAA,EAKI,CAAE,GAEN,IAAeG,SAAAF,EAAGD,EAAKI,mBAAmB,OAEjBC,IAAAH,EAAA,CAAA,GACtBN,GAAaG,EAAeG,GAGzBI,EAA8B,SAAdH,EAClBZ,OAAOgB,YAAYhB,OAAOiB,QAAQT,GAAiBU,OAAO,SAAAC,GAAI,MAAmB,mBAAnBA,EAAA,EAA6B,IAC3F,CAAE,EAEN,OAAWC,IAAAA,MAAMN,EAAqB,CACpCO,aAAKC,EAAcC,EAAUC,GAC3B,GAAiB,gBAAbD,EAA4B,OAAgBX,EAEhD,MAAqBZ,OAAOC,OAAOqB,EAAcjB,GACnBiB,EAAajB,GAAciB,EAEzD,GAAiB,WAAbC,EACF,OAAY,WAGV,OAA+BE,EAACC,EAClC,EAGF,GAAiB,WAAbH,EAGF,OACFG,EAEA,IAiJ0DC,EAjJvCC,EAAGC,QAAQR,IAAIK,EAAQH,EAAUC,GAEpD,GAAwB,iBAAbD,EAAuB,OAAOK,EAGzC,GAA6B,mBAALA,EACtB,SAAoCzB,KAAKqB,GAK3C,GAuIWM,EAD+CH,EAtIhCC,KAuIHG,EAAcA,eAACJ,KAAYA,EAAchC,IAvIpBiC,IAAkBF,EAAQ,CAAA,IAAAM,EAC9DC,EAAwBrB,EAAS,IAAIW,EAG3C,GAAIK,EAAcM,cAAgBD,EAAoB,SAEtD,MAA4B3B,EAC1BC,EACAqB,EACA,CACEf,gBAAiBoB,EACjBE,sBAAiD,OAA1B1B,EAAAA,EAAK0B,uBAAqBH,EAAIN,EAErDU,YAAa3B,EAAK2B,cAItB,OAAaV,EAACH,GAAYc,CAC5B,CAEA,OAAOT,CACT,EAGAU,aAAKC,EAAcC,EAAKC,EAAUjB,GAAQ,IAAAkB,EAAAC,EACxC,GAAmB,iBAALH,EAAe,OAAW,EAExC,IAAMb,EAAQc,EACIG,EAAG5C,OAAOC,OAAOsC,EAAclC,GAIjD,GAAIuC,GAAwB,YAARJ,EAGlB,OAFCD,EAAqBlC,GAAcsB,GAE7B,EAGT,GAAIiB,GAAwB,WAARJ,EAAkB,CACpC,MAAsBD,EAAalC,GAEnC,OAAIsB,IAAUkB,GAEVC,EAAcnB,KAAWmB,EAAcD,KAGzB,SAAdjC,EACD2B,EAAqBlC,GAAcsB,GAEnCY,EAAqBlC,GAAW0C,EAAA,CAAA,EAC5BhC,EACAY,GAELpB,EAAQyC,KAAK,CAGXC,WAAYV,EAAalC,GACzB6C,OAAQ,CACNtC,UAAW,OACX6B,SAAUd,EACVkB,cAAAA,SAMR,CAEA,IAAMM,EAAkBP,EAAeL,EAAalC,GAAckC,EAC/CM,EAAGhB,QAAQR,IAAI8B,EAAiBX,EAAKhB,GAGxD,GAAIqB,IAAkBlB,EAAO,OAAW,EAIpCG,EAASH,KAAWI,iBAAeJ,KAAWA,EAAMhC,IAAyC,MAAbkD,GAAAA,EAAeX,YACjGW,EAAcO,OAASzB,EAEhBE,QAACS,IAAIa,EAAiBX,EAAKb,EAAOwB,GAG3C,IAAqBE,EAAG,CAGtBJ,WAA2CE,OAAjCT,EAAE,OAAFC,EAAElC,QAAA,EAAAkC,EAAMR,uBAAyBgB,EAAAA,EAC3CD,OAAQ,CACNtC,WAAcA,EAAa4B,IAAAA,GAAMc,QAAQ,QAAS,IAClDb,SAAUd,EACVkB,cAAAA,IAOJ,OAHAtC,EAAQyC,KAAKK,GACG,MAAhB5C,EAAK2B,aAAL3B,EAAK2B,YAAc,CAACiB,MAGtB,EAEAE,IAAG,SAAEC,EAAGC,GACN,OAAc5B,QAAC0B,IAAIC,EAAEnD,GAAaoD,EACpC,EAEAC,QAAO,SAAEF,GACP,OAAO3B,QAAQ6B,QAAQF,EAAEnD,GAC3B,EAEAsD,yBAAwB,SAAEH,EAAGC,GAC3B,OAAO5B,QAAQ8B,yBAAyBH,EAAEnD,GAAaoD,EACzD,GAGJ,CA0BA,WAAwB5D,GAEtB,IAAgB+D,EAAGnC,EAAyB5B,GAE5C,OAAWgE,KAACC,UACVF,EACA,SAACG,EAAMpC,GACL,OAAII,EAAAA,eAAeJ,GACV,CAAEqC,MAAOlB,EAAcnB,EAAMqC,OAAQC,KAAMtC,EAAMsC,MAEnDtC,CACT,EACJ,CAEA,WAAmC9B,GACjC,IAAMqE,EAAO,IAAIC,QA4BjB,OA1BA,SAASC,EAAUzC,GACjB,GAAIA,GAA0B,iBAALA,EAAe,CAEtC,GAAIuC,EAAKX,IAAI5B,GACX,OAAO,KAIT,GAFAuC,EAAKG,IAAI1C,GAEL7B,MAAMC,QAAQ4B,GAChB,OAAYA,EAAC2C,IAAIF,GAGnB,IAAMG,EAAc,CAAE,EAEtB,IAAK,IAAS/B,KAASb,EACjB3B,OAAOwE,UAAUpE,eAAeF,KAAKyB,EAAOa,KAC9C+B,EAAO/B,GAAO4B,EAASzC,EAAMa,KAGjC,OACF+B,CAAA,CAGA,OAAO5C,CACT,CAEOyC,CAASvE,EAClB,kBCpMgB,SACd4E,EACAC,GAMA,IAEEtC,GACEsC,MAAAA,EAAAA,EAAW,CAAA,GADbtC,YAGIuC,EAAsBF,EACtBlE,EC/CQqE,SAA2BC,EAAiBC,QAAAA,IAAAA,IAAAA,GAAsB,GAChF,IAAIC,GAAa,IACY,GAEbC,EAAuB,GAC9BrD,EAAGkD,EA2CZ,MAAO,CACLI,SA1Ce,WAAStD,OAAAA,CAAK,EA2C7BqB,KAzCW,SAACP,GACZd,EAAQc,EAQRyC,EAAaC,KAAK1C,GAGbsC,IACHA,GAAa,UACAK,UAAUC,KAAK,WAC1BL,EAAaM,QAAQ,SAACC,GAAQA,EAAEvC,KAAKkC,EAAmB,GACxDA,EAAe,GACfH,GAAa,CACf,GAEJ,EAsBES,UApBgB,SAACC,GAMjB,OAJIX,GAAqBW,EAASzC,KAAKrB,GAEvCqD,EAAaG,KAAKM,GAEX,CACLC,YAAa,WACXV,EAAeA,EAAa9D,OAAO,SAAAqE,GAAC,OAAKA,IAAKE,CAAQ,EACxD,EAEJ,EAUEE,eARqB,WACrBX,EAAe,EACjB,EAQF,CDPkBJ,CAAgDD,GAE1DiB,EAAetF,EACnBC,EACAoE,EAEA,CAAEvC,YAAAA,IAIJ,MAAO,CACLyD,MAAOD,EACPE,MAAO,WACLF,EAAaxC,OFpCH2C,SAAelG,GAC7B,IAAMmG,EAAmB,GACnBC,EAAsB,GAEHC,EAAG,IAASC,IAErCD,EAAoB5D,IAAI8D,KAAM,SAACb,GAAyB,WAAaa,KAACb,EAAE,GACxEW,EAAoB5D,IAAI6D,IAAK,SAACZ,EAA2Cc,GAAO,WAAYF,IAACG,EAAWxG,MAAMyG,KAAKhB,GAAIc,GAAI,GAC3HH,EAAoB5D,IAAIkE,IAAK,SAACjB,EAA2Cc,GAAY,OAAA,QAAQC,EAAWxG,MAAMyG,KAAKhB,GAAIc,GAAI,GAE3H,MAAc,KAEd,OA6BA,SAASI,EAAOlB,GACd,GAAiB,iBAALA,GAAuB,OAANA,EAAY,OAAQA,EACjD,GAAIzF,MAAMC,QAAQwF,GAAI,SAAkBA,EAAGkB,GAC3C,GAAIlB,EAAEmB,cAAgB1G,SAAW2G,EAAUT,EAAoB7E,IAAIkE,EAAEmB,cACnE,OAAcC,EAACpB,EAAGkB,GAEpB,MAAW,CAAA,EAUX,IAAK,SARLT,EAAKb,KAAKI,GACVU,EAAQd,KAAKyB,GAGb5G,OAAO6G,sBAAsBtB,GAAGD,QAAQ,SAACwB,GACvCF,EAAGE,GAAWvB,EAAGuB,EACnB,GAEgBvB,EACd,GAAKvF,OAAOI,eAAeF,KAAKqF,EAAGwB,GAAnC,CACA,MAAYxB,EAAEwB,GAGd,GAAmB,oBAAoB,OAARC,EAC7BJ,EAAGG,GAAKC,OACH,GAAIA,EAAIN,cAAgB1G,SAAW2G,EAAUT,EAAoB7E,IAAI2F,EAAIN,cAC9EE,EAAGG,GAAKJ,EAAQK,EAAKP,OAGhB,CACL,IAAMQ,EAAIjB,EAAKkB,QAAQF,GAGrBJ,EAAGG,IADM,IAAPE,EACMhB,EAAQgB,GAERR,EAAMO,EAClB,CAhBA,CAsBF,OAJAhB,EAAKmB,MACLlB,EAAQkB,MAIVP,CAAA,CAtEOH,CAAM5G,GAEb,WAAqBuH,EAAQf,GAI3B,IAHA,IAAMgB,EAAOrH,OAAOqH,KAAKD,KACd,UAAUC,EAAKC,UAEb,EAAGL,EAAII,EAAKC,OAAQL,IAAK,CACpC,IAAOF,EAAGM,EAAKJ,KACHG,EAAEL,GAEd,GAAmB,oBAAoB,OAARC,EAC7BO,EAAGR,GAAKC,OACH,GAAIA,EAAIN,cAAgB1G,SAAW2G,EAAUT,EAAoB7E,IAAI2F,EAAIN,cAC9Ea,EAAGR,GAAKJ,EAAQK,EAAKX,OAGhB,CACL,IAAMmB,EAAQxB,EAAKkB,QAAQF,GAGzBO,EAAGR,IADU,IAAXS,EACMvB,EAAQuB,GAERnB,EAAGW,EACf,CACF,CAEA,OAAOO,CACT,CA4CF,CE/C4BxB,CAAUtB,EAClC,EACAgD,SAAU,SAAC/C,GAAW,IAAAgD,EACdjD,EAAeC,MAAAA,SAAAA,EAASD,kBAATC,EAAAA,EAASD,aAAemB,EAAaxC,QACnCuE,EAAGC,EAAMA,QAAC,IAE5BD,EAAkBE,SAAWpD,GAAgBA,IAAiBmB,IACjE+B,EAAkBE,SAAU,EAC3BjC,EAAqBxC,OAASqB,GAGjC,IAAsBqD,EAAGF,EAAAA,OAGJ,OAFlBF,EAA2B,mBAAb,MAAPhD,OAAO,EAAPA,EAASqD,QACN,MAAPrD,GAAAA,MAAAA,EAASqD,YAAF,EAAPrD,EAASqD,SACF,MAAPrD,OAAO,EAAPA,EAASqD,QAAML,EACd,IAGiCM,EAAGJ,EAAAA,OACzCE,EAAiBD,QACd3G,OAAO,SAAA+G,GAAMA,OAAAA,EAAGC,SAAS,KAAK,GAC9B5D,IAAI,SAAA2D,GAAMA,OAAAA,EAAG3E,QAAQ,KAAM,GAAG,IAkDnC,OA9CA6E,EAAeA,gBAAC,WACH,MAAPzD,GAAAA,EAAS0D,iBACN1D,EAAQ0D,gBAAgBxC,EAAaxC,QAAQiC,KAAK,SAAC1D,GACtDiE,EAAaxC,OAASzB,CACxB,GAAQ,MAAC,SAAC0G,GACRC,QAAQC,MAAM,uCAAwCF,EACxD,EAGJ,EAAG,IAGHG,EAAAA,qBACE,SAACC,GACC,IAAMC,EAAenI,EAAQiF,UAAU,CACrCxC,KAAM,SAAC2F,GACL,IAAkBC,EAAG9I,MAAMC,QAAQ4I,GAC/BA,EACA,CAACA,GAEL,GAAKjE,MAAAA,IAAAA,EAASqD,OAIZ,OAHAU,SACO,MAAP/D,GAAiB,MAAjBA,EAASmE,UAATnE,EAASmE,SAAWD,IAKlBA,EAAaE,KAAK,SAAAC,GAAU,MACE,WAArB7F,OAAOtC,WACfkH,EAAiBD,QAAQK,SAASa,EAAW7F,OAAOtC,YACpDoH,EAAmCH,QAAQmB,KAAK,SAAAf,GAAMc,OAAAA,EAAW7F,OAAOtC,UAAUqI,WAAWhB,EAAG,EAAC,KAEpGQ,IACO,MAAP/D,GAAiB,MAAjBA,EAASmE,UAATnE,EAASmE,SAAWD,GAExB,IAGF,OAAO,WACLF,EAAahD,aACf,CACF,EACA,WAAMnF,OAAAA,EAAQ0E,UAAU,EACxB,WAAM1E,OAAAA,EAAQ0E,UAAU,GAI5BW,CAAA,EAEJ,sBAjHgBsD,SAA6CzE,GAQ3D,OAPAzE,OAAOmJ,eAAe1E,EAAc9E,EAAyB,CAC3DgC,OAAO,EACPyH,YAAY,EACZC,UAAU,EACVC,cAAc,IAIlB7E,CAAA"}