{ "version": 3, "sources": ["globals:@olenbetong/appframe-core", "../../src/bundle-entries/browser.ts", "../../src/DataObject.ts", "../../src/DataHandler.ts", "../../src/Client.ts", "../../src/errors.ts", "../../../../node_modules/.pnpm/mitt@3.0.1/node_modules/mitt/src/index.ts", "../../src/events.ts", "../../src/utils/fieldTypes.ts", "../../src/utils/handleResponseError.ts", "../../src/utils/getFields.ts", "../../src/utils/isEqual.ts", "../../src/utils/requestTimeout.ts", "../../src/utils/index.ts", "../../src/FileUploader.ts", "../../src/Paging.ts", "../../src/RecordSource.ts", "../../src/Storage.ts", "../../src/utils/cloneDeep.ts", "../../src/Procedure.ts", "../../src/browser/Client.ts", "../../src/generateApiDataObject.ts", "../../src/bundle-entries/browser.esm.ts"], "sourcesContent": ["module.exports = af.common", "// This file is the entry point for browser bundles\nimport { DataObject } from \"../DataObject.js\";\nimport { Procedure, ProcedureAPI } from \"../Procedure.js\";\n\nexport * from \"./browser.esm\";\n\nglobalThis.af = globalThis.af ?? {};\nglobalThis.af = globalThis.af ?? {};\nglobalThis.af.DataObject = DataObject;\nglobalThis.af.Procedure = Procedure;\nglobalThis.af.ProcedureAPI = ProcedureAPI;\n", "import { getLocalizedString, invariant, logError } from \"@olenbetong/appframe-core\";\n\nimport {\n\tDataHandler,\n\tDataHandlerDescriptor,\n\tDataProviderHandler,\n\tPagedRetrieveParameters,\n\tPagedRetrieveResponse,\n\tRequestError,\n\tRetrieveParameters,\n\tRetrieveResponse,\n} from \"./DataHandler.js\";\nimport { FileUploader } from \"./FileUploader.js\";\nimport { Paging } from \"./Paging.js\";\nimport { RecordSource } from \"./RecordSource.js\";\nimport { MemoryStorage, Storage, StorageArray, StorageRecord, uid } from \"./Storage.js\";\nimport * as errors from \"./errors.js\";\nimport { DataObjectEventToValueMap, DataObjectEvents, EventTarget } from \"./events.js\";\nimport { FieldDefinition } from \"./fields.js\";\nimport clone from \"./utils/cloneDeep.js\";\nimport { fieldTypes, guessType, isEqual } from \"./utils/index.js\";\n\nexport type RefreshDataSourceOptions = {\n\tparameters?: Partial>;\n\tthrow?: boolean;\n};\n\ntype SavingState = {\n\tactiveCalls: number;\n\tcurrentPromise: Promise | null;\n};\n\nfunction objHasKeys(object: any) {\n\treturn Object.keys(object).length > 0;\n}\n\nexport type CurrentRow> = StorageRecord;\nexport type DataRecord> = T & { [uid]: string | number };\n\nexport type DataObjectOptions> = {\n\tallowDelete?: boolean;\n\tallowInsert?: boolean;\n\tallowUpdate?: boolean;\n\tarticleId?: string;\n\tdataHandler?: DataHandler | DataHandlerDescriptor;\n\tdataSourceId: string;\n\tdisableAutoload?: boolean;\n\tdynamicLoading?: boolean;\n\tfields: FieldDefinition[];\n\tgroupBy?: keyof T | null | string[];\n\thasIDTrig?: boolean;\n\thasIITrig?: boolean;\n\thasIUTrig?: boolean;\n\tlinkFields?: Array | Partial> | null;\n\tmasterDataObject?: AfDataObject | null;\n\toptimisticLocking?: boolean;\n\tparameters?: RetrieveParameters;\n\tselectFirstRow?: boolean;\n\tsystemFieldNames?: Record;\n\ttimeout?: number;\n\tuniqueIdField?: keyof T;\n};\n\n/**\n * This interface should be used to check compatability with the Omega DataObject\n * implementation. If we make changes to this interface, it should most likely be\n * listed as a breaking change in the README file.\n */\nexport interface AfDataObject> extends EventTarget> {\n\tareParametersChanged: () => boolean;\n\tareRecordsSaving: () => boolean;\n\tbeforeReload: () => Promise;\n\tcancelEdit: () => boolean;\n\tcancelField: (field: keyof T) => boolean;\n\tcanModifyCurrentRow: () => boolean;\n\tcanModifyRow: (index: number) => boolean;\n\tclearFilter: () => void;\n\tcurrentRow(): CurrentRow;\n\tcurrentRow(field: F): T[F] | null;\n\tcurrentRow(field: F, value: T[F]): boolean;\n\tdataLastLoaded: () => Date;\n\tdeleteCurrentRow: () => Promise;\n\tdeleteRow: (index: number) => Promise;\n\tendEdit: () => Promise;\n\tgetCurrentIndex: () => number;\n\tgetData(): DataRecord[];\n\tgetData(index: number): DataRecord;\n\tgetData(index: number, field: F): T[F];\n\tgetDataLength: () => number;\n\tgetDataSourceId: () => string;\n\tgetFields(): FieldDefinition[];\n\tgetFields(field: string): FieldDefinition | undefined;\n\tgetFields(field: keyof T): FieldDefinition;\n\tgetLinkFields: () => Partial> | Array | null;\n\tgetMasterDataObject: () => AfDataObject | null;\n\tgetParameter

>(name: P): RetrieveParameters[P];\n\tgetUniqueIdField: () => keyof T;\n\thasField: (field: string) => boolean;\n\tisAutoLoadDisabled: () => boolean;\n\tisDataLoaded: () => boolean;\n\tisDataLoading: () => boolean;\n\tisDeleteAllowed: () => boolean;\n\tisDeleteNeverAllowed: () => boolean;\n\tisDirty: (indexOfFieldName?: number | string) => boolean;\n\tisDynamicLoading: () => boolean;\n\tisInsertAllowed: () => boolean;\n\tisInsertNeverAllowed: () => boolean;\n\tisNewRecord: (index: number) => boolean;\n\tisNullable: (field: string) => boolean;\n\tisSaving: (index?: number) => boolean;\n\tisUpdateAllowed: () => boolean;\n\tisUpdateNeverAllowed: () => boolean;\n\toriginalRow(): T;\n\toriginalRow(field: F): T[F];\n\trefreshCurrentRow: () => Promise;\n\trefreshDataSource: () => Promise;\n\trefreshRow: (index: number) => Promise;\n\tremoveRow: (index: number) => void;\n\tretrievePartial: (skip: number, maxRecords: number) => void;\n\tsave: (data: Partial) => void;\n\tsetAllowDelete: (allow: boolean) => void;\n\tsetAllowUpdate: (allow: boolean) => void;\n\tsetAllowInsert: (allow: boolean) => void;\n\tsetCurrentIndex(index: number): boolean;\n\tsetCurrentIndex(index: number, waitForSave: true): Promise;\n\tsetCurrentIndex(index: number, waitForSave: false): boolean;\n\tsetParameter

>(name: P, value: RetrieveParameters[P]): void;\n}\n\ntype PartialWithUid = Partial & { [uid]: string | number };\n\n/**\n * Data object capable of handling data from different sources.\n */\nexport class DataObject = {}>\n\textends EventTarget>\n\timplements AfDataObject\n{\n\treadonly version = globalThis.__VERSION__;\n\treadonly dataHandler: DataHandler;\n\treadonly masterDataObject: AfDataObject | null;\n\treadonly options: Required>;\n\treadonly recordSource: RecordSource;\n\treadonly storageEngine: Storage;\n\tget fields(): FieldDefinition[] {\n\t\treturn this.options.fields;\n\t}\n\tprotected pagingComponent: Paging | undefined;\n\n\tprotected currentIndex: number;\n\tprotected dataLoaded: number | null;\n\tprotected dataLoading: boolean;\n\tprotected dataSaving: boolean;\n\tprotected dirtyRecords: Record>;\n\tprotected errorRecords: Record;\n\tprotected fieldNames: Array;\n\tprotected newRecord: PartialWithUid;\n\tprotected parametersChanged: boolean;\n\tprotected savingRecords: Record;\n\tprotected temporarilyDisallowDelete: boolean;\n\tprotected temporarilyDisallowInsert: boolean;\n\tprotected temporarilyDisallowUpdate: boolean;\n\n\tconstructor(options: DataObjectOptions) {\n\t\tsuper(DataObjectEvents);\n\t\tlet defaults = this.getDefaultOptions();\n\t\tthis.options = {\n\t\t\t...defaults,\n\t\t\t...options,\n\t\t\tparameters: Object.assign({}, clone(defaults.parameters), clone(options.parameters)),\n\t\t} as Required>;\n\n\t\tthis.currentRow = this.currentRow.bind(this);\n\t\tthis.getData = this.getData.bind(this);\n\t\tthis.getDirtyRecord = this.getDirtyRecord.bind(this);\n\t\tthis.getFields = this.getFields.bind(this);\n\t\tthis.getParameter = this.getParameter.bind(this);\n\t\tthis.getSavedField = this.getSavedField.bind(this);\n\t\tthis.originalRow = this.originalRow.bind(this);\n\t\tthis.setCurrentIndex = this.setCurrentIndex.bind(this);\n\t\tthis.setField = this.setField.bind(this);\n\t\tthis.setParameter = this.setParameter.bind(this);\n\t\tthis.storageRetrieve = this.storageRetrieve.bind(this);\n\n\t\tthis.storageEngine = new MemoryStorage(this.fields);\n\t\tthis.currentIndex = -1;\n\t\tthis.dataLoaded = null;\n\t\tthis.dataLoading = false;\n\t\tthis.dataSaving = false;\n\t\tthis.dirtyRecords = {};\n\t\tthis.errorRecords = {};\n\t\tthis.fieldNames = this.options.fields.map((field) => field.name as keyof T);\n\t\tthis.newRecord = { [uid]: this.storageEngine.getNewUid() } as PartialWithUid;\n\t\tthis.parametersChanged = false;\n\t\tthis.savingRecords = {};\n\t\tthis.temporarilyDisallowDelete = false;\n\t\tthis.temporarilyDisallowUpdate = false;\n\t\tthis.temporarilyDisallowInsert = false;\n\n\t\tthis.recordSource = new RecordSource(this); // convenience functions for parameters\n\n\t\tthis.dataHandler = this.handleDataHandlerOption(this.options);\n\t\tthis.masterDataObject = this.handleMasterDataObjectOption();\n\t}\n\n\tareParametersChanged = (): boolean => this.parametersChanged;\n\tareRecordsSaving = (): boolean => objHasKeys(this.savingRecords);\n\n\tasync beforeReload() {\n\t\treturn true;\n\t}\n\n\tdataLastLoaded = (): Date => new Date(this.dataLoaded || 0);\n\tgetCurrentIndex = (): number => this.currentIndex;\n\tgetDataLength = (): number => this.storageLength();\n\n\t/**\n\t * Get what is set as the maximum rows to dataObject.\n\t */\n\tgetMaxRecords = (): number => this.options.parameters.maxRecords || -1;\n\n\tgetPagingComponent = (): Paging => {\n\t\tif (!this.pagingComponent) {\n\t\t\tthis.pagingComponent = new Paging({ dataObject: this });\n\t\t}\n\n\t\treturn this.pagingComponent;\n\t};\n\n\thasDirtyRecords = (): boolean => objHasKeys(this.dirtyRecords);\n\n\thasError = (index: number): boolean => {\n\t\tif (this.errorRecords[index]) {\n\t\t\treturn this.errorRecords[index];\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t};\n\n\tisDataLoaded = (): boolean => this.dataLoaded !== null;\n\tisDataLoading = (): boolean => this.dataLoading;\n\tisDynamicLoading = (): boolean => this.options.dynamicLoading;\n\n\t/**\n\t * Check if a record is a new record (ID field is null)\n\t * @param index Index of the record to check\n\t * @returns {boolean}\n\t */\n\tisNewRecord = (index: number): boolean => {\n\t\tif (typeof index === \"number\" && index % 1 === 0) {\n\t\t\tif (index === -1) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tif (this.fieldNames.indexOf(this.options.uniqueIdField) === -1) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\treturn this.getSavedField(index, this.options.uniqueIdField) === null;\n\t\t}\n\n\t\treturn false;\n\t};\n\n\tgetFileStoreURL(record: Record, type?: \"download\" | \"view\"): string;\n\tgetFileStoreURL(primKey: string, fileName: string, type?: \"download\" | \"view\"): string;\n\tgetFileStoreURL(\n\t\tprimKeyOrRecord: string | Record,\n\t\tfileNameOrType?: string | \"download\" | \"view\",\n\t\ttype: \"download\" | \"view\" = \"view\",\n\t): string {\n\t\tif (typeof primKeyOrRecord === \"object\") {\n\t\t\tif (Object.hasOwn(primKeyOrRecord, \"PrimKey\") && Object.hasOwn(primKeyOrRecord, \"FileName\")) {\n\t\t\t\treturn this.dataHandler.getFileStoreURL(\n\t\t\t\t\tprimKeyOrRecord[\"PrimKey\"] as string,\n\t\t\t\t\tprimKeyOrRecord[\"FileName\"],\n\t\t\t\t\tfileNameOrType as \"download\" | \"view\" | undefined,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn \"\";\n\t\t}\n\t\treturn this.dataHandler.getFileStoreURL(primKeyOrRecord, fileNameOrType ?? \"file\", type);\n\t}\n\n\tgetBlobURL(record: Record, field: string, type?: \"download\" | \"view\"): string;\n\tgetBlobURL(primKey: string, field: string, fileName: string, type?: \"download\" | \"view\"): string;\n\tgetBlobURL(\n\t\tprimKeyOrRecord: Record | string,\n\t\tfield: string,\n\t\tfileNameOrType?: string | \"download\" | \"view\",\n\t\ttype: \"download\" | \"view\" = \"view\",\n\t) {\n\t\tif (typeof primKeyOrRecord === \"object\") {\n\t\t\tif (Object.hasOwn(primKeyOrRecord, \"PrimKey\") && Object.hasOwn(primKeyOrRecord, \"FileName\")) {\n\t\t\t\treturn this.dataHandler.getBlobURL(\n\t\t\t\t\tprimKeyOrRecord[\"PrimKey\"] as string,\n\t\t\t\t\tfield,\n\t\t\t\t\tprimKeyOrRecord[\"FileName\"],\n\t\t\t\t\tfileNameOrType as \"download\" | \"view\" | undefined,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn \"\";\n\t\t}\n\n\t\treturn this.dataHandler.getBlobURL(primKeyOrRecord, field, fileNameOrType ?? \"file\", type);\n\t}\n\n\tprotected storageCreate = (data?: T | null, uid?: string | number): number => this.storageEngine.create(data, uid);\n\n\tprotected storageRetrieve(): StorageArray;\n\tprotected storageRetrieve(index: number): StorageRecord;\n\tprotected storageRetrieve(index: number, field: F): T[F] | null;\n\tprotected storageRetrieve(\n\t\tindex?: number,\n\t\tfield?: F,\n\t): StorageArray | StorageRecord | T[F] | null {\n\t\tif (typeof index !== \"number\") {\n\t\t\treturn this.storageEngine.retrieve();\n\t\t} else if (!field) {\n\t\t\treturn index === -1 ? this.storageEngine.newRow(this.newRecord[uid]) : this.storageEngine.retrieve(index);\n\t\t} else {\n\t\t\treturn index === -1 ? null : this.storageEngine.retrieve(index, field);\n\t\t}\n\t}\n\n\tprotected storageUpdate = (index: number, data: T): boolean => this.storageEngine.update(index, data);\n\tprotected storageDestroy = (index?: number): boolean => this.storageEngine.destroy(index);\n\tprotected storageLength = (): number => this.storageEngine.length;\n\n\tcancelEdit = (): boolean => {\n\t\tconst wasDirty = this.isDirty();\n\t\tthis.makeClean(this.currentIndex);\n\n\t\tif (wasDirty) {\n\t\t\tthis.fireEvent(\"onCancelEdit\", this.currentIndex);\n\t\t}\n\n\t\treturn wasDirty;\n\t};\n\n\tprivate canSetFieldValueToNull = (field: FieldDefinition, skipInsteadOfTriggerChecks = false): boolean => {\n\t\tif (!skipInsteadOfTriggerChecks) {\n\t\t\tif (this.isNewRecord(this.currentIndex)) {\n\t\t\t\tif (this.options.hasIITrig) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (this.options.hasIUTrig) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn (field.nullable || field.computed) ?? false;\n\t};\n\n\tclearFilter = (): void => {\n\t\tthis.setParameters({ filterObject: null, filterString: \"\" });\n\t\tthis.fireEvent(\"onClearFilter\");\n\t};\n\n\t/**\n\t * Returns the row at the current index\n\t *\n\t * @returns {CurrentRow} Record\n\t */\n\tcurrentRow(): CurrentRow;\n\t/**\n\t * Returns the value of a field in the record at the current index\n\t * @param {F} field\n\t * @returns {T[F]}\n\t */\n\tcurrentRow(field: F): T[F] | null;\n\t/**\n\t * Sets the value of a field in the record at the current index\n\t * @param {F} field Field whose value should change\n\t * @param {T[F]} value Value to set on the field\n\t * @returns {boolean} true if successful\n\t */\n\tcurrentRow(field: F, value: T[F]): boolean;\n\tcurrentRow(field?: keyof T, value?: T[keyof T]): CurrentRow | T[keyof T] | boolean | null {\n\t\tif (field === undefined && value === undefined) {\n\t\t\treturn clone(this.getDirtyRecord());\n\t\t} else if (field && value === undefined) {\n\t\t\treturn clone(this.getDirtyRecord(field));\n\t\t} else if (field && value !== undefined) {\n\t\t\tconst { dataSourceId } = this.options;\n\n\t\t\tif (this.isNewRecord(this.currentIndex)) {\n\t\t\t\tinvariant(\n\t\t\t\t\tthis.isInsertAllowed(),\n\t\t\t\t\t`Inserting is${this.isInsertNeverAllowed() ? \"\" : \" currently\"} not allowed on ${dataSourceId}`,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tinvariant(\n\t\t\t\t\tthis.isUpdateAllowed(),\n\t\t\t\t\t`Updating is${this.isUpdateNeverAllowed() ? \"\" : \" currently\"} not allowed on ${dataSourceId}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst returnValue = this.setField(field, value);\n\n\t\t\treturn returnValue;\n\t\t}\n\n\t\treturn null;\n\t}\n\n\tprivate isValidData = (data: any): data is RetrieveResponse => {\n\t\tif (Array.isArray(data)) {\n\t\t\treturn true;\n\t\t} else if (typeof data === \"object\") {\n\t\t\treturn typeof data.skip === \"number\" && (Array.isArray(data.data) || typeof data.total === \"number\");\n\t\t}\n\n\t\treturn false;\n\t};\n\n\tprivate handleRetrieveDataError = (ex: any): void => {\n\t\ttry {\n\t\t\tglobalThis.onerror?.(ex.message, ex.fileName, ex.lineNumber, ex.columnNumber, ex);\n\t\t} catch (ex2) {\n\t\t\t/* ignoring failures to report error */\n\t\t}\n\n\t\tconst isIncorrectTypeError = new RegExp(errors.incorrectTypeOfField(this.getDataObjectIdentity(), '[^\"]+')).test(\n\t\t\tex.message,\n\t\t);\n\n\t\tif (isIncorrectTypeError) {\n\t\t\tex.message = `Failed to parse record received from server. This is most likely because the record definition was changed. Try to reload the page to see if the problem is fixed.`;\n\t\t}\n\n\t\tthis.fireEvent(\"onDataLoadFailed\", ex.message);\n\t};\n\n\tprivate startRequest = (): { revert: () => any } => {\n\t\tlet parametersWasChanged = this.parametersChanged;\n\t\tthis.parametersChanged = false;\n\n\t\treturn {\n\t\t\trevert: () => {\n\t\t\t\tthis.parametersChanged = parametersWasChanged;\n\t\t\t},\n\t\t};\n\t};\n\n\tprivate previousRetrieveRequest: AbortController | null = null;\n\tprivate dataHandlerRetrieve = async (params: RetrieveParameters | PagedRetrieveParameters): Promise => {\n\t\tconst { revert } = this.startRequest();\n\t\tconst eventResult = this.fireEvent(\"onBeforeLoad\", params);\n\n\t\tif (eventResult === false) {\n\t\t\t// NOTE: Not the best solution - would be better to have an event that fires\n\t\t\t// after onBeforeUnload that could be used for working indicators and such\n\t\t\tthis.fireEvent(\"onDataLoadFailed\", null);\n\t\t\trevert();\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.dataSaving) {\n\t\t\tconst savingStatuses = Object.values(this.savingRecords);\n\n\t\t\tawait Promise.all(savingStatuses.filter((s) => s.currentPromise !== null).map((s) => s.currentPromise));\n\t\t}\n\n\t\tlet shouldSetDataLoading = true;\n\t\ttry {\n\t\t\tconst controller = new AbortController();\n\n\t\t\tif (this.previousRetrieveRequest !== null) {\n\t\t\t\tthis.previousRetrieveRequest.abort();\n\t\t\t}\n\t\t\tthis.previousRetrieveRequest = controller;\n\n\t\t\tthis.dataLoading = true;\n\t\t\tthis.fireEvent(\"onDataLoading\", null);\n\n\t\t\tlet result = await this.dataHandler.retrieve({ ...params, returnTotal: false }, { signal: controller.signal });\n\n\t\t\tif (this.previousRetrieveRequest === controller) {\n\t\t\t\tthis.previousRetrieveRequest = null;\n\t\t\t} else {\n\t\t\t\tshouldSetDataLoading = false;\n\t\t\t}\n\n\t\t\tif (shouldSetDataLoading) {\n\t\t\t\tthis.dataLoading = false;\n\t\t\t}\n\n\t\t\tif (!controller.signal.aborted) {\n\t\t\t\tinvariant(\n\t\t\t\t\tthis.isValidData(result),\n\t\t\t\t\t`Invalid data from server. Expected array or paging object, got ${typeof result}`,\n\t\t\t\t);\n\n\t\t\t\ttry {\n\t\t\t\t\tthis.handleRetrieveData(result);\n\n\t\t\t\t\tif (!Array.isArray(result) && typeof (result as PagedRetrieveResponse).skip === \"number\") {\n\t\t\t\t\t\tthis.dataHandlerRetrieveCounter(params as PagedRetrieveParameters, result);\n\t\t\t\t\t}\n\t\t\t\t} catch (ex: any) {\n\t\t\t\t\tthis.handleRetrieveDataError(ex);\n\n\t\t\t\t\tthrow new Error(ex.message);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn;\n\t\t} catch (ex: any) {\n\t\t\tif (shouldSetDataLoading) {\n\t\t\t\tthis.dataLoading = false;\n\t\t\t}\n\t\t\tif (ex.name === \"AbortError\") {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\trevert();\n\n\t\t\tif (process.env.NODE_ENV !== \"test\") {\n\t\t\t\tconsole.error(ex);\n\t\t\t\tlogError(ex);\n\t\t\t}\n\n\t\t\t// This should only happen on network failures (offline, navigate, cors etc)\n\t\t\t// Should not throw an error, since this can cause an alert to pop up if the\n\t\t\t// user navigates away while a request is pending.\n\t\t\tthis.fireEvent(\"onDataLoadFailed\", ex.message);\n\t\t}\n\t};\n\n\tprivate previousRowCountRequest: AbortController | null = null;\n\tdataHandlerRetrieveCounter = async (\n\t\tparams: PagedRetrieveParameters,\n\t\tresponse: PagedRetrieveResponse,\n\t): Promise => {\n\t\tif (this.dataSaving) {\n\t\t\t// Delay loading until after save is complete\n\t\t\tawait Promise.all(\n\t\t\t\tObject.values(this.savingRecords)\n\t\t\t\t\t.filter((record) => record.currentPromise !== null)\n\t\t\t\t\t.map((record) => record.currentPromise),\n\t\t\t);\n\t\t}\n\n\t\ttry {\n\t\t\tconst controller = new AbortController();\n\n\t\t\tif (this.previousRowCountRequest !== null) {\n\t\t\t\tthis.previousRowCountRequest.abort();\n\t\t\t}\n\t\t\tthis.previousRowCountRequest = controller;\n\n\t\t\tconst result = (await this.dataHandler.rowcount(params, { signal: controller.signal })) as\n\t\t\t\t| RequestError\n\t\t\t\t| PagedRetrieveResponse;\n\n\t\t\tif (this.previousRowCountRequest === controller) {\n\t\t\t\tthis.previousRowCountRequest = null;\n\t\t\t}\n\n\t\t\tif (controller.signal.aborted) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tinvariant(this.isValidData(result), \"The data retrieved by the DataObject was not an Array\");\n\t\t\ttry {\n\t\t\t\tlet dataLength = this.getDataLength();\n\t\t\t\tif (result.total > dataLength) {\n\t\t\t\t\tthis.storageEngine.length = result.total;\n\t\t\t\t}\n\n\t\t\t\tthis.dataLoaded = Date.now();\n\t\t\t\tthis.fireEvent(\"onRowCountLoaded\", {\n\t\t\t\t\tskip: result.skip,\n\t\t\t\t\tcount: response.data.length,\n\t\t\t\t\ttotal: result.total,\n\t\t\t\t});\n\t\t\t} catch (ex: any) {\n\t\t\t\tthis.handleRetrieveDataError(ex);\n\n\t\t\t\tthrow new Error(ex.message);\n\t\t\t}\n\t\t} catch (ex: any) {\n\t\t\tif (ex.name === \"AbortError\") {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// This should only happen on network failures (offline, navigate, cors etc)\n\t\t\t// Should not throw an error, since this can cause an alert to pop up if the\n\t\t\t// user navigates away while a request is pending.\n\t\t\tthis.fireEvent(\"onDataLoadFailed\", ex.message);\n\n\t\t\treturn;\n\t\t}\n\n\t\treturn;\n\t};\n\n\tprivate getDefaultOptions = (): Partial> => {\n\t\tconst { af } = globalThis;\n\n\t\treturn {\n\t\t\tarticleId: af?.article?.id,\n\t\t\ttimeout: 0,\n\t\t\tlinkFields: null,\n\t\t\tdisableAutoload: false,\n\t\t\tdynamicLoading: false,\n\t\t\tallowDelete: false,\n\t\t\tallowUpdate: false,\n\t\t\tallowInsert: false,\n\t\t\tselectFirstRow: true,\n\t\t\toptimisticLocking: false,\n\t\t\thasIITrig: false,\n\t\t\thasIUTrig: false,\n\t\t\thasIDTrig: false,\n\t\t\tparameters: {\n\t\t\t\tfilterString: \"\",\n\t\t\t\twhereClause: \"\",\n\t\t\t\tfilterObject: null,\n\t\t\t\twhereObject: null,\n\t\t\t\tsortOrder: [],\n\t\t\t\tmaxRecords: 50,\n\t\t\t\tdistinctRows: false,\n\t\t\t\tmasterChildCriteria: {},\n\t\t\t},\n\t\t\tsystemFieldNames: {},\n\t\t\tmasterDataObject: null,\n\t\t\tgroupBy: null,\n\t\t\tuniqueIdField: \"PrimKey\" as keyof T,\n\t\t\tfields: [],\n\t\t};\n\t};\n\n\t/**\n\t * Delete the currently selected current row.\n\t *\n\t * @param {Callback} callback\n\t * @returns {false | Promise}\n\t */\n\tdeleteCurrentRow = (): Promise => this.deleteRow(this.currentIndex);\n\n\tdeleteRow = async (index: number): Promise => {\n\t\tinvariant(!this.isDeleteNeverAllowed(), \"Deleting is not allowed on this DataObject\");\n\t\tinvariant(this.isDeleteAllowed(), \"Deleting is currently not allowed on this DataObject\");\n\n\t\tconst eventResult = this.fireEvent(\"onRecordDeleting\", index);\n\t\tconst { uniqueIdField } = this.options;\n\n\t\tif (eventResult === false) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst uniqueId = this.storageRetrieve(index, uniqueIdField);\n\n\t\tif (uniqueId === null) {\n\t\t\tthis.removeRow(index);\n\n\t\t\treturn index;\n\t\t} else {\n\t\t\tconst destroyParams: Partial = {};\n\t\t\tdestroyParams[uniqueIdField] = uniqueId as T[keyof T];\n\n\t\t\tif (await this.dataHandler.destroy(destroyParams)) {\n\t\t\t\tconst records = this.storageRetrieve();\n\n\t\t\t\tfor (let i = 0; i < records.length; i++) {\n\t\t\t\t\tlet row = records[i];\n\t\t\t\t\tif (isEqual(row[uniqueIdField], uniqueId)) {\n\t\t\t\t\t\tthis.removeRow(i);\n\n\t\t\t\t\t\treturn i;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t};\n\n\t/**\n\t * Creates a new record for the data object without adding it to storage.\n\t * Can be added later using 'addRow'. Used to get a row with a unique ID\n\t * that will be persisted after saving.\n\t *\n\t * @param data\n\t * @returns\n\t */\n\tnewRow = (data?: Partial): Partial & { [uid]: string | number } =>\n\t\t({\n\t\t\t[uid]: this.storageEngine.getNewUid(),\n\t\t\t...data,\n\t\t}) as Partial & { [uid]: string | number };\n\n\t/**\n\t *\n\t * @param row\n\t * @returns\n\t */\n\taddRow = async (row: Partial & { [uid]?: number | string }): Promise | null> => {\n\t\tinvariant(\n\t\t\tthis.isInsertAllowed(),\n\t\t\t`Inserting is${this.isInsertNeverAllowed() ? \"\" : \" currently\"} not allowed on ${this.getDataSourceId()}`,\n\t\t);\n\n\t\tlet id = row[uid];\n\t\tlet newRow = {\n\t\t\t...this.options.parameters.masterChildCriteria,\n\t\t\t...row,\n\t\t};\n\t\tlet eventResult = this.fireEvent(\"onBeforeSave\", newRow);\n\n\t\tif (eventResult === false) {\n\t\t\treturn null;\n\t\t}\n\n\t\tlet record = await this.dataHandler.create(newRow);\n\n\t\tif (record) {\n\t\t\tlet index = this.storageEngine.create(record, id);\n\t\t\tthis.fireEvent(\"onRecordCreated\", index);\n\t\t\tthis.fireEvent(\"onAfterSave\", index);\n\t\t\treturn this.getData(index);\n\t\t}\n\n\t\treturn record;\n\t};\n\n\tendEdit = async (): Promise => {\n\t\tif (!this.isDirty()) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif (this.options.masterDataObject !== null && this.options.masterDataObject.isDirty()) {\n\t\t\tawait this.options.masterDataObject.endEdit();\n\t\t}\n\n\t\tlet index = this.currentIndex;\n\t\tif (index !== -1 && Object.hasOwn(this.savingRecords, index)) {\n\t\t\tif (this.savingRecords[index].activeCalls) {\n\t\t\t\tawait this.savingRecords[index].currentPromise;\n\t\t\t\treturn this.endEdit();\n\t\t\t}\n\t\t}\n\n\t\tlet startTimestamp = Date.now();\n\t\tlet idField = this.options.uniqueIdField;\n\t\tlet hasIdField = this.fieldNames.indexOf(idField) >= 0;\n\t\tlet id = index === -1 ? null : this.getSavedField(index, idField);\n\t\tlet dirtyRecord: PartialWithUid | Partial;\n\t\tlet record: Partial;\n\t\tlet dataHandlerFunc: \"create\" | \"update\";\n\n\t\tif (id === null) {\n\t\t\tdirtyRecord = index === -1 ? this.newRecord : this.dirtyRecords[index];\n\t\t\trecord = Object.assign({}, dirtyRecord, this.options.parameters.masterChildCriteria);\n\t\t\tdataHandlerFunc = \"create\";\n\t\t} else {\n\t\t\tdirtyRecord = this.dirtyRecords[index];\n\t\t\trecord = Object.assign({}, dirtyRecord);\n\t\t\tlet savedId = this.getSavedField(index, idField);\n\t\t\tif (savedId !== null) {\n\t\t\t\trecord[idField] = savedId;\n\t\t\t}\n\n\t\t\tdataHandlerFunc = \"update\";\n\t\t}\n\n\t\tlet eventResult = this.fireEvent(\"onBeforeSave\", record);\n\t\tlet updatedFieldName = this.options.systemFieldNames[\"updated\"] || (\"Updated\" as keyof T);\n\n\t\tif (this.options.optimisticLocking === true && this.fieldNames.indexOf(updatedFieldName) !== -1 && index !== -1) {\n\t\t\trecord[updatedFieldName] = this.currentRow(updatedFieldName) as T[keyof T];\n\t\t}\n\n\t\tif (eventResult === false) {\n\t\t\treturn false;\n\t\t}\n\n\t\tthis.fireEvent(\"onSaving\");\n\n\t\tlet validationResult = this.validateSavingData(record);\n\t\tif (validationResult) {\n\t\t\tthis.fireEvent(\"onSaveFailed\", index);\n\t\t\tthrow new Error(validationResult);\n\t\t}\n\n\t\tlet normalRecord = Object.assign({}, dirtyRecord);\n\n\t\t// Remove any field if its definition says to ignore it\n\t\tthis.fields.forEach((field) => {\n\t\t\tif (field.ignored) {\n\t\t\t\tif (field.name !== this.options.uniqueIdField && Object.hasOwn(record, field.name)) {\n\t\t\t\t\tdelete record[field.name as keyof T];\n\t\t\t\t}\n\n\t\t\t\tif (Object.hasOwn(normalRecord, field.name)) {\n\t\t\t\t\tdelete normalRecord[field.name as keyof T];\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tif (Object.keys(normalRecord).length > 0) {\n\t\t\tlet newIndex: number | null;\n\t\t\tif (index === -1) {\n\t\t\t\tnewIndex = this.storageCreate(null, this.newRecord[uid]);\n\t\t\t\tdelete this.dirtyRecords[newIndex]; // Temporarily mark the record as clean until save is complete\n\t\t\t\tthis.currentIndex = newIndex;\n\t\t\t\tthis.fireEvent(\"onRecordCreated\", newIndex);\n\t\t\t\tthis.makeClean(-1);\n\t\t\t} else {\n\t\t\t\tnewIndex = index;\n\t\t\t\tdelete this.dirtyRecords[index]; // Set the dirty status of the record to not-dirty while saving\n\t\t\t}\n\n\t\t\tlet savingState: SavingState;\n\t\t\tif (!Object.hasOwn(this.savingRecords, newIndex)) {\n\t\t\t\tsavingState = {\n\t\t\t\t\tactiveCalls: 1,\n\t\t\t\t\tcurrentPromise: null,\n\t\t\t\t};\n\t\t\t\tthis.savingRecords[index] = savingState;\n\t\t\t} else {\n\t\t\t\tsavingState = this.savingRecords[index];\n\t\t\t\tsavingState.activeCalls++;\n\t\t\t}\n\n\t\t\tthis.dataSaving = true;\n\t\t\tsavingState.currentPromise = this.dataHandler[dataHandlerFunc](record, undefined);\n\n\t\t\tlet processSavingState = () => {\n\t\t\t\tif (newIndex !== null) {\n\t\t\t\t\tdelete this.savingRecords[newIndex];\n\t\t\t\t}\n\n\t\t\t\tif (Object.keys(this.savingRecords).length === 0) {\n\t\t\t\t\tthis.dataSaving = false;\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tlet result: T | null;\n\t\t\ttry {\n\t\t\t\tresult = await savingState.currentPromise;\n\n\t\t\t\t// If data was reloaded after endEdit was called and completed before this callback\n\t\t\t\t// we need to look for a row having the same PrimKey/UniqueKey, and abort if not found\n\t\t\t\tif (startTimestamp < (this.dataLoaded ?? 0)) {\n\t\t\t\t\tif (id === null) {\n\t\t\t\t\t\t// If row did not have a unqiue id\n\t\t\t\t\t\t// we cannot test if the record is the same\n\t\t\t\t\t\t// so we set index to null\n\t\t\t\t\t\tnewIndex = null;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (newIndex >= this.getDataLength() || (hasIdField && this.storageRetrieve(newIndex, idField) !== id)) {\n\t\t\t\t\t\t\tnewIndex = this.getIndexFromUniqueId(id);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (newIndex !== null) {\n\t\t\t\t\t// If we have the index of the saved record\n\t\t\t\t\tdelete this.errorRecords[index];\n\n\t\t\t\t\tif (result !== null) {\n\t\t\t\t\t\tthis.storageUpdate(newIndex, result);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconsole.warn(\"Statement did not return any values, nothing was updated\");\n\t\t\t\t\t}\n\n\t\t\t\t\tlet data = this.storageRetrieve(newIndex) as T;\n\n\t\t\t\t\tif (!this.isDirty(newIndex)) {\n\t\t\t\t\t\tthis.makeClean(newIndex, true);\n\t\t\t\t\t}\n\n\t\t\t\t\tprocessSavingState();\n\t\t\t\t\tthis.fireEvent(\"onAfterSave\", newIndex);\n\n\t\t\t\t\treturn data;\n\t\t\t\t} else {\n\t\t\t\t\tdelete this.errorRecords[index];\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tif (newIndex !== null && !this.isDirty(newIndex)) {\n\t\t\t\t\tthis.dirtyRecords[newIndex] = dirtyRecord;\n\t\t\t\t}\n\n\t\t\t\tif (newIndex !== null) {\n\t\t\t\t\tif (hasIdField && this.storageRetrieve(newIndex, idField) !== id) {\n\t\t\t\t\t\tnewIndex = this.getIndexFromUniqueId(id as T[keyof T]);\n\t\t\t\t\t}\n\t\t\t\t\tif (newIndex) {\n\t\t\t\t\t\tthis.dirtyRecords[newIndex] = dirtyRecord;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tprocessSavingState();\n\n\t\t\t\tif (newIndex != null) {\n\t\t\t\t\tthis.errorRecords[newIndex] = true;\n\t\t\t\t\tthis.fireEvent(\"onSaveFailed\", newIndex);\n\t\t\t\t}\n\n\t\t\t\tif ((error as any)?.name !== \"AbortError\") {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tsavingState.currentPromise = null;\n\t\t\t\tsavingState.activeCalls--;\n\t\t\t}\n\t\t} else {\n\t\t\tthis.makeClean(index);\n\t\t\treturn false;\n\t\t}\n\n\t\treturn false;\n\t};\n\n\t/**\n\t * Resets a field to the value currently saved in the database\n\t *\n\t * @param {keyof T} field Field to reset\n\t * @returns {boolean} True if successful\n\t */\n\tcancelField = (field: keyof T): boolean =>\n\t\tthis.setField(field, this.getSavedField(this.currentIndex, field) as T[keyof T]);\n\tprotected getFieldIndex = (fieldName: keyof T): number => this.fields.findIndex((f) => f.name === fieldName);\n\n\tgetFieldDefinition = (field: string): FieldDefinition | undefined => this.fields.find((f) => f.name === field);\n\n\t/**\n\t * Get the definition of all fields in the data object\n\t *\n\t * @return {FieldDefinition[]} All field definitions\n\t */\n\tgetFields(): FieldDefinition[];\n\t/**\n\t * Get the definition of a single field in the data object if it exists,\n\t * otherwise undefined\n\t * @param {string} field - Field whose definition to get\n\t */\n\tgetFields(field: string): FieldDefinition | undefined;\n\tgetFields(field: keyof T): FieldDefinition;\n\tgetFields(fieldName?: keyof T | string): FieldDefinition[] | FieldDefinition | undefined {\n\t\tif (fieldName) {\n\t\t\tfor (let i = 0; i < this.fields.length; i++) {\n\t\t\t\tlet field = this.fields[i];\n\t\t\t\tif (field.name === fieldName) {\n\t\t\t\t\treturn Object.assign({}, field, {\n\t\t\t\t\t\tcaption: getLocalizedString(field.caption || field.name) as string,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn undefined;\n\t\t} else {\n\t\t\treturn this.fields.map((field) =>\n\t\t\t\tObject.assign({}, field, {\n\t\t\t\t\tcaption: getLocalizedString(field.caption || field.name) as string,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Creates a `FileUploader` instance that uploads files to this data source.\n\t * If the {fieldName} param is provided, files will be uploaded as blobs to that\n\t * field.\n\t *\n\t * @param {string | undefined} fieldName\n\t */\n\tgetUploader(fieldName?: string) {\n\t\tlet articleId = this.options.articleId;\n\n\t\tif (/\\.\\d{3}$/.test(articleId)) {\n\t\t\tarticleId = articleId.substring(0, articleId.length - 4);\n\t\t}\n\n\t\treturn new FileUploader({ dataObject: this, articleId, fieldName });\n\t}\n\n\thasField = (fieldName: string): boolean => this.fields.some((f) => f.name === fieldName);\n\n\t/**\n\t * Checks if a particular field can be set to null . This will in most cases reflect the logic of sql server.\n\t */\n\tisNullable = (fieldName: string): boolean => {\n\t\tfor (let field of this.fields) {\n\t\t\tif (field.name === fieldName) {\n\t\t\t\treturn this.canSetFieldValueToNull(field);\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t};\n\n\tprivate setField(field: F, value: T[F]): boolean {\n\t\tconst fieldIndex = this.getFieldIndex(field);\n\t\tconst fieldDefinition = this.fields[fieldIndex];\n\n\t\tinvariant(fieldDefinition, `Field '${field as string}' does not exist in the data object`);\n\n\t\t// Make empty strings null\n\t\tif (typeof value === \"string\" && value === \"\") {\n\t\t\t(value as T[F] | null) = null;\n\t\t}\n\n\t\t// Check validation\n\t\tinvariant(\n\t\t\tfieldTypes[this.getFieldType(fieldDefinition, value)].validate(value),\n\t\t\t`Supplied field '${field as string}' was of incorrect type`,\n\t\t);\n\n\t\tlet dirtyRecord = this.currentIndex === -1 ? this.newRecord : this.dirtyRecords[this.currentIndex];\n\n\t\tconst fieldValue = this.storageRetrieve(this.currentIndex, field);\n\n\t\tif (isEqual(fieldValue, value)) {\n\t\t\tif (this.isDirty(fieldDefinition.name)) {\n\t\t\t\tdelete dirtyRecord[fieldDefinition.name as keyof T];\n\t\t\t\tif (!objHasKeys(dirtyRecord)) {\n\t\t\t\t\tif (this.currentIndex !== -1) {\n\t\t\t\t\t\tdelete this.dirtyRecords[this.currentIndex];\n\t\t\t\t\t}\n\t\t\t\t\tthis.fireEvent(\"onDirtyChanged\", false);\n\t\t\t\t}\n\t\t\t\tthis.fireEvent(\"onFieldChanged\", {\n\t\t\t\t\tname: field,\n\t\t\t\t\tvalue,\n\t\t\t\t});\n\n\t\t\t\treturn true;\n\t\t\t} else {\n\t\t\t\treturn false; // nothing happend, same value\n\t\t\t}\n\t\t} else {\n\t\t\tif (dirtyRecord && isEqual(dirtyRecord[fieldDefinition.name as keyof T], value)) {\n\t\t\t\treturn false; // nothing happend, same value\n\t\t\t} else {\n\t\t\t\tconst wasDirty = dirtyRecord && objHasKeys(dirtyRecord);\n\n\t\t\t\tif (this.currentIndex !== -1 && !dirtyRecord) {\n\t\t\t\t\tthis.dirtyRecords[this.currentIndex] = dirtyRecord = {};\n\t\t\t\t}\n\n\t\t\t\tdirtyRecord[fieldDefinition.name as keyof T] = value;\n\n\t\t\t\tif (!wasDirty) {\n\t\t\t\t\tthis.fireEvent(\"onDirtyChanged\", true);\n\t\t\t\t}\n\n\t\t\t\tthis.fireEvent(\"onFieldChanged\", {\n\t\t\t\t\tname: field,\n\t\t\t\t\tvalue,\n\t\t\t\t});\n\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate getSavedField(index: number, field: F): T[F] | null {\n\t\treturn this.storageRetrieve(index, field);\n\t}\n\n\t/**\n\t * Returns all data currently loaded in the data object\n\t */\n\tgetData(): DataRecord[];\n\t/**\n\t * Returns the record at the specified index. Throws an error if index is out of range.\n\t * @param index\n\t */\n\tgetData(index: number): DataRecord;\n\t/**\n\t * Returns the value of the specified field from the record at the specified index. Throws an\n\t * error if the index is out of range, or the field does not exist.\n\t * @param {number} index\n\t * @param {string} field\n\t */\n\tgetData(index: number, field: F): T[F];\n\tgetData(index?: number, fieldName?: F) {\n\t\tif (index !== undefined) {\n\t\t\tthis.checkIndexRange(index);\n\t\t\tif (fieldName !== undefined) {\n\t\t\t\tinvariant(\n\t\t\t\t\tthis.hasField(fieldName as string),\n\t\t\t\t\t`${this.getDataObjectIdentity()} does not have a field named '${fieldName as string}'`,\n\t\t\t\t);\n\n\t\t\t\treturn this.storageRetrieve(index, fieldName);\n\t\t\t} else {\n\t\t\t\treturn this.storageRetrieve(index);\n\t\t\t}\n\t\t} else {\n\t\t\treturn this.storageRetrieve();\n\t\t}\n\t}\n\n\tprotected getDataObjectIdentity = () => {\n\t\tif (this.options.dataSourceId) {\n\t\t\treturn \"The data object \" + this.options.dataSourceId;\n\t\t} else {\n\t\t\treturn \"This data object\";\n\t\t}\n\t};\n\n\tgetDirtyRecord(): CurrentRow;\n\tgetDirtyRecord(field: K): T[K] | null;\n\tgetDirtyRecord(field?: K): CurrentRow | T[K] | null {\n\t\tconst dirtyRecord =\n\t\t\t(this.currentIndex === -1 ? this.newRecord : this.dirtyRecords[this.currentIndex]) || ({} as Partial);\n\n\t\tif (typeof field !== \"string\") {\n\t\t\tlet current: any = this.storageRetrieve(this.currentIndex) ?? ({} as Partial);\n\n\t\t\treturn {\n\t\t\t\t...current,\n\t\t\t\t...dirtyRecord,\n\t\t\t\t[uid]: current?.[uid] ?? (dirtyRecord as StorageRecord>)[uid],\n\t\t\t} as StorageRecord;\n\t\t} else {\n\t\t\tif (Object.hasOwn(dirtyRecord, field)) {\n\t\t\t\treturn dirtyRecord[field] ?? null;\n\t\t\t} else {\n\t\t\t\treturn this.storageRetrieve(this.currentIndex, field);\n\t\t\t}\n\t\t}\n\t}\n\n\tgetIndexFromUniqueId = (uniqueId: T[keyof T]): number | null => {\n\t\tconst rowCount = this.getDataLength();\n\n\t\tfor (let i = 0; i < rowCount; i++) {\n\t\t\tif (this.storageRetrieve(i, this.options.uniqueIdField) === uniqueId) {\n\t\t\t\treturn i; // Return index if found\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t};\n\n\tprivate handleDataHandlerOption = (options: DataObjectOptions): DataHandler => {\n\t\tconst { articleId, dataHandler, dataSourceId, timeout } = options;\n\n\t\t// If a valid DataHandler instance is specified - use that\n\t\tif (dataHandler instanceof DataHandler) {\n\t\t\treturn dataHandler as DataHandler;\n\t\t}\n\n\t\t// Else if an object defining a DataHandler subclass is specified\n\t\tif (dataHandler && typeof dataHandler === \"object\") {\n\t\t\tif (Object.hasOwn(dataHandler, \"type\") && Object.hasOwn(dataHandler, \"options\")) {\n\t\t\t\tconst { options, type } = dataHandler as DataHandlerDescriptor;\n\n\t\t\t\tif (typeof type !== \"function\" && globalThis.af?.data) {\n\t\t\t\t\tconst Handler = (globalThis.af.data as any)[type] as { new (options?: any): DataHandler };\n\n\t\t\t\t\tif (typeof Handler === \"function\") {\n\t\t\t\t\t\t// Try to make a new DataHandler of that type using supplied options\n\t\t\t\t\t\treturn new Handler(options);\n\t\t\t\t\t}\n\t\t\t\t} else if (typeof type === \"function\") {\n\t\t\t\t\tconst Handler = type as { new (options?: any): DataHandler };\n\t\t\t\t\treturn new Handler(options);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn new DataProviderHandler({ articleId, dataSourceId, fields: options.fields, timeout });\n\t};\n\n\tprivate handleRetrieveData = (response: RetrieveResponse) => {\n\t\tconst wasDirty = this.isDirty();\n\t\tif (Array.isArray(response)) {\n\t\t\tthis.storageDestroy();\n\t\t\tthis.dirtyRecords = {};\n\t\t\tthis.storageEngine.create(response);\n\n\t\t\tthis.dataLoaded = Date.now();\n\t\t\tthis.currentIndex = this.options.selectFirstRow && response.length ? 0 : -1;\n\n\t\t\tthis.fireEvent(\"onDataLoaded\", response.length);\n\t\t\tthis.fireEvent(\"onCurrentIndexChanged\", this.currentIndex);\n\n\t\t\tif (wasDirty) {\n\t\t\t\tthis.fireEvent(\"onDirtyChanged\", false);\n\t\t\t}\n\t\t} else if (typeof response.skip === \"number\" && Array.isArray(response.data)) {\n\t\t\tif (response.skip === 0) {\n\t\t\t\tthis.storageDestroy();\n\t\t\t\tthis.dirtyRecords = {};\n\t\t\t\tconst newData: T[] = [];\n\n\t\t\t\tfor (let i = 0; i < response.data.length; i++) {\n\t\t\t\t\tnewData[i + response.skip] = response.data[i];\n\t\t\t\t}\n\n\t\t\t\tfor (let record of newData) {\n\t\t\t\t\tthis.storageCreate(record);\n\t\t\t\t}\n\n\t\t\t\tthis.dataLoaded = Date.now();\n\n\t\t\t\tthis.fireEvent(\"onPartialDataLoaded\", {\n\t\t\t\t\tskip: response.skip,\n\t\t\t\t\tcount: response.data.length,\n\t\t\t\t\ttotal: response.total,\n\t\t\t\t});\n\n\t\t\t\tthis.setIndexTo(this.options.selectFirstRow && newData.length ? 0 : -1);\n\n\t\t\t\tif (wasDirty) {\n\t\t\t\t\tthis.fireEvent(\"onDirtyChanged\", false);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor (let i = 0; i < response.data.length; i++) {\n\t\t\t\t\tthis.storageUpdate(i + response.skip, response.data[i]);\n\t\t\t\t\tdelete this.dirtyRecords[i + response.skip];\n\t\t\t\t}\n\n\t\t\t\tthis.dataLoaded = Date.now();\n\t\t\t\tthis.fireEvent(\"onPartialDataLoaded\", {\n\t\t\t\t\tskip: response.skip,\n\t\t\t\t\tcount: response.data.length,\n\t\t\t\t\ttotal: response.total,\n\t\t\t\t});\n\t\t\t}\n\t\t} else {\n\t\t\tthrow new TypeError(\"Invalid pData parameter passed to handleRetrieveData\");\n\t\t}\n\t};\n\n\t/**\n\t * Returns the value of the first record in the data object where predicate is true, and undefined\n\t * otherwise.\n\t * @param predicate find calls predicate once for each record of the data object, in ascending\n\t * order, until it finds one where predicate returns true. If such a rcord is found, find\n\t * immediately returns that record value. Otherwise, find returns undefined.\n\t */\n\tfind = (\n\t\tpredicate: (value: DataRecord, index: number, obj: DataRecord[]) => unknown,\n\t): DataRecord | undefined => this.getData().find(predicate);\n\n\t/**\n\t * Returns the index of the first record in the data object where predicate is true, and -1\n\t * otherwise.\n\t * @param predicate find calls predicate once for each record of the data object, in ascending\n\t * order, until it finds one where predicate returns true. If such a record is found,\n\t * findIndex immediately returns that record index. Otherwise, findIndex returns -1.\n\t */\n\tfindIndex = (predicate: (value: DataRecord, index: number, obj: StorageArray) => unknown): number =>\n\t\tthis.getData().findIndex(predicate);\n\n\t/**\n\t * Returns the records of the data object that meet the condition specified in a callback function.\n\t * @param predicate A function that accepts up to three arguments. The filter method calls the predicate function one time for each element in the array.\n\t */\n\tfilter = (predicate: (value: DataRecord, index: number, data: DataRecord[]) => unknown): DataRecord[] =>\n\t\tthis.getData().filter(predicate);\n\n\t/**\n\t * Calls a defined callback function on each element of an array, and returns an array that contains the results.\n\t * @param callbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.\n\t */\n\tmap = (callbackfn: (value: DataRecord, index: number, array: DataRecord[]) => U): U[] =>\n\t\tthis.getData().map(callbackfn);\n\n\t/**\n\t * Calls a defined callback function on each element of an array, and returns an array that contains the results.\n\t * @param callbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.\n\t * */\n\tforEach = (callbackFn: (value: DataRecord, index: number, array: DataRecord[]) => void) =>\n\t\tthis.getData().forEach(callbackFn);\n\n\tisDirty = (indexOrFieldName?: number | string): boolean => {\n\t\tif (indexOrFieldName === undefined) {\n\t\t\tconst dirtyRecord = this.currentIndex === -1 ? this.newRecord : this.dirtyRecords[this.currentIndex];\n\n\t\t\treturn !!(dirtyRecord && objHasKeys(dirtyRecord));\n\t\t}\n\n\t\tif (typeof indexOrFieldName === \"number\" && indexOrFieldName % 1 === 0) {\n\t\t\tconst dirtyRecord = indexOrFieldName === -1 ? this.newRecord : this.dirtyRecords[indexOrFieldName];\n\n\t\t\treturn !!(dirtyRecord && objHasKeys(dirtyRecord));\n\t\t} else if (typeof indexOrFieldName === \"string\") {\n\t\t\tconst dirtyRecord = this.currentIndex === -1 ? this.newRecord : this.dirtyRecords[this.currentIndex];\n\n\t\t\treturn !!(dirtyRecord && Object.hasOwn(dirtyRecord, indexOrFieldName));\n\t\t}\n\n\t\treturn false;\n\t};\n\n\tisSaving = (index?: number): boolean => {\n\t\tif (index === undefined) {\n\t\t\treturn Object.hasOwn(this.savingRecords, this.currentIndex);\n\t\t}\n\n\t\tif (typeof index === \"number\" && index % 1 === 0) {\n\t\t\treturn Object.hasOwn(this.savingRecords, index);\n\t\t}\n\n\t\treturn false;\n\t};\n\n\tprivate makeClean = (pIndex?: number, pWasDirty?: boolean) => {\n\t\tconst index = pIndex !== undefined ? pIndex : this.getCurrentIndex();\n\t\tconst wasDirty = pWasDirty !== undefined ? pWasDirty : this.isDirty();\n\n\t\tif (index === -1) {\n\t\t\tthis.newRecord = { [uid]: this.storageEngine.getNewUid() } as PartialWithUid;\n\t\t} else {\n\t\t\tconst { uniqueIdField } = this.options;\n\t\t\tconst hasUniqueIdField = this.fieldNames.includes(uniqueIdField);\n\n\t\t\tif (hasUniqueIdField && this.getSavedField(index, uniqueIdField) === null) {\n\t\t\t\tthis.removeRow(index); // Removes the row internally and fires onCurrentIndexChanged\n\n\t\t\t\treturn; // Stop here, so onRecordRefreshed does not get fired\n\t\t\t} else {\n\t\t\t\tdelete this.dirtyRecords[index];\n\t\t\t\tdelete this.errorRecords[index];\n\t\t\t}\n\t\t}\n\n\t\tif (index === this.currentIndex && wasDirty) {\n\t\t\tthis.fireEvent(\"onDirtyChanged\", false);\n\t\t}\n\n\t\tthis.fireEvent(\"onRecordRefreshed\", index);\n\t};\n\n\tgetMasterDataObject = (): AfDataObject | null => this.options.masterDataObject;\n\n\tprivate refreshMasterChildCriteria = (masterDataObject: AfDataObject) => {\n\t\tconst { linkFields, parameters } = this.options;\n\t\tconst masterChildCriteria: Partial = parameters.masterChildCriteria || {};\n\t\tconst masterRow = masterDataObject.currentRow();\n\t\tlet changed = false;\n\n\t\tinvariant(linkFields, \"Specified linkFields was not an object or array\");\n\t\tif (Array.isArray(linkFields)) {\n\t\t\tfor (let fieldName of linkFields) {\n\t\t\t\tif (Object.hasOwn(masterRow, fieldName) && masterChildCriteria[fieldName as keyof T] !== masterRow[fieldName]) {\n\t\t\t\t\tmasterChildCriteria[fieldName] = masterRow[fieldName];\n\t\t\t\t\tchanged = true;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tfor (let childName of Object.keys(linkFields)) {\n\t\t\t\tlet masterName = linkFields[childName as keyof T] as string;\n\t\t\t\tif (\n\t\t\t\t\tObject.hasOwn(masterRow, masterName) &&\n\t\t\t\t\tmasterChildCriteria[childName as keyof T] !== masterRow[masterName]\n\t\t\t\t) {\n\t\t\t\t\tmasterChildCriteria[childName as keyof T] = masterRow[masterName];\n\t\t\t\t\tchanged = true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (changed) {\n\t\t\tthis.options.parameters.masterChildCriteria = masterChildCriteria;\n\t\t\tthis.parametersChanged = true;\n\t\t\tthis.fireEvent(\"onParameterUpdated\", {\n\t\t\t\tname: \"masterChildCriteria\",\n\t\t\t\tvalue: masterChildCriteria,\n\t\t\t});\n\t\t}\n\t};\n\n\tprivate bindToMaster = (masterDataObject: AfDataObject) => {\n\t\tmasterDataObject.attachEvent(\"onCurrentIndexChanging\", async (event: CustomEvent) => {\n\t\t\tlet { detail: index } = event;\n\t\t\tlet evtResult = this.fireEvent(\"onMasterIndexChanging\", index);\n\t\t\tif (evtResult === false) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tawait this.endEdit();\n\t\t\t} catch (error) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t});\n\n\t\tmasterDataObject.attachEvent(\"onBeforeLoad\", async () => {\n\t\t\tlet evtResult = this.fireEvent(\"onMasterBeforeLoad\", null);\n\t\t\tif (evtResult === false) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tawait this.endEdit();\n\t\t\t} catch (error) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t});\n\n\t\tmasterDataObject.attachEvent(\"onCurrentIndexChanged\", async (event: CustomEvent) => {\n\t\t\tlet { detail: index } = event;\n\t\t\tthis.refreshMasterChildCriteria(masterDataObject);\n\n\t\t\tif (index === -1) {\n\t\t\t\t// Fake loading of no records\n\t\t\t\tlet evtResult = this.fireEvent(\"onBeforeLoad\", this.options.parameters);\n\n\t\t\t\tif (evtResult === false) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tthis.previousRetrieveRequest?.abort();\n\t\t\t\tthis.previousRowCountRequest?.abort();\n\t\t\t\tthis.handleRetrieveData([]); // Clear our internal data\n\t\t\t} else if (this.options.disableAutoload !== true) {\n\t\t\t\tthis.refreshDataSource();\n\t\t\t}\n\t\t});\n\n\t\tmasterDataObject.attachEvent(\"onFieldChanged\", () => {\n\t\t\tthis.refreshMasterChildCriteria(masterDataObject);\n\t\t});\n\n\t\tmasterDataObject.attachEvent(\"onAfterSave\", (event: CustomEvent) => {\n\t\t\tlet { detail: index } = event;\n\n\t\t\tif (this.getCurrentIndex() === index) {\n\t\t\t\tthis.refreshMasterChildCriteria(masterDataObject);\n\n\t\t\t\tif (this.areParametersChanged() && this.options.disableAutoload !== true) {\n\t\t\t\t\tthis.refreshDataSource();\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tthis.refreshMasterChildCriteria(masterDataObject);\n\t};\n\n\tprivate handleMasterDataObjectOption = (): AfDataObject | null => {\n\t\t// Bind to masterDataObject if any\n\t\tlet { linkFields, masterDataObject } = this.options;\n\n\t\tif (this.options.masterDataObject) {\n\t\t\tif (\n\t\t\t\ttypeof masterDataObject === \"string\" &&\n\t\t\t\tObject.hasOwn(globalThis, masterDataObject) &&\n\t\t\t\ttypeof globalThis[masterDataObject] === \"object\"\n\t\t\t) {\n\t\t\t\tthis.options.masterDataObject = globalThis[masterDataObject] as unknown as AfDataObject;\n\t\t\t}\n\n\t\t\tinvariant(linkFields, \"LinkFields was not specified in the options\");\n\t\t\tif (Array.isArray(linkFields)) {\n\t\t\t\tinvariant(linkFields.length !== 0, \"No fields found in specified linkFields\");\n\t\t\t} else if (typeof linkFields === \"object\") {\n\t\t\t\tinvariant(Object.keys(linkFields).length !== 0, \"No fields found in specified linkFields\");\n\t\t\t} else {\n\t\t\t\tthrow new TypeError(\"Specified linkFields was not an object or array\");\n\t\t\t}\n\n\t\t\tthis.bindToMaster(this.options.masterDataObject);\n\n\t\t\treturn this.options.masterDataObject;\n\t\t}\n\n\t\treturn null;\n\t};\n\n\t/**\n\t * Provides the name of the data object.\n\t */\n\tgetDataSourceId = (): string => this.options.dataSourceId;\n\n\t/**\n\t * Get what is set as the maximum rows to dataObject.\n\t */\n\tgetLinkFields = (): Array | Partial> | null => this.options.linkFields;\n\n\t/**\n\t * Get unique field of the data object.\n\t */\n\tgetUniqueIdField = (): keyof T => this.options.uniqueIdField;\n\n\tisAutoLoadDisabled = (): boolean => this.options.disableAutoload;\n\n\toriginalRow(): T;\n\toriginalRow(field: F): T[F];\n\toriginalRow(field?: F): T | T[F] {\n\t\tif (field === undefined) {\n\t\t\treturn this.storageRetrieve(this.currentIndex) as T;\n\t\t} else {\n\t\t\treturn this.getSavedField(this.currentIndex, field) as T[F];\n\t\t}\n\t}\n\n\t/**\n\t * Get a data filtering parameter value\n\t *\n\t * @param {P} name Parameter to get current value for\n\t */\n\tgetParameter

>(name: P): RetrieveParameters[P] {\n\t\tconst { parameters } = this.options;\n\t\tinvariant(Object.hasOwn(parameters, name), \"Invalid parameter name specified when calling getParameter\");\n\t\treturn clone(parameters[name]);\n\t}\n\n\t/**\n\t * Set a parameter value for data filtering.\n\t *\n\t * @param {P} name Name of the parameter\n\t * @param {RetrieveParameters[P]} value Parameter value to set\n\t */\n\tsetParameter

>(name: P, value: RetrieveParameters[P]): void {\n\t\tconst { parameters } = this.options;\n\n\t\tif (name === \"filterString\" || name === \"whereClause\") {\n\t\t\tif (!value) {\n\t\t\t\tvalue = \"\";\n\t\t\t} // Let the filterString/whereClause be empty string if it is falsy\n\n\t\t\tconst parameter = name === \"filterString\" ? \"filterObject\" : \"whereObject\";\n\t\t\tthis.setParameter(parameter, null); // Clear filterObject/whereObject when clearing the string equivalent\n\t\t}\n\n\t\tinvariant(\n\t\t\tObject.hasOwn(parameters, name) && name !== \"masterChildCriteria\",\n\t\t\t\"Invalid parameter specified when calling setParameter: \" + name,\n\t\t);\n\n\t\tconst parameter = (parameters as any)[name];\n\n\t\tinvariant(typeof parameter === typeof value, \"Invalid type of the supplied parameter value: \" + typeof value);\n\n\t\tif (!isEqual(parameter, value)) {\n\t\t\tparameters[name] = value;\n\t\t\tthis.parametersChanged = true;\n\n\t\t\tif (name === \"maxRecords\") {\n\t\t\t\tglobalThis.af?.common.localStorage.set(\n\t\t\t\t\t`${globalThis.af?.article.id}-${this.getDataSourceId()}-pageSize`,\n\t\t\t\t\tvalue,\n\t\t\t\t\tfalse,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tthis.fireEvent(\"onParameterUpdated\", { name, value });\n\t\t}\n\t}\n\n\tsetParameters(parameters: Partial>): void {\n\t\tfor (let [parameter, value] of Object.entries(parameters)) {\n\t\t\tthis.setParameter(parameter, value);\n\t\t}\n\t}\n\n\tprivate getFieldType(field: FieldDefinition, value: any): string {\n\t\tlet type = field.type ?? guessType(value);\n\t\tif (!field.type && value !== null) {\n\t\t\tfield.type = type;\n\t\t}\n\n\t\treturn type;\n\t}\n\n\tcanModifyCurrentRow = (): boolean => this.canModifyRow(this.currentIndex);\n\n\tcanModifyRow = (index: number): boolean => {\n\t\tif (this.isNewRecord(index)) {\n\t\t\treturn this.isInsertAllowed();\n\t\t} else {\n\t\t\treturn this.isUpdateAllowed();\n\t\t}\n\t};\n\n\tisDeleteNeverAllowed = (): boolean => !this.options.allowDelete;\n\tisUpdateNeverAllowed = (): boolean => !this.options.allowUpdate;\n\tisInsertNeverAllowed = (): boolean => !this.options.allowInsert;\n\n\t/**\n\t * Checks if deleting row is allowed. Deleting can either be permanently disabled\n\t * in the data object options, or temporarily disabled with setAllowDelete\n\t * @returns {boolean}\n\t */\n\tisDeleteAllowed = (): boolean => this.options.allowDelete && !this.temporarilyDisallowDelete;\n\n\t/**\n\t * Checks if updating row is allowed. Updating can either be permanently disabled\n\t * in the data object options, or temporarily disabled with setAllowUpdate\n\t * @returns {boolean}\n\t */\n\tisUpdateAllowed = (): boolean => this.options.allowUpdate && !this.temporarilyDisallowUpdate;\n\n\t/**\n\t * Checks if creating new rows is allowed. Insert can either be permanently disabled\n\t * in the data object options, or temporarily disabled with setAllowInsert\n\t * @returns {boolean}\n\t */\n\tisInsertAllowed = (): boolean => this.options.allowInsert && !this.temporarilyDisallowInsert;\n\n\tsetAllowDelete = (allow: boolean): void => {\n\t\tconst disallow = !allow;\n\t\tif (this.temporarilyDisallowDelete !== disallow) {\n\t\t\tthis.temporarilyDisallowDelete = disallow;\n\t\t\tthis.fireEvent(\"onAllowDeleteChanged\", !disallow);\n\t\t}\n\t};\n\n\tsetAllowUpdate = (allow: boolean): void => {\n\t\tconst disallow = !allow;\n\t\tif (this.temporarilyDisallowUpdate !== disallow) {\n\t\t\tthis.temporarilyDisallowUpdate = disallow;\n\t\t\tthis.fireEvent(\"onAllowUpdateChanged\", !disallow);\n\t\t}\n\t};\n\n\tsetAllowInsert = (allow: boolean): void => {\n\t\tconst disallow = !allow;\n\t\tif (this.temporarilyDisallowInsert !== disallow) {\n\t\t\tthis.temporarilyDisallowInsert = disallow;\n\t\t\tthis.fireEvent(\"onAllowInsertChanged\", !disallow);\n\t\t}\n\t};\n\n\trefreshCurrentRow = async (): Promise => await this.refreshRow(this.currentIndex);\n\n\tprivate waitForLoadOrFail = async () => {\n\t\tlet controller = new AbortController();\n\t\tlet { signal } = controller;\n\n\t\tlet load = new Promise((resolve, reject) => {\n\t\t\tthis.attachEvent(\"onDataLoaded\", () => resolve(), { signal });\n\t\t\tthis.attachEvent(\"onPartialDataLoaded\", () => resolve(), { signal });\n\t\t\tthis.attachEvent(\"onDataLoadFailed\", (evt) => reject(evt.detail), { signal });\n\t\t});\n\n\t\ttry {\n\t\t\tawait load;\n\t\t} catch (error) {\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\tcontroller.abort();\n\t\t}\n\t};\n\n\trefreshDataSource = async (options: RefreshDataSourceOptions = {}): Promise => {\n\t\tif (options.parameters) {\n\t\t\tthis.setParameters(options.parameters);\n\t\t}\n\n\t\tif (this.isDirty()) {\n\t\t\tconst shouldReload = await this.beforeReload.call(this);\n\t\t\tif (!shouldReload) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tif (this.isDataLoading() && !this.areParametersChanged()) {\n\t\t\ttry {\n\t\t\t\treturn await this.waitForLoadOrFail();\n\t\t\t} catch (error) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tif (this.options.dynamicLoading === true) {\n\t\t\tthis.retrievePartial(0, this.options.parameters.maxRecords || -1).catch(() => null);\n\t\t} else {\n\t\t\tthis.dataHandlerRetrieve({ ...this.options.parameters }).catch(() => null);\n\t\t}\n\n\t\ttry {\n\t\t\tawait this.waitForLoadOrFail();\n\t\t} catch (error) {\n\t\t\tif (options.throw) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\t};\n\n\trefreshRow = async (index: number): Promise => {\n\t\t// If already reloading data,\n\t\tif (this.isDataLoading()) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst start = Date.now();\n\t\tconst idField = this.options.uniqueIdField;\n\t\tconst id = this.getSavedField(index, idField) as T[keyof T];\n\t\tconst params: RetrieveParameters & { masterChildCriteria: Partial } = {\n\t\t\tfilterString: \"\",\n\t\t\twhereClause: \"\",\n\t\t\tsortOrder: [],\n\t\t\tmasterChildCriteria: {},\n\t\t\treturnTotal: false,\n\t\t};\n\n\t\tparams.masterChildCriteria[idField] = id;\n\n\t\ttry {\n\t\t\tconst result = await this.dataHandler.retrieve(params);\n\n\t\t\t// If data was reloaded after refreshCurrentRow was called and completed before this callback\n\t\t\t// we need to look for a row having the same PrimKey/UniqueKey, and abort if not found\n\t\t\tif (this.dataLoaded !== null && start < this.dataLoaded) {\n\t\t\t\t// If index is more or equal to data length, or primkey is different\n\t\t\t\tif (index >= this.getDataLength() || this.storageRetrieve(index, idField) !== id) {\n\t\t\t\t\tlet indexFromId = this.getIndexFromUniqueId(id); // Look for record's new index\n\n\t\t\t\t\tif (indexFromId === null) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tindex = indexFromId;\n\t\t\t\t}\n\n\t\t\t\t// If index was reset / record's new index was not found\n\t\t\t\tif (index === null) {\n\t\t\t\t\treturn;\n\t\t\t\t} // Abort, because the row is not visible\n\t\t\t}\n\n\t\t\tinvariant(Array.isArray(result), `refreshRow: Invalid data from server. Expected Array, got ${typeof result}`);\n\t\t\tinvariant(result.length === 1, `Invalid data from server. Expected 1 row, got ${result.length} rows.`);\n\t\t\tconst row = result[0];\n\n\t\t\tinvariant(\n\t\t\t\trow && isEqual(row[idField], id),\n\t\t\t\t`Incorrect row from server. Expected \"${idField as string}\" = '${id}', saw \"${idField as string}\" = '${\n\t\t\t\t\trow[idField]\n\t\t\t\t}'`,\n\t\t\t);\n\n\t\t\tthis.storageUpdate(index, row);\n\t\t\tthis.makeClean(index); // will also fire onRecordRefreshed\n\n\t\t\treturn result[0];\n\t\t} catch (error: any) {\n\t\t\tif (error.name !== \"AbortError\") {\n\t\t\t\tthis.fireEvent(\"onDataLoadFailed\", error.message);\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\t};\n\n\tremoveRow = (index: number) => {\n\t\tlet storedRecord = this.storageRetrieve(index);\n\t\tlet rowId;\n\t\tif (storedRecord !== null) {\n\t\t\trowId = (storedRecord as StorageRecord)[uid];\n\t\t\tthis.storageDestroy(index); // Destroy the internal record\n\t\t}\n\n\t\tdelete this.dirtyRecords[index]; // Remove dirty-record\n\n\t\tif (index === this.currentIndex) {\n\t\t\t// If deleting the current index\n\t\t\t// Decrement current index if this was the last record\n\t\t\tif (this.storageLength() <= index) {\n\t\t\t\tthis.currentIndex--;\n\t\t\t}\n\n\t\t\tthis.fireEvent(\"onRecordDeleted\", index);\n\t\t\tthis.fireEvent(\"onRecordDeleted2\", { index, uid: rowId });\n\t\t\t// Notify all controls that we changed to a different record\n\t\t\tthis.fireEvent(\"onCurrentIndexChanged\", this.currentIndex);\n\t\t} else {\n\t\t\t// If we removed a record before the one we have selected decrement the current index\n\t\t\tif (index < this.currentIndex) {\n\t\t\t\tthis.currentIndex--;\n\t\t\t}\n\n\t\t\tthis.fireEvent(\"onRecordDeleted\", index);\n\t\t\tthis.fireEvent(\"onRecordDeleted2\", { index, uid: rowId });\n\t\t\t// Since the current record did not actually change, we do not fire onCurrentIndexChanged\n\t\t}\n\t};\n\n\tretrievePartial = async (skip: number, maxRecords: number): Promise => {\n\t\tconst parameters = {\n\t\t\t...this.options.parameters,\n\t\t\tskip,\n\t\t\tmaxRecords,\n\t\t};\n\n\t\tawait this.dataHandlerRetrieve(parameters);\n\t};\n\n\tsave = async (data: Partial): Promise => {\n\t\tfor (let field in data) {\n\t\t\tthis.currentRow(field, data[field] as T[keyof T]);\n\t\t}\n\n\t\treturn await this.endEdit();\n\t};\n\n\t/**\n\t * Saves the current record if it is dirty, and sets current index\n\t * @param {number} index\n\t * @returns {boolean}\n\t */\n\tsetCurrentIndex(index: number): boolean;\n\t/**\n\t * Saves the current record if it is dirty, waits for the save to complete\n\t * and then sets a new current index.\n\t * @param {number} index\n\t * @param {true} waitForSave\n\t * @returns {Promise}\n\t */\n\tsetCurrentIndex(index: number, waitForSave: true): Promise;\n\t/**\n\t * Saves the current record if it is dirty, and sets current index\n\t * @param {number} index\n\t * @returns {boolean}\n\t */\n\tsetCurrentIndex(index: number, waitForSave: false): boolean;\n\t/**\n\t * Sets the current index to the index of the first record in the data object where predicate is true,\n\t * and -1 otherwise.\n\t * @param predicate find calls predicate once for each record of the data object, in ascending\n\t * order, until it finds one where predicate returns true. If such a rcord is found, the current\n\t * index is set to that record index. Otherwise, the current index is set to -1.\n\t */\n\tsetCurrentIndex(predicate: (value: StorageRecord, index: number, data: StorageArray) => unknown): boolean;\n\t/**\n\t * Sets the current index to the index of the first record in the data object where predicate is true,\n\t * and -1 otherwise. If the current record is dirty, setCurrentIndex will wait for it to save\n\t * before changing the index.\n\t * @param predicate find calls predicate once for each record of the data object, in ascending\n\t * order, until it finds one where predicate returns true. If such a rcord is found, the current\n\t * index is set to that record index. Otherwise, the current index is set to -1.\n\t */\n\tsetCurrentIndex(\n\t\tpredicate: (value: StorageRecord, index: number, data: StorageArray) => unknown,\n\t\twaitForSave: true,\n\t): Promise;\n\t/**\n\t * Sets the current index to the index of the first record in the data object where predicate is true,\n\t * and -1 otherwise.\n\t * @param predicate find calls predicate once for each record of the data object, in ascending\n\t * order, until it finds one where predicate returns true. If such a rcord is found, the current\n\t * index is set to that record index. Otherwise, the current index is set to -1.\n\t */\n\tsetCurrentIndex(\n\t\tpredicate: (value: StorageRecord, index: number, data: StorageArray) => unknown,\n\t\twaitForSave: false,\n\t): boolean;\n\tsetCurrentIndex(\n\t\tindexOrPredicate: number | ((value: StorageRecord, index: number, data: StorageArray) => unknown),\n\t\twaitForSave?: boolean,\n\t): boolean | Promise {\n\t\tlet index: number = typeof indexOrPredicate === \"function\" ? this.findIndex(indexOrPredicate) : indexOrPredicate;\n\n\t\tthis.checkIndexRange(index);\n\n\t\tconst wasDirty = this.isDirty();\n\t\tif (wasDirty && this.currentIndex !== index) {\n\t\t\tconst save = this.endEdit();\n\n\t\t\tif (waitForSave) {\n\t\t\t\treturn save.then((result) => {\n\t\t\t\t\tif (!result) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn this.setIndexTo(index);\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\treturn this.setIndexTo(index);\n\t}\n\n\tprivate setIndexTo = async (index: number): Promise => {\n\t\tthis.checkIndexRange(index);\n\n\t\tlet eventResult = this.fireEvent(\"onCurrentIndexChanging\", index);\n\n\t\tif (eventResult === false) {\n\t\t\treturn false;\n\t\t}\n\n\t\tthis.currentIndex = index;\n\t\tthis.fireEvent(\"onCurrentIndexChanged\", this.currentIndex);\n\n\t\treturn true;\n\t};\n\n\tprivate checkIndexRange = (index: number) => {\n\t\tinvariant(index >= -1 && index < this.storageLength(), `No record found at the supplied index: ${index}`);\n\t};\n\n\tvalidateField(field: string | FieldDefinition, value: any): true | string {\n\t\tlet fieldDef = typeof field === \"string\" ? this.getFieldDefinition(field as string) : field;\n\t\tif (!fieldDef) {\n\t\t\treturn `Field '${field}' does not exist`;\n\t\t}\n\n\t\tif (value === null && !this.canSetFieldValueToNull(fieldDef)) {\n\t\t\treturn fieldDef.name + \" cannot be empty\";\n\t\t}\n\n\t\tif (fieldDef.type && !fieldTypes[fieldDef.type].validate(value)) {\n\t\t\treturn fieldDef.name + \" was of incorrect type\";\n\t\t}\n\n\t\treturn true;\n\t}\n\n\tprivate validateSavingData(record: Partial) {\n\t\tlet recordFieldNames = Object.keys(record) as (keyof T)[];\n\t\t// Loop over fields and check if the passed fields and values are valid\n\t\tlet result = this.fields\n\t\t\t.map((field) => {\n\t\t\t\tif (Object.hasOwn(record, field.name)) {\n\t\t\t\t\t// Remove field from list so we can later check if too many fields was sent in\n\t\t\t\t\trecordFieldNames = recordFieldNames.filter((name) => field.name !== name);\n\n\t\t\t\t\tif (record[field.name as keyof T] === null && !this.canSetFieldValueToNull(field)) {\n\t\t\t\t\t\treturn field.name + \" cannot be empty\";\n\t\t\t\t\t}\n\n\t\t\t\t\tif (field.type && !fieldTypes[field.type].validate(record[field.name as keyof T])) {\n\t\t\t\t\t\treturn field.name + \" was of incorrect type\";\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t\t.filter((value) => !!value);\n\n\t\t// If passed field is equal to a link field, ignore it\n\t\tlet { linkFields } = this.options;\n\t\tif (linkFields !== null) {\n\t\t\tlet fields = Array.isArray(linkFields) ? linkFields : (Object.keys(linkFields) as (keyof T)[]);\n\t\t\trecordFieldNames = recordFieldNames.filter((name) => !fields.includes(name));\n\t\t}\n\n\t\t// If there is still fields in recordFieldNames - show error\n\t\tif (recordFieldNames.length) {\n\t\t\treturn result.concat(recordFieldNames.map((name) => `${name as string} is not a valid field name`)).join(\"\\n\");\n\t\t} else {\n\t\t\treturn result.join(\"\\n\");\n\t\t}\n\t}\n\n\tbulkDestroy = async (primKeys: string[][]) => await this.dataHandler.bulkdestroy({ PrimKeys: primKeys });\n\n\tbulkInsert = async (fields: FieldDefinition[], data: T[], bulk = false, json: any) => {\n\t\tif (fields && !json) {\n\t\t\tfields.forEach(function (item) {\n\t\t\t\tinvariant(item.type && item.name, \"Type and name needs to be present in pFields collection\");\n\t\t\t});\n\t\t}\n\n\t\tconst obj: any = {\n\t\t\tData: data,\n\t\t\tFields: fields,\n\t\t};\n\n\t\tif (json) {\n\t\t\tobj.Json = json;\n\t\t}\n\n\t\tif (bulk) {\n\t\t\tobj.Bulk = \"true\";\n\t\t}\n\n\t\tconst linkFields = this.getLinkFields();\n\t\tconst masterDataObject = this.getMasterDataObject();\n\n\t\tif (masterDataObject && linkFields) {\n\t\t\tif (Array.isArray(linkFields)) {\n\t\t\t\tfor (let field of linkFields) {\n\t\t\t\t\tobj[field] = masterDataObject.currentRow(field);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor (let [childField, masterField] of Object.entries(linkFields)) {\n\t\t\t\t\tobj[childField] = masterDataObject.currentRow(masterField as keyof T);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tlet result = await this.dataHandler.bulkinsert(obj);\n\n\t\treturn result;\n\t};\n}\n", "import { invariant } from \"@olenbetong/appframe-core\";\n\nimport { IClient, getDefaultClient } from \"./Client.js\";\nimport * as errors from \"./errors.js\";\nimport { EventTarget } from \"./events.js\";\nimport { FieldDefinition } from \"./fields.js\";\nimport { fieldTypes, guessType } from \"./utils/fieldTypes.js\";\nimport { getFields, handleResponseError } from \"./utils/index.js\";\n\nfunction getFieldType(field: FieldDefinition, value: any): string {\n\tlet type = field.type ?? guessType(value);\n\tif (!field.type && value !== null) {\n\t\tfield.type = type;\n\t}\n\n\treturn type;\n}\n\nexport function isRequestError(result: any): result is RequestError {\n\treturn result !== null && !Array.isArray(result) && Object.hasOwn(result, \"error\");\n}\n\nexport function arrayRecordToObject(fields: FieldDefinition[], data: T[keyof T][], dataSourceId?: string | null): T {\n\tdataSourceId = dataSourceId ?? \"Anonymous data source\";\n\tinvariant(\n\t\tfields.length === data.length,\n\t\t`${dataSourceId}: Incorrect number of fields in record was passed to the 'from' parameter of parseData`,\n\t);\n\n\tlet record: any = {};\n\tfor (let i = 0; i < fields.length; i++) {\n\t\tlet value = data[i];\n\t\tlet field = fields[i];\n\t\tlet type = getFieldType(field, value);\n\t\tlet fieldType = fieldTypes[type];\n\n\t\tif (fieldType) {\n\t\t\tinvariant(fieldType.validate(value), errors.incorrectTypeOfField(dataSourceId, field.name));\n\t\t\trecord[field.name] = value === null ? null : fieldType.parse(value);\n\t\t}\n\t}\n\n\treturn record as T;\n}\n\nexport function arrayRecordsToObjects(fields: FieldDefinition[], data: any[][], dataSourceId?: string | null): T[] {\n\treturn data.map((record) => arrayRecordToObject(fields, record, dataSourceId ?? undefined));\n}\n\n/**\n * Normalized error object returned when a DataHandler request fails\n */\nexport type RequestError = {\n\taborted?: boolean;\n\terror: string;\n\tinternalError?: any;\n\tlogged?: boolean;\n\tstack?: string;\n\tstatus?: number;\n\tstatusText?: string;\n\tresponseText?: string;\n};\n\nexport enum RequestType {\n\tCreate = \"create\",\n\tDestroy = \"destroy\",\n\tRetrieve = \"retrieve\",\n\tUpdate = \"update\",\n\tRowcount = \"rowcount\",\n\tDistinctData = \"distinctData\",\n\tBulkDestroy = \"bulkdestroy\",\n\tBulkInsert = \"bulkinsert\",\n}\nexport interface DataHandlerConstructor {\n\tnew (options?: any): DataHandler;\n}\n\nexport type DataHandlerDescriptor = {\n\toptions: any;\n\ttype: Function | string | number;\n};\n\nexport enum SortOrder {\n\tAsc = \"asc\",\n\tDesc = \"desc\",\n\tAscNullsLast = \"ascnullslast\",\n\tDescNullsFirst = \"descnullsfirst\",\n}\n\n/**\n * Filter object passed to whereObject or filterObject\n */\nexport type Filter = FilterGroup | FilterExpression | null;\nexport type FilterObject = Filter;\n\nexport type FilterGroup = {\n\ttype: \"group\";\n\tname?: string;\n\tmode: \"and\" | \"or\";\n\titems: Array;\n};\n\nexport type FilterExpression = {\n\ttype: \"expression\";\n\tcolumn: string;\n\toperator: string;\n\tvalue: string | string[] | Date | number | null;\n\tvalueType: string;\n};\n\n/**\n * Parameters passed to a retrieve, distinctData or rowcount request on a DataHandler\n */\nexport type RetrieveParameters = {\n\t[index: string]: any;\n\tdistinctRows?: boolean;\n\tfields?: FieldDefinition[];\n\tfilterObject?: Filter | null;\n\tfilterString?: string;\n\tgroupBy?: string[];\n\tmasterChildCriteria?: Partial;\n\tmaxRecords?: number;\n\tskip?: number;\n\tsortOrder?: Array>;\n\tuniqueName?: string;\n\treturnTotal?: boolean;\n\twhereClause?: string;\n\twhereObject?: Filter | null;\n};\n\nexport type PagedRetrieveParameters = RetrieveParameters & {\n\tskip: number;\n};\n\nexport type RequestOptions = Partial<{\n\tsignal: AbortSignal;\n}>;\n\nexport type RequestData = Partial>;\nexport type APIRequestData = RequestData & {\n\toperation: RequestType;\n\tresourceName: string;\n\tfields: FieldDefinition[];\n\texcludeFieldNames?: boolean;\n};\n\n/**\n * Parameters required by a bulkdestroy request on a DataHandler\n */\nexport type BulkDestroyParameters =\n\t| {\n\t\t\tFilterString?: string;\n\t\t\tIds: string;\n\t\t\tKey: string;\n\t\t\tMasterChildCriteria: Record;\n\t\t\tUpdateColumns: Record;\n\t\t\tWhereClause?: string;\n\t }\n\t| {\n\t\t\tPrimKeys: string[][];\n\t };\n\nexport type BulkInsertParameters = Partial & {\n\t/**\n\t * Field definitions of fields included in Data\n\t */\n\tFields: FieldDefinition[];\n\t/**\n\t * Data values in same order as the Fields\n\t */\n\tData: any[][];\n\tBulk: boolean;\n\tJson: boolean;\n};\n\nexport type BulkUpdateParameters = {\n\tFields: FieldDefinition[];\n\tData: any[][];\n};\n\n/**\n * Parameters required by a distinctData request on a DataHandler\n */\nexport type DistinctDataRequestData = {\n\tparameters: {\n\t\tfield: string;\n\t\tfields: string;\n\t};\n};\n\n/**\n * Parameters required by a destroy request on a DataHandler\n */\nexport type DestroyRequest = {\n\tPrimKey: string;\n};\n\n/**\n * Type returned from a rowcount request on a DataHandler\n */\nexport type PagedRetrieveResponse = {\n\tdata: T[];\n\tskip: number;\n\ttotal: number;\n};\n\n/**\n * Type returned from a retrieve request on a DataHandler\n */\nexport type RetrieveResponse = T[] | PagedRetrieveResponse;\n\nexport type DataProviderHandlerBaseOptions = {\n\ttimeout?: number;\n\tclient?: IClient | null;\n};\n\nexport type DataProviderHandlerOptions = DataProviderHandlerBaseOptions & {\n\tarticleId: string;\n\tdataSourceId: string | null;\n\tfields: Array;\n\tgroupBy?: string[];\n};\n\nexport type DataProviderHandlerAPIOptions = Omit & {\n\tuniqueName?: string;\n\tfields: string | Array | null;\n\tdataSourceId: string;\n};\n\ntype DataProviderHandlerEvent = { onSuccess: unknown; onError: string; onComplete: unknown };\n\nconst DataProviderHandlerEvents = {\n\tonSuccess: { abortable: false },\n\tonError: { abortable: false },\n\tonComplete: { abortable: false }, // Fires after a request completes\n};\n\nexport abstract class DataHandler> extends EventTarget {\n\tabstract create(data: Partial, options?: RequestOptions): Promise;\n\tabstract destroy(data: Partial, options?: RequestOptions): Promise;\n\tabstract retrieve(data: RetrieveParameters, options?: RequestOptions): Promise;\n\tabstract retrieve(\n\t\tdata: PagedRetrieveParameters,\n\t\toptions?: RequestOptions,\n\t): Promise>;\n\tabstract rowcount(data: RequestData, options?: RequestOptions): Promise>;\n\tabstract update(data: Partial, options?: RequestOptions): Promise;\n\tabstract bulkdestroy(data: BulkDestroyParameters): Promise;\n\tabstract bulkinsert(data: BulkInsertParameters): Promise;\n\tabstract distinctData(data: DistinctDataRequestData): Promise;\n\tabstract getFileStoreURL(primKey: string, fileName: string, type?: \"download\" | \"view\"): string;\n\tabstract getBlobURL(primKey: string, field: string, fileName: string, type?: \"download\" | \"view\"): string;\n\n\tconstructor() {\n\t\tsuper(DataProviderHandlerEvents);\n\t}\n}\n\nfunction getDefaultOptions() {\n\treturn {\n\t\tarticleId: globalThis.af?.article?.id,\n\t\tdataSourceId: null,\n\t\ttimeout: 0,\n\t\tfields: [],\n\t\tgroupBy: false,\n\t};\n}\n\nabstract class DataProviderHandlerBase> extends DataHandler {\n\tprotected previousRetrieveRequest: AbortController | null = null;\n\tprivate options: DataProviderHandlerBaseOptions;\n\tget client(): IClient {\n\t\treturn this.options.client ?? getDefaultClient();\n\t}\n\tset client(value: IClient | null) {\n\t\tthis.options.client = value;\n\t}\n\n\tconstructor(options: DataProviderHandlerBaseOptions) {\n\t\tsuper();\n\t\tthis.options = options;\n\t}\n\n\tasync request(\n\t\turl: string,\n\t\tdata: RequestData | null,\n\t\toptions: RequestOptions = {},\n\t): Promise {\n\t\tlet requestInit: RequestInit & { timeout?: number } = {\n\t\t\tbody: JSON.stringify(data),\n\t\t\ttimeout: this.options.timeout,\n\t\t\t...options,\n\t\t};\n\n\t\tconst response = await this.client.afFetch(url, requestInit);\n\n\t\tif (response.ok) {\n\t\t\tlet data = await response.json();\n\t\t\tif (Object.hasOwn(data, \"success\")) {\n\t\t\t\tthis.fireEvent(\"onSuccess\", data.success as T);\n\n\t\t\t\treturn data.success as DataType;\n\t\t\t}\n\t\t}\n\n\t\tconst responseError = await handleResponseError(response);\n\n\t\tif (responseError.canRetry) {\n\t\t\treturn await this.request(url, data, options);\n\t\t}\n\n\t\tthis.fireEvent(\"onError\", responseError.message);\n\n\t\tthrow Error(responseError.message);\n\t}\n}\n\nexport class DataProviderHandler>\n\textends DataProviderHandlerBase\n\timplements DataHandler\n{\n\tprivate _options: DataProviderHandlerOptions;\n\tfields: FieldDefinition[];\n\n\tconstructor(options: Pick & Partial) {\n\t\tsuper(Object.assign({}, getDefaultOptions(), options || {}, 1));\n\t\tthis._options = Object.assign({}, getDefaultOptions(), options || {}, 1);\n\t\tthis.fields = this._options.fields.map((field: FieldDefinition | string) => {\n\t\t\tif (typeof field === \"string\") {\n\t\t\t\treturn { name: field };\n\t\t\t}\n\t\t\treturn field;\n\t\t});\n\t}\n\n\tprivate getFieldsUrlPart() {\n\t\tlet fields = \"\";\n\t\tif (this._options.fields) {\n\t\t\tif (this._options.fields.length > 1) {\n\t\t\t\tfields = this._options.fields.toString().replace(/,/g, \"-\");\n\t\t\t}\n\n\t\t\tif (this._options.groupBy) {\n\t\t\t\tfields += \"/\" + this._options.groupBy;\n\t\t\t}\n\t\t}\n\n\t\treturn fields;\n\t}\n\n\tprivate getUrlForType(type: RequestType, includeFields = false) {\n\t\treturn `/${type}/${this._options.articleId}/${this._options.dataSourceId}/${\n\t\t\tincludeFields ? this.getFieldsUrlPart() : \"\"\n\t\t}`;\n\t}\n\n\tprivate getArticleId() {\n\t\tlet articleId = this._options.articleId;\n\t\tif (/\\.\\d{3}$/.test(articleId)) {\n\t\t\tarticleId = articleId.substring(0, articleId.length - 4);\n\t\t}\n\t\treturn articleId;\n\t}\n\n\tgetFileStoreURL(primKey: string, fileName: string, type: \"download\" | \"view\" = \"view\") {\n\t\treturn `/file/${type}/${this.getArticleId()}/${this._options.dataSourceId}/${primKey}/${encodeURIComponent(\n\t\t\tfileName,\n\t\t)}`;\n\t}\n\n\tgetBlobURL(primKey: string, field: string, fileName: string, type: \"download\" | \"view\" = \"view\") {\n\t\treturn `/file/db/${this.getArticleId()}/${this._options.dataSourceId}/${field}/${primKey}/${encodeURIComponent(\n\t\t\tfileName,\n\t\t)}`;\n\t}\n\n\tasync create(data: RequestData, options?: RequestOptions): Promise {\n\t\tconst result = await this.request(\n\t\t\t`/create/${this._options.articleId}/${this._options.dataSourceId}`,\n\t\t\tdata,\n\t\t\toptions,\n\t\t);\n\n\t\tif (result === null) return null;\n\n\t\treturn arrayRecordToObject(data.fields ?? this.fields, result, this._options.dataSourceId ?? \"\");\n\t}\n\n\tasync retrieve(data: RetrieveParameters, options?: RequestOptions): Promise;\n\tasync retrieve(data: PagedRetrieveParameters, options?: RequestOptions): Promise>;\n\tasync retrieve(data: RetrieveParameters | PagedRetrieveParameters, options?: RequestOptions) {\n\t\tconst result = await this.request>(\n\t\t\tthis.getUrlForType(RequestType.Retrieve),\n\t\t\tdata,\n\t\t\toptions,\n\t\t);\n\t\tif (Array.isArray(result)) {\n\t\t\treturn arrayRecordsToObjects(data.fields ?? this.fields, result, this._options.dataSourceId);\n\t\t} else {\n\t\t\t(result as any).data = arrayRecordsToObjects(data.fields ?? this.fields, result.data);\n\t\t\treturn result as unknown as RetrieveResponse;\n\t\t}\n\t}\n\n\tasync rowcount(data: RequestData, options?: RequestOptions) {\n\t\treturn this.request>(this.getUrlForType(RequestType.Rowcount), data, options);\n\t}\n\n\tasync update(data: RequestData, options?: RequestOptions): Promise {\n\t\tlet response = await this.request(this.getUrlForType(RequestType.Update), data, options);\n\n\t\treturn response ? arrayRecordToObject(data.fields ?? this.fields, response, this._options.dataSourceId) : response;\n\t}\n\n\tasync destroy(data: RequestData, options?: RequestOptions) {\n\t\treturn this.request(this.getUrlForType(RequestType.Destroy), data, options);\n\t}\n\n\tasync bulkdestroy(data: BulkDestroyParameters, options?: RequestOptions) {\n\t\tlet result = await this.request(this.getUrlForType(RequestType.BulkDestroy, false), data, options);\n\n\t\treturn result;\n\t}\n\n\tprivate resultSetToObjects(result: T[keyof T][][], fields?: FieldDefinition[]): T[] {\n\t\treturn arrayRecordsToObjects(fields ?? this.fields, result, this._options.dataSourceId);\n\t}\n\n\tasync bulkinsert(data: RequestData, options?: RequestOptions) {\n\t\tlet result = await this.request(this.getUrlForType(RequestType.BulkInsert), data, options);\n\t\tlet parsed = this.resultSetToObjects(result);\n\n\t\treturn parsed;\n\t}\n\n\tasync distinctData(data: DistinctDataRequestData, options?: RequestOptions) {\n\t\tlet result = await this.request(\n\t\t\t`/retrieve/${this._options.articleId}/${this._options.dataSourceId}/${data.parameters.fields}/true/${data.parameters.field}`,\n\t\t\tdata,\n\t\t\toptions,\n\t\t);\n\t\tlet parsed = this.resultSetToObjects(result);\n\n\t\treturn parsed;\n\t}\n}\n\nexport class DataProviderHandlerAPI>\n\textends DataProviderHandlerBase\n\timplements DataHandler\n{\n\tprivate _options: DataProviderHandlerAPIOptions;\n\tfields: FieldDefinition[];\n\n\tconstructor(options: DataProviderHandlerAPIOptions) {\n\t\tsuper(Object.assign({}, getDefaultOptions(), options));\n\t\tthis._options = options;\n\t\tthis.fields = this._options.fields.map((field: FieldDefinition | string) => {\n\t\t\tif (typeof field === \"string\") {\n\t\t\t\treturn { name: field };\n\t\t\t}\n\t\t\treturn field;\n\t\t});\n\t}\n\n\tprivate resultSetToObjects(result: T[keyof T][][], fields?: FieldDefinition[]): T[] {\n\t\treturn arrayRecordsToObjects(fields ?? this.fields, result, this._options.dataSourceId);\n\t}\n\n\tprivate resultRowToObject(result: T[keyof T][], fields?: FieldDefinition[]): T {\n\t\treturn arrayRecordToObject(fields ?? this.fields, result, this._options.dataSourceId);\n\t}\n\n\tprivate getParameters(type: RequestType, data: RequestData): APIRequestData {\n\t\tlet params: APIRequestData = {\n\t\t\toperation: type,\n\t\t\tresourceName: this._options.dataSourceId,\n\t\t\tfields: getFields(this._options.fields),\n\t\t\texcludeFieldNames: true,\n\t\t\t...data,\n\t\t};\n\n\t\tif (type === RequestType.Retrieve && this._options.groupBy) {\n\t\t\tparams.groupBy = this._options.groupBy;\n\t\t}\n\n\t\tif (this._options.uniqueName) {\n\t\t\tparams.uniqueName = this._options.uniqueName;\n\t\t}\n\n\t\treturn params;\n\t}\n\n\tgetFileStoreURL(primKey: string, fileName: string, type: \"download\" | \"view\" = \"view\") {\n\t\treturn `/api/data/file/${type}/${this._options.dataSourceId}/${primKey}/${encodeURIComponent(fileName)}`;\n\t}\n\n\tgetBlobURL(primKey: string, field: string, fileName: string, type: \"download\" | \"view\" = \"view\") {\n\t\treturn `/api/data/blob/${this._options.dataSourceId}/${primKey}/${field}/${encodeURIComponent(fileName)}`;\n\t}\n\n\tasync create(data: RequestData, options?: RequestOptions): Promise {\n\t\tlet result = await this.request(\n\t\t\t\"/api/data\",\n\t\t\tthis.getParameters(RequestType.Create, data),\n\t\t\toptions,\n\t\t);\n\t\treturn result == null ? null : this.resultRowToObject(result, data.fields);\n\t}\n\n\tasync retrieve(data: RetrieveParameters, options?: RequestOptions): Promise;\n\tasync retrieve(data: PagedRetrieveParameters, options?: RequestOptions): Promise>;\n\tasync retrieve(data: RequestData, options?: RequestOptions) {\n\t\tlet result = await this.request>(\n\t\t\t\"/api/data\",\n\t\t\tthis.getParameters(RequestType.Retrieve, data),\n\t\t\toptions,\n\t\t);\n\t\tlet parsed: RetrieveResponse;\n\t\tif (Array.isArray(result)) {\n\t\t\tparsed = arrayRecordsToObjects(data.fields ?? this.fields, result, this._options.dataSourceId);\n\t\t} else {\n\t\t\tparsed = {\n\t\t\t\t...result,\n\t\t\t\tdata: arrayRecordsToObjects(data.fields ?? this.fields, result.data, this._options.dataSourceId),\n\t\t\t};\n\t\t}\n\t\treturn parsed;\n\t}\n\n\tasync rowcount(data: RequestData, options?: RequestOptions) {\n\t\tlet result = await this.request>(\n\t\t\t\"/api/data\",\n\t\t\tthis.getParameters(RequestType.Rowcount, data),\n\t\t\toptions,\n\t\t);\n\n\t\treturn result;\n\t}\n\n\tasync update(data: RequestData, options?: RequestOptions): Promise {\n\t\tlet result = await this.request(\n\t\t\t\"/api/data\",\n\t\t\tthis.getParameters(RequestType.Update, data),\n\t\t\toptions,\n\t\t);\n\t\tlet parsed = !result ? result : this.resultRowToObject(result, data.fields);\n\n\t\treturn parsed;\n\t}\n\n\tasync destroy(data: RequestData, options?: RequestOptions) {\n\t\tlet result = await this.request(\"/api/data\", this.getParameters(RequestType.Destroy, data), options);\n\t\treturn result;\n\t}\n\n\tasync bulkdestroy(data: BulkDestroyParameters, options?: RequestOptions) {\n\t\tlet result = await this.request(\"/api/data\", this.getParameters(RequestType.BulkDestroy, data), options);\n\n\t\treturn result;\n\t}\n\n\tasync bulkinsert(data: RequestData, options?: RequestOptions) {\n\t\tlet result = await this.request(\n\t\t\t\"/api/data\",\n\t\t\tthis.getParameters(RequestType.BulkInsert, data),\n\t\t\toptions,\n\t\t);\n\t\tlet parsed = this.resultSetToObjects(result, data.fields);\n\t\treturn parsed;\n\t}\n\n\tasync distinctData(data: DistinctDataRequestData, options?: RequestOptions) {\n\t\tlet parameters = this.getParameters(RequestType.DistinctData, data);\n\t\tparameters.distinctRows = true;\n\t\tlet result = await this.request(\"/api/data\", parameters, options);\n\t\tlet parsed = this.resultSetToObjects(result);\n\n\t\treturn parsed;\n\t}\n}\n", "import { invariant } from \"@olenbetong/appframe-core\";\n\nexport type LoginOptions = {\n\tremember?: boolean;\n};\n\nexport interface IClient {\n\treadonly hostname: string;\n\n\t/**\n\t * Wraps fetch and adds JSON headers (Accept and Content-Type) and X-Requested-With\n\t * which is required by some handlers. If timeout is set in `init`, the request will\n\t * be aborted if not finished by the amount of milliseconds set.\n\t *\n\t * If Content-Type should not be JSON, either pass in another Content-Type, or set\n\t * isJson to false in `init`\n\t */\n\tafFetch(url: string, init: RequestInit & { timeout?: number; isJson?: boolean }): Promise;\n\tfetch(input: any, init: any): Promise;\n\tlogin(username: string, password: string, options?: LoginOptions): Promise;\n\tsetHostname(hostname?: string): void;\n}\n\nlet defaultClient: IClient;\n\nexport function getDefaultClient() {\n\tinvariant(defaultClient, \"No default client has been set\");\n\treturn defaultClient;\n}\n\nexport function setDefaultClient(client: IClient) {\n\tdefaultClient = client;\n}\n", "export const incorrectTypeOfField = (id: string, field: string) =>\n\t`${id}: Failed to set value of the field '${field}'. Incorrect type.`;\nexport const fieldCannotBeEmpty = (id: string, field: string) =>\n\t`${id}: Failed to set value of the field '${field}'. Field cannot be empty.`;\n", "export type EventType = string | symbol;\n\n// An event handler can take an optional event argument\n// and should not return a value\nexport type Handler = (event: T) => void;\nexport type WildcardHandler> = (\n\ttype: keyof T,\n\tevent: T[keyof T]\n) => void;\n\n// An array of all currently registered event handlers for a type\nexport type EventHandlerList = Array>;\nexport type WildCardEventHandlerList> = Array<\n\tWildcardHandler\n>;\n\n// A map of event types and their corresponding event handlers.\nexport type EventHandlerMap> = Map<\n\tkeyof Events | '*',\n\tEventHandlerList | WildCardEventHandlerList\n>;\n\nexport interface Emitter> {\n\tall: EventHandlerMap;\n\n\ton(type: Key, handler: Handler): void;\n\ton(type: '*', handler: WildcardHandler): void;\n\n\toff(\n\t\ttype: Key,\n\t\thandler?: Handler\n\t): void;\n\toff(type: '*', handler: WildcardHandler): void;\n\n\temit(type: Key, event: Events[Key]): void;\n\temit(\n\t\ttype: undefined extends Events[Key] ? Key : never\n\t): void;\n}\n\n/**\n * Mitt: Tiny (~200b) functional event emitter / pubsub.\n * @name mitt\n * @returns {Mitt}\n */\nexport default function mitt>(\n\tall?: EventHandlerMap\n): Emitter {\n\ttype GenericEventHandler =\n\t\t| Handler\n\t\t| WildcardHandler;\n\tall = all || new Map();\n\n\treturn {\n\t\t/**\n\t\t * A Map of event names to registered handler functions.\n\t\t */\n\t\tall,\n\n\t\t/**\n\t\t * Register an event handler for the given type.\n\t\t * @param {string|symbol} type Type of event to listen for, or `'*'` for all events\n\t\t * @param {Function} handler Function to call in response to given event\n\t\t * @memberOf mitt\n\t\t */\n\t\ton(type: Key, handler: GenericEventHandler) {\n\t\t\tconst handlers: Array | undefined = all!.get(type);\n\t\t\tif (handlers) {\n\t\t\t\thandlers.push(handler);\n\t\t\t} else {\n\t\t\t\tall!.set(type, [handler] as EventHandlerList);\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Remove an event handler for the given type.\n\t\t * If `handler` is omitted, all handlers of the given type are removed.\n\t\t * @param {string|symbol} type Type of event to unregister `handler` from (`'*'` to remove a wildcard handler)\n\t\t * @param {Function} [handler] Handler function to remove\n\t\t * @memberOf mitt\n\t\t */\n\t\toff(type: Key, handler?: GenericEventHandler) {\n\t\t\tconst handlers: Array | undefined = all!.get(type);\n\t\t\tif (handlers) {\n\t\t\t\tif (handler) {\n\t\t\t\t\thandlers.splice(handlers.indexOf(handler) >>> 0, 1);\n\t\t\t\t} else {\n\t\t\t\t\tall!.set(type, []);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Invoke all handlers for the given type.\n\t\t * If present, `'*'` handlers are invoked after type-matched handlers.\n\t\t *\n\t\t * Note: Manually firing '*' handlers is not supported.\n\t\t *\n\t\t * @param {string|symbol} type The event type to invoke\n\t\t * @param {Any} [evt] Any value (object is recommended and powerful), passed to each handler\n\t\t * @memberOf mitt\n\t\t */\n\t\temit(type: Key, evt?: Events[Key]) {\n\t\t\tlet handlers = all!.get(type);\n\t\t\tif (handlers) {\n\t\t\t\t(handlers as EventHandlerList)\n\t\t\t\t\t.slice()\n\t\t\t\t\t.map((handler) => {\n\t\t\t\t\t\thandler(evt!);\n\t\t\t\t\t});\n\t\t\t}\n\n\t\t\thandlers = all!.get('*');\n\t\t\tif (handlers) {\n\t\t\t\t(handlers as WildCardEventHandlerList)\n\t\t\t\t\t.slice()\n\t\t\t\t\t.map((handler) => {\n\t\t\t\t\t\thandler(type, evt!);\n\t\t\t\t\t});\n\t\t\t}\n\t\t}\n\t};\n}\n", "import mitt, { Emitter, Handler } from \"mitt\";\n\nimport { RetrieveParameters } from \"./DataHandler\";\n\n/**\n * Events that can be triggered by a data object\n */\nexport type DataObjectEventToValueMap = {\n\tonCurrentIndexChanging: number;\n\tonCurrentIndexChanged: number;\n\tonMasterIndexChanging: number;\n\tonAllowDeleteChanged: boolean;\n\tonAllowUpdateChanged: boolean;\n\tonAllowInsertChanged: boolean;\n\tonBeginEdit: number;\n\tonCancelEdit: number;\n\tonBeforeSave: Partial;\n\tonSaving: undefined;\n\tonAfterSave: number;\n\tonSaveFailed: number;\n\tonBeforeLoad: RetrieveParameters;\n\tonDataLoaded: number;\n\tonDataLoading: null;\n\tonMasterBeforeLoad: null;\n\tonPartialDataLoaded: { skip: number; count: number; total: number };\n\tonDataLoadFailed: string | null;\n\tonDirtyChanged: boolean;\n\tonFieldChanged: { name: keyof T; value: T[keyof T] };\n\tonParameterUpdated: ParameterUpdatedValue>;\n\tonRecordCreated: number;\n\tonRecordRefreshed: number;\n\tonRecordDeleting: number;\n\tonRecordDeleted: number;\n\tonRecordDeleted2: { index: number; uid: any };\n\tonRowCountLoaded: { skip: number; count: number; total: number };\n\tonClearFilter: undefined;\n};\n\nexport type EventOptions = {\n\t/**\n\t * If true, the handler will only be called once, before it is removed.\n\t */\n\tonce?: boolean;\n\t/**\n\t * If you pass an AbortSignal to the event options, the handler will be detached when the signal is aborted.\n\t */\n\tsignal?: AbortSignal;\n};\n\nexport type ParameterUpdatedValue> = {\n\tname: K;\n\tvalue: RetrieveParameters[K];\n};\n\nexport type DataObjectEvent = keyof DataObjectEventToValueMap;\n\nexport const DataObjectEvents: Record = {\n\tonCurrentIndexChanging: { abortable: true },\n\tonCurrentIndexChanged: { abortable: false },\n\tonMasterIndexChanging: { abortable: true },\n\tonAllowDeleteChanged: { abortable: false },\n\tonAllowUpdateChanged: { abortable: false },\n\tonAllowInsertChanged: { abortable: false },\n\tonBeginEdit: { abortable: true },\n\tonCancelEdit: { abortable: true },\n\tonBeforeSave: { abortable: true },\n\tonSaving: { abortable: false },\n\tonAfterSave: { abortable: false },\n\tonSaveFailed: { abortable: false },\n\tonBeforeLoad: { abortable: true },\n\tonDataLoaded: { abortable: false },\n\tonDataLoading: { abortable: false },\n\tonMasterBeforeLoad: { abortable: true },\n\tonPartialDataLoaded: { abortable: false },\n\tonDataLoadFailed: { abortable: false },\n\tonDirtyChanged: { abortable: false },\n\tonFieldChanged: { abortable: false },\n\tonParameterUpdated: { abortable: false },\n\tonRecordCreated: { abortable: false },\n\tonRecordRefreshed: { abortable: false },\n\tonRecordDeleting: { abortable: true },\n\tonRecordDeleted: { abortable: false },\n\tonRecordDeleted2: { abortable: false },\n\tonRowCountLoaded: { abortable: false },\n\tonClearFilter: { abortable: false },\n};\n\ntype CustomEventify = { [K in keyof T]: CustomEvent };\n\nexport class EventTarget> {\n\treadonly eventHandler: Emitter>;\n\tprotected events: Record;\n\n\tconstructor(events: Record) {\n\t\tthis.eventHandler = mitt();\n\t\tthis.events = events;\n\t}\n\n\t/**\n\t * This maps the handler functions to a function that detaches the event.\n\t * This way, we can still detach the handler by reference if we have actually\n\t * attached a wrapped handler.\n\t */\n\tprivate detachFunctionMap = new Map>();\n\n\tattachEvent = (\n\t\tevent: K,\n\t\tfunc: Handler[K]>,\n\t\toptions: EventOptions = {},\n\t): (() => void) => {\n\t\tlet handler: Handler[K]> = func;\n\t\tif (options.once === true) {\n\t\t\thandler = (data: CustomEventify[K]) => {\n\t\t\t\tfunc(data);\n\t\t\t\tthis.detachEvent(event, func);\n\t\t\t};\n\t\t}\n\n\t\tthis.detachFunctionMap.set(func, handler);\n\t\tthis.eventHandler.on(event, handler);\n\n\t\tconst { signal } = options;\n\t\tif (signal) {\n\t\t\tconst onAbort = () => {\n\t\t\t\tthis.detachEvent(event, func);\n\t\t\t};\n\t\t\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\t\t}\n\n\t\treturn () => this.detachEvent(event, handler);\n\t};\n\n\tdetachEvent = (event: K, func: Handler[K]>): void => {\n\t\tlet handler = this.detachFunctionMap.get(func);\n\t\tif (handler) {\n\t\t\tthis.eventHandler.off(event, handler);\n\t\t\tthis.detachFunctionMap.delete(func);\n\t\t}\n\t};\n\n\tprotected fireEvent = (eventName: K, args?: Events[K]) => {\n\t\tlet event = new globalThis.CustomEvent(eventName as string, {\n\t\t\tcancelable: this.events[eventName].abortable,\n\t\t\tdetail: args,\n\t\t});\n\t\tthis.eventHandler.emit(eventName, event);\n\n\t\treturn !event.defaultPrevented;\n\t};\n}\n", "const regexes = {\n\tisodate: /^(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})(?:\\.(\\d{1,7}))?Z$/,\n\tjsondate: /^\\/Date\\((-?[0-9]+)\\)\\/$/i,\n\tuniqueidentifier: /^[a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}$/i,\n\tbase64: /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/,\n};\n\nexport type FieldType = {\n\t/**\n\t * Parse data from server as type\n\t */\n\tparse: (value: any) => any;\n\t/**\n\t * Check that a value is of the correct type.\n\t */\n\tvalidate: (value: any) => boolean;\n};\n\nexport function guessType(val: any): string {\n\t// Doesn't really matter which type it is if the value is null\n\t// Both parsing and validation will pass for any type\n\tif (val == null) {\n\t\treturn \"string\";\n\t}\n\n\tif (Array.isArray(val)) {\n\t\treturn \"array\";\n\t} else if (typeof val === \"string\") {\n\t\tif (regexes.isodate.test(val) || regexes.jsondate.test(val)) {\n\t\t\treturn \"datetime\";\n\t\t} else if (regexes.uniqueidentifier.test(val)) {\n\t\t\treturn \"uniqueidentifier\";\n\t\t}\n\n\t\treturn \"string\";\n\t} else if (val instanceof Date) {\n\t\treturn \"datetime\";\n\t}\n\n\tlet type = typeof val;\n\tif ([\"bigint\", \"number\", \"boolean\"].includes(type)) {\n\t\treturn type;\n\t}\n\n\treturn \"string\";\n}\n\nexport function registerType(type: string, fieldType: FieldType) {\n\tif (!fieldTypes[type]) {\n\t\tfieldTypes[type] = fieldType;\n\t} else {\n\t\tconsole.warn(`Field type '${type}' already registered`);\n\t}\n}\n\nfunction validateDate(val: any): val is Date | null {\n\treturn (\n\t\tval === null ||\n\t\tval instanceof Date ||\n\t\t(typeof val === \"string\" && (regexes.isodate.test(val) || regexes.jsondate.test(val))) ||\n\t\ttypeof val === \"number\"\n\t);\n}\n\nconst ONE_DAY_IN_MS = 86_400_000;\n\nexport const fieldTypes: Record = {\n\tstring: {\n\t\tparse: (value: any) => value.toString(),\n\t\tvalidate: (value: any) => value === null || typeof value === \"string\",\n\t},\n\tnumber: {\n\t\tparse: (value: any) => value,\n\t\tvalidate: (value: any) => value === null || (typeof value === \"number\" && !isNaN(value)),\n\t},\n\tboolean: {\n\t\tparse: (value: any) => value,\n\t\tvalidate: (value: any) => value === null || typeof value === \"boolean\",\n\t},\n\tbigint: {\n\t\tparse: (value: any) => BigInt(value),\n\t\tvalidate: (value: any) =>\n\t\t\tvalue === null || typeof value === \"string\" || typeof value === \"bigint\" || typeof value === \"number\",\n\t},\n\tuniqueidentifier: {\n\t\tparse: (value: any) => value,\n\t\tvalidate: (value: any) => value === null || (typeof value === \"string\" && regexes.uniqueidentifier.test(value)),\n\t},\n\tarray: {\n\t\tparse: (value: any) => value,\n\t\tvalidate: (value: any) => value === null || Array.isArray(value),\n\t},\n\tdate: {\n\t\tparse: (value: any) => {\n\t\t\tlet milliseconds = fieldTypes[\"datetime\"].parse(value).valueOf();\n\n\t\t\tif (value instanceof Date) {\n\t\t\t\tmilliseconds = +value;\n\t\t\t} else if (typeof value === \"string\" && !value.indexOf(\"/Date(\")) {\n\t\t\t\tmilliseconds = Number(value.substring(6, value.length - 2));\n\t\t\t} else {\n\t\t\t\tmilliseconds = +new Date(value);\n\t\t\t}\n\n\t\t\treturn new Date(~~(milliseconds / ONE_DAY_IN_MS) * ONE_DAY_IN_MS);\n\t\t},\n\t\tvalidate: validateDate,\n\t},\n\tdatetime: {\n\t\tparse: (value: any) => {\n\t\t\tif (value instanceof Date) {\n\t\t\t\treturn value;\n\t\t\t} else if (typeof value === \"string\" && !value.indexOf(\"/Date(\")) {\n\t\t\t\treturn new Date(Number(value.substring(6, value.length - 2)));\n\t\t\t}\n\t\t\treturn new Date(value);\n\t\t},\n\t\tvalidate: validateDate,\n\t},\n\ttime: {\n\t\tparse: (value: any) => fieldTypes[\"datetime\"].parse(value),\n\t\tvalidate: validateDate,\n\t},\n\txml: {\n\t\tparse: (value: any) => value.toString(),\n\t\tvalidate: (value: any) => value === null || typeof value === \"string\",\n\t},\n\tbinary: {\n\t\tparse: (value: any) => {\n\t\t\tif (!value) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tlet binStr = atob(value);\n\t\t\tlet bytes = new Uint8Array(binStr.length);\n\n\t\t\tfor (let i = 0; i < binStr.length; i++) {\n\t\t\t\tbytes[i] = binStr.charCodeAt(i);\n\t\t\t}\n\n\t\t\treturn bytes.buffer;\n\t\t},\n\t\tvalidate: (value: any) => {\n\t\t\tif (value === null || value instanceof ArrayBuffer || value instanceof Uint8Array || value instanceof Blob) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\treturn regexes.base64.test(value);\n\t\t},\n\t},\n};\n", "/* eslint-disable no-console */\nfunction userSessionExpiredPromise(): Promise {\n\treturn new Promise((resolve) => {\n\t\tconst timeout = setTimeout(\n\t\t\t() => {\n\t\t\t\tresolve(false);\n\t\t\t},\n\t\t\t1000 * 60 * 10,\n\t\t);\n\n\t\tglobalThis.af?.userSession?.expired?.(() => {\n\t\t\tclearTimeout(timeout);\n\t\t\tresolve(true);\n\t\t});\n\t});\n}\n\ntype ResponseError = {\n\thandled: boolean;\n\tcanRetry: boolean;\n\terror: string | Record;\n\tmessage: string;\n\tstack?: string;\n\tstackTrace?: string;\n\tstatus?: number;\n\tstatusText?: string;\n};\n\nfunction isXHR(response: Response | XMLHttpRequest): response is XMLHttpRequest {\n\treturn globalThis.XMLHttpRequest !== undefined && response instanceof XMLHttpRequest;\n}\n\nexport async function handleResponseError(response: Response | XMLHttpRequest): Promise {\n\tconst contentType = isXHR(response)\n\t\t? response.getResponseHeader(\"Content-Type\")\n\t\t: response.headers.get(\"Content-Type\") || \"\";\n\tlet { status, statusText } = response;\n\tlet data: any;\n\n\tif (isXHR(response)) {\n\t\tdata = contentType?.includes(\"json\") ? JSON.parse(response.response) : response.response;\n\t} else {\n\t\tdata = contentType?.includes(\"json\") ? await response.json() : await response.text();\n\t}\n\n\tif (status === 401 && data === \"Session expired\") {\n\t\treturn {\n\t\t\thandled: true,\n\t\t\tcanRetry: await userSessionExpiredPromise(),\n\t\t\terror: data,\n\t\t\tmessage: data,\n\t\t\tstatus,\n\t\t\tstatusText,\n\t\t};\n\t}\n\n\tif (typeof data === \"object\" && Object.hasOwn(data, \"error\")) {\n\t\tlet message = typeof data.error === \"object\" ? data.error.message : data.error;\n\t\tlet stack = typeof data.error === \"object\" ? data.error.stackTrace : data.stack;\n\t\tconst error: ResponseError = {\n\t\t\t...data,\n\t\t\thandled: false,\n\t\t\tcanRetry: false,\n\t\t\tmessage,\n\t\t\tstackTrace: stack,\n\t\t\tstack,\n\t\t};\n\n\t\tif (Object.hasOwn(data, \"stack\") && process.env.NODE_ENV !== \"test\") {\n\t\t\tconsole.groupCollapsed(data.error);\n\t\t\tconsole.log(data.stack);\n\t\t\tconsole.groupEnd();\n\t\t}\n\n\t\treturn error;\n\t}\n\n\tlet contentMaybeHtml = contentType?.includes(\"text/html\");\n\tif (!contentMaybeHtml && data[0] == \"<\") {\n\t\tcontentMaybeHtml = true;\n\t}\n\n\tif (data && data.length > 0 && contentMaybeHtml) {\n\t\tlet errorRegEx = /

((.|\\n)*?)<\\/pre>/;\n\t\tlet regExArray = errorRegEx.exec(data);\n\t\tlet error = `Sorry, but there seems to be an error.\\nThe server responded with status code: ${status}`;\n\t\tif (regExArray) {\n\t\t\terror = regExArray[1];\n\t\t}\n\t\treturn {\n\t\t\thandled: false,\n\t\t\tcanRetry: false,\n\t\t\terror,\n\t\t\tmessage: error,\n\t\t\tstatus,\n\t\t\tstatusText,\n\t\t};\n\t}\n\n\tlet message: string = !data && status ? `${status} ${statusText}` : data || \"Unspecified error\";\n\n\treturn {\n\t\thandled: false,\n\t\tcanRetry: false,\n\t\terror: message,\n\t\tmessage,\n\t\tstatus,\n\t\tstatusText,\n\t};\n}\n", "import { FieldDefinition } from \"../fields.js\";\n\nexport function getFields(\n\tfields: null | Array | string,\n\tdefaultNullable = true,\n): FieldDefinition[] {\n\tif (fields === null) {\n\t\treturn [];\n\t} else if (Array.isArray(fields)) {\n\t\treturn fields.map((field) => {\n\t\t\tif (typeof field === \"object\") {\n\t\t\t\treturn field;\n\t\t\t} else {\n\t\t\t\treturn { name: field, nullable: defaultNullable } as FieldDefinition;\n\t\t\t}\n\t\t});\n\t} else if (typeof fields === \"string\") {\n\t\treturn [{ name: fields }];\n\t}\n\n\treturn fields;\n}\n", "function getTag(object: any) {\n\treturn Object.prototype.toString.call(object);\n}\n\n/**\n * Not a complete isEqual implementation, just fulfills our needs\n */\nexport function isEqual(object: any, other: any) {\n\tif (!object || !other) {\n\t\treturn object === other;\n\t}\n\n\tif (typeof object === \"object\" && typeof other === \"object\") {\n\t\tlet tagObject = getTag(object);\n\t\tlet tagOther = getTag(other);\n\n\t\tif (tagObject === tagOther) {\n\t\t\tif (tagObject === \"[object Date]\") {\n\t\t\t\treturn object.getTime() === other.getTime();\n\t\t\t} else if (tagObject === \"[object Array]\") {\n\t\t\t\tif (object.length !== other.length) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tfor (let i = 0; i < object.length; i++) {\n\t\t\t\t\tif (!isEqual(object[i], other[i])) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tfor (let [key, value] of Object.entries(object)) {\n\t\t\t\tif (!isEqual(other[key], value)) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\treturn object === other;\n}\n", "export function requestTimeout(controller: AbortController, timeout: number) {\n\tlet cancelled = false;\n\n\tconst t = setTimeout(() => {\n\t\tif (!cancelled && !controller.signal.aborted) {\n\t\t\tcontroller.abort();\n\t\t}\n\t}, timeout);\n\n\treturn function cancelTimeout() {\n\t\tclearTimeout(t);\n\t\tcancelled = true;\n\t};\n}\n", "import { fieldTypes, guessType, registerType } from \"./fieldTypes.js\";\n\nexport { fieldTypes, guessType, registerType };\nexport { handleResponseError } from \"./handleResponseError.js\";\nexport { getFields } from \"./getFields.js\";\nexport { isEqual } from \"./isEqual.js\";\nexport { requestTimeout } from \"./requestTimeout.js\";\n\nexport const indexError = (idx: number) => `No record found with index ${idx}`;\n", "import { invariant } from \"@olenbetong/appframe-core\";\n\nimport { IClient, getDefaultClient } from \"./Client.js\";\nimport { DataObject } from \"./DataObject.js\";\nimport { EventTarget } from \"./events.js\";\nimport { handleResponseError } from \"./utils/handleResponseError.js\";\n\ntype FileUploaderOptions =\n\t| {\n\t\t\tarticleId?: string;\n\t\t\tdataObject: DataObject;\n\t\t\tfieldName?: string;\n\t\t\tprimKey?: string;\n\t\t\troute?: undefined;\n\t\t\tclient?: IClient | null;\n\t  }\n\t| {\n\t\t\tarticleId?: undefined;\n\t\t\tdataObject: undefined;\n\t\t\tfieldName?: undefined;\n\t\t\tprimKey?: undefined;\n\t\t\troute: string;\n\t\t\tclient?: IClient | null;\n\t  };\n\nexport type FileUploaderEventToValueMap = {\n\tonBeforeUpload: null;\n\tonUploaded: null;\n\tonUploadFailed: { error: unknown };\n\tonProgress: {\n\t\tloaded: number;\n\t\ttotal: number;\n\t};\n};\n\nexport type FileUploaderEvent = keyof FileUploaderEventToValueMap;\n\nexport const FileUploaderEvents: Record = {\n\tonBeforeUpload: { abortable: true },\n\tonUploaded: { abortable: false },\n\tonUploadFailed: { abortable: false },\n\tonProgress: { abortable: false },\n};\n\nexport class FileUploader extends EventTarget {\n\tprivate articleId: string;\n\tprivate dataObject: DataObject | string | undefined;\n\tprivate fieldName: string | undefined;\n\tprivate primKey: string | undefined;\n\tprivate options: FileUploaderOptions;\n\tget client(): IClient {\n\t\treturn this.options.client ?? getDefaultClient();\n\t}\n\tset client(value: IClient | null) {\n\t\tthis.options.client = value;\n\t}\n\n\tconstructor(options: FileUploaderOptions) {\n\t\tsuper(FileUploaderEvents);\n\t\tthis.articleId = options.articleId ?? globalThis.af?.article?.id;\n\t\tthis.dataObject = options.dataObject;\n\t\tthis.fieldName = options.fieldName;\n\t\tthis.primKey = options.primKey;\n\t\tthis.options = { ...options };\n\t}\n\n\tprivate getDataSourceId() {\n\t\treturn typeof this.dataObject === \"string\" ? this.dataObject : this.dataObject?.getDataSourceId();\n\t}\n\n\tgetUploadUrl(): string {\n\t\tlet url = this.options.route ?? `/file/upload/${this.articleId}/${this.getDataSourceId()}`;\n\n\t\tif (this.fieldName) {\n\t\t\turl += \"/\" + this.fieldName;\n\t\t}\n\n\t\tif (this.primKey) {\n\t\t\turl += \"/\" + this.primKey;\n\t\t}\n\n\t\treturn url;\n\t}\n\n\tasync upload(fileOrBlob: File | Blob, fields?: Record, fileName?: string): Promise {\n\t\tthis.fireEvent(\"onBeforeUpload\", null);\n\n\t\tconst masterCriteria =\n\t\t\ttypeof this.dataObject === \"string\"\n\t\t\t\t? {}\n\t\t\t\t: (this.dataObject?.getParameter(\"masterChildCriteria\") as Record);\n\n\t\tif (fields?.[\"PrimKey\"]) {\n\t\t\tthis.primKey = fields.PrimKey;\n\t\t\tdelete fields.PrimKey;\n\t\t}\n\n\t\tconst allFields = {\n\t\t\t...masterCriteria,\n\t\t\t...fields,\n\t\t};\n\n\t\tif (globalThis.XMLHttpRequest) {\n\t\t\tconst data = new globalThis.FormData();\n\n\t\t\tfor (let [field, value] of Object.entries(allFields)) {\n\t\t\t\tdata.append(field, value);\n\t\t\t}\n\n\t\t\tdata.append(\n\t\t\t\tthis.fieldName ?? \"File\",\n\t\t\t\tfileOrBlob,\n\t\t\t\tfileOrBlob instanceof File ? fileOrBlob.name : fileName || \"file\",\n\t\t\t);\n\n\t\t\tconst reqPromise = new Promise((resolve, reject) => {\n\t\t\t\tconst request = new XMLHttpRequest();\n\n\t\t\t\trequest.upload.addEventListener(\"progress\", (evt) => {\n\t\t\t\t\tthis.fireEvent(\"onProgress\", {\n\t\t\t\t\t\tloaded: evt.loaded,\n\t\t\t\t\t\ttotal: evt.total,\n\t\t\t\t\t});\n\t\t\t\t});\n\n\t\t\t\trequest.addEventListener(\"readystatechange\", () => {\n\t\t\t\t\tif (request.readyState === 4) {\n\t\t\t\t\t\tif (request.status === 200) {\n\t\t\t\t\t\t\tthis.fireEvent(\"onUploaded\", null);\n\t\t\t\t\t\t\tresolve(request.response);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tconst result = JSON.parse(request.response);\n\n\t\t\t\t\t\t\t\tinvariant(!result.error, result.error);\n\t\t\t\t\t\t\t\tthrow Error(\"Upload failed: \" + request.status + \" \" + request.response);\n\t\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\t\tthis.fireEvent(\"onUploadFailed\", {\n\t\t\t\t\t\t\t\t\terror,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\treject(error);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\trequest.open(\"POST\", this.getUploadUrl());\n\t\t\t\trequest.setRequestHeader(\"Accept\", \"application/json\");\n\t\t\t\trequest.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n\t\t\t\trequest.send(data as FormData);\n\t\t\t});\n\t\t\treturn await reqPromise;\n\t\t} else {\n\t\t\ttry {\n\t\t\t\tconst nodeFetchModule = \"./node.js\";\n\t\t\t\tconst { FormData } = await import(/* @vite-ignore */ /* webpackIgnore: true */ nodeFetchModule);\n\t\t\t\tconst data = new FormData();\n\n\t\t\t\tfor (let [field, value] of Object.entries(allFields)) {\n\t\t\t\t\tdata.append(field, value);\n\t\t\t\t}\n\n\t\t\t\tdata.append(\n\t\t\t\t\tthis.fieldName ?? \"File\",\n\t\t\t\t\tfileOrBlob,\n\t\t\t\t\t(fileOrBlob as any)?.[\"name\"] ?? (fileOrBlob as any)?.[\"fileName\"] ?? \"file\",\n\t\t\t\t);\n\n\t\t\t\tlet url = this.getUploadUrl();\n\t\t\t\tlet response = await this.client.afFetch(url, {\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\theaders: {\n\t\t\t\t\t\tAccept: \"application/json\",\n\t\t\t\t\t},\n\t\t\t\t\tbody: data,\n\t\t\t\t\tisJson: false,\n\t\t\t\t});\n\n\t\t\t\tif (response.ok) {\n\t\t\t\t\tconst result = (await response.json()) as\n\t\t\t\t\t\t| { success: any; error: undefined }\n\t\t\t\t\t\t| { success: false; error?: any };\n\t\t\t\t\tinvariant(!result.error, result.error);\n\t\t\t\t} else {\n\t\t\t\t\tlet { message } = await handleResponseError(response);\n\t\t\t\t\tthrow Error(message);\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tthis.fireEvent(\"onUploadFailed\", { error });\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\t}\n}\n", "import { Handler } from \"mitt\";\n\nimport { RetrieveParameters } from \"./DataHandler.js\";\nimport { DataObject as IDataObject } from \"./DataObject.js\";\nimport { StorageArray, StorageRecord } from \"./Storage.js\";\nimport { EventTarget, ParameterUpdatedValue } from \"./events.js\";\n\ntype PartialDataLoadedCallbackValue = {\n\tskip: number;\n\tcount: number;\n\ttotal: number;\n\trefresh?: boolean;\n};\n\ntype PagingOptions> = {\n\tdataObject: IDataObject;\n};\n\nexport type PagingEvents = {\n\tbeforePageChange: { oldPage: number; newPage: number };\n\tpageChange: { oldPage: number; newPage: number };\n\tpageCountChange: { pageCount: number };\n\tpageRefresh: { page: number };\n\tbeforePageRefresh: { page: number };\n};\n\nexport type PagingEventsHandlers = { [K in keyof PagingEvents]: CustomEvent };\n\nexport type PagingEvent = keyof PagingEvents;\n\nconst PagingEvents: Record = {\n\tbeforePageChange: { abortable: true },\n\tbeforePageRefresh: { abortable: true },\n\tpageChange: { abortable: false },\n\tpageCountChange: { abortable: false },\n\tpageRefresh: { abortable: false },\n};\n\nexport class Paging> extends EventTarget {\n\tprivate currentData: StorageRecord[] | null = null;\n\tprivate currentPage = 0;\n\tprivate dataObject: IDataObject;\n\tprivate __loadedPages: Record = {};\n\tprivate options: PagingOptions;\n\tprivate pageCount: number;\n\tprivate pageSize: number;\n\tprivate total: number;\n\n\tconstructor(pOptions: PagingOptions) {\n\t\tsuper(PagingEvents);\n\t\tthis.options = { ...pOptions };\n\n\t\tthis.dataObject = this.options.dataObject;\n\t\tthis.pageSize = this.dataObject.getParameter(\"maxRecords\") ?? 50;\n\t\tthis.total = this.dataObject.getDataLength();\n\t\tthis.pageCount = this.pageSize === -1 ? 1 : Math.ceil(this.total / this.pageSize);\n\n\t\tthis.changePage = this.changePage.bind(this);\n\t\tthis.getPageCount = this.getPageCount.bind(this);\n\t\tthis.getCurrentData = this.getCurrentData.bind(this);\n\t\tthis.getCurrentPage = this.getCurrentPage.bind(this);\n\t\tthis.loadData = this.loadData.bind(this);\n\t\tthis.loadedPages = this.loadedPages.bind(this);\n\t\tthis.refreshPage = this.refreshPage.bind(this);\n\t\tthis.handlePartialDataLoaded = this.handlePartialDataLoaded.bind(this);\n\t\tthis.handleParameterUpdated = this.handleParameterUpdated.bind(this);\n\t\tthis.handleRecordDeleted = this.handleRecordDeleted.bind(this);\n\n\t\tthis.attachEvents();\n\n\t\tif (this.dataObject.isDataLoaded()) {\n\t\t\tthis.internalChangePage(null, 0);\n\t\t}\n\t}\n\n\tprivate updatePageCount() {\n\t\tvar pageCount = Math.ceil(this.total / this.pageSize);\n\t\tif (this.pageCount === pageCount) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.pageCount = pageCount;\n\t\tthis.fireEvent(\"pageCountChange\", { pageCount });\n\t}\n\n\tprivate internalChangePage(pOldPage: number | null, pNewPage: number) {\n\t\tlet data: StorageRecord[] = [];\n\t\tlet startIndex = pNewPage * this.pageSize;\n\t\tlet stopIndex = startIndex + this.pageSize;\n\n\t\tif (stopIndex > this.total) {\n\t\t\tstopIndex = this.total;\n\t\t}\n\t\tif (!Object.hasOwn(this.__loadedPages, pNewPage)) {\n\t\t\tthis.dataObject.retrievePartial(pNewPage * this.pageSize, this.pageSize);\n\t\t\tthis.__loadedPages[pNewPage] = false;\n\t\t\tthis.currentData = null;\n\t\t} else if (this.__loadedPages[pNewPage] === true) {\n\t\t\tfor (let i = startIndex; i < stopIndex; i++) {\n\t\t\t\tdata.push(this.dataObject.getData(i));\n\t\t\t}\n\n\t\t\tthis.currentData = data;\n\t\t} else {\n\t\t\tthis.currentData = null;\n\t\t}\n\n\t\tthis.currentPage = pNewPage;\n\n\t\tif (pOldPage !== null && this.__loadedPages[pOldPage] === false) {\n\t\t\tdelete this.__loadedPages[pOldPage];\n\t\t}\n\t}\n\n\tattach(eventName: K, handler: Handler) {\n\t\treturn this.attachEvent(eventName, handler);\n\t}\n\n\tdetach(eventName: K, handler: Handler) {\n\t\treturn this.detachEvent(eventName, handler);\n\t}\n\n\tasync changePage(pPage: number) {\n\t\tif (this.dataObject.isDirty()) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.dataObject.getCurrentIndex() === -1) {\n\t\t\ttry {\n\t\t\t\tawait this.dataObject.endEdit();\n\t\t\t} catch (_) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tif (this.currentPage !== pPage) {\n\t\t\tlet args = { oldPage: this.currentPage, newPage: pPage };\n\t\t\tlet result = this.fireEvent(\"beforePageChange\", args);\n\n\t\t\tif (!result) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tthis.internalChangePage(args.oldPage, args.newPage);\n\t\t\tthis.fireEvent(\"pageChange\", args);\n\t\t}\n\n\t\t/*remove new records*/\n\t\tif (this.currentPage > 0 && (this.dataObject.isUpdateAllowed() || this.dataObject.isInsertAllowed())) {\n\t\t\tconst data = this.dataObject.getData();\n\n\t\t\tdata.forEach((item, index) => {\n\t\t\t\tif (this.dataObject.isDirty(index) && this.dataObject.isNewRecord(index)) {\n\t\t\t\t\tthis.dataObject.deleteRow(index);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tlet pageSize = this.dataObject.getParameter(\"maxRecords\") ?? 50;\n\t\tif (\n\t\t\tthis.dataObject.getDataLength() > 0 &&\n\t\t\tMath.floor(this.currentPage * pageSize) !== this.dataObject.getCurrentIndex() &&\n\t\t\tthis.dataObject.getCurrentIndex() !== -1\n\t\t) {\n\t\t\tthis.dataObject.setCurrentIndex(this.currentPage * pageSize);\n\t\t}\n\t}\n\n\trefreshPage() {\n\t\tlet eventData = { page: this.currentPage };\n\t\tlet result = this.fireEvent(\"beforePageRefresh\", eventData);\n\n\t\tif (!result) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.currentData = [];\n\n\t\tconst startIndex = this.currentPage * this.pageSize;\n\t\tlet stopIndex = startIndex + this.pageSize;\n\t\tif (stopIndex > this.total) {\n\t\t\tstopIndex = this.total;\n\t\t}\n\n\t\tfor (let i = startIndex; i < stopIndex; i++) {\n\t\t\tthis.currentData.push(this.dataObject.getData(i));\n\t\t}\n\n\t\tthis.fireEvent(\"pageRefresh\", eventData);\n\n\t\tlet currentIndex = this.dataObject.getCurrentIndex();\n\t\tlet pageSize = this.dataObject.getParameter(\"maxRecords\") ?? 50;\n\t\tif (this.dataObject.getDataLength() > 0 && currentIndex !== -1 && pageSize >= 0) {\n\t\t\tlet firstRecord = this.currentPage * pageSize;\n\t\t\tlet nextPage = (this.currentPage + 1) * pageSize;\n\t\t\tif (currentIndex < firstRecord || currentIndex >= nextPage) {\n\t\t\t\tthis.dataObject.setCurrentIndex(this.currentPage * pageSize);\n\t\t\t}\n\t\t}\n\t}\n\n\tgetPageCount() {\n\t\treturn this.pageCount;\n\t}\n\n\tgetCurrentPage() {\n\t\treturn this.currentPage;\n\t}\n\n\tgetCurrentData(): StorageArray | null {\n\t\treturn this.currentData;\n\t}\n\n\tprivate handlePartialDataLoaded(event?: CustomEventInit) {\n\t\tif (!event) return;\n\n\t\tlet data = event.detail;\n\n\t\tif (!data) return;\n\n\t\tconst correctSkip = data.skip % this.pageSize === 0;\n\t\tconst loadedPage = data.skip / this.pageSize;\n\n\t\tif (data.skip === 0) {\n\t\t\tthis.total = data.count;\n\t\t}\n\n\t\tif (correctSkip) {\n\t\t\tif (data.skip === 0) {\n\t\t\t\tthis.__loadedPages = {};\n\t\t\t}\n\n\t\t\tthis.__loadedPages[loadedPage] = true;\n\n\t\t\tif (this.currentPage === loadedPage) {\n\t\t\t\tthis.refreshPage();\n\t\t\t}\n\t\t} else {\n\t\t\tconsole.warn(\"Incorrect skip parameter received from partial data event\");\n\t\t}\n\t}\n\n\tprivate handleParameterUpdated>(\n\t\tevent?: CustomEventInit>,\n\t) {\n\t\tif (!event) return;\n\n\t\tlet { detail: param } = event;\n\t\tlet lastPage = 0;\n\t\tif (param?.name === \"maxRecords\") {\n\t\t\tlet newPageSize = param[\"value\"] || 25;\n\t\t\tif (this.pageSize !== newPageSize) {\n\t\t\t\tthis.pageSize = newPageSize;\n\n\t\t\t\tif (!this.dataObject.isDataLoaded()) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tthis.updatePageCount();\n\n\t\t\t\tif (this.currentPage >= this.total / this.pageSize) {\n\t\t\t\t\tif (this.pageSize > 0) {\n\t\t\t\t\t\tlastPage = this.total / this.pageSize;\n\t\t\t\t\t\tif (lastPage > 0) {\n\t\t\t\t\t\t\tlastPage = Math.ceil(lastPage) - 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.changePage(lastPage);\n\t\t\t\t} else {\n\t\t\t\t\tthis.__loadedPages = {};\n\t\t\t\t\tthis.internalChangePage(this.currentPage, this.currentPage);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate attachEvents() {\n\t\tthis.dataObject.attachEvent(\"onPartialDataLoaded\", this.handlePartialDataLoaded);\n\t\tthis.dataObject.attachEvent(\"onParameterUpdated\", this.handleParameterUpdated);\n\t\tthis.dataObject.attachEvent(\"onRecordDeleted\", this.handleRecordDeleted);\n\t\tthis.dataObject.attachEvent(\"onRowCountLoaded\", this.handleRowCountLoaded);\n\t\tthis.dataObject.attachEvent(\"onRecordRefreshed\", this.refreshPage);\n\t\tthis.dataObject.attachEvent(\"onRecordCreated\", () => {\n\t\t\tthis.total++;\n\t\t});\n\t}\n\n\tprivate handleRecordDeleted() {\n\t\tlet prevCount = this.pageCount;\n\t\tlet lastPage = 0;\n\n\t\tthis.total--;\n\t\tthis.updatePageCount();\n\n\t\tif (this.currentPage >= this.total / this.pageSize) {\n\t\t\tif (this.pageSize > 0) {\n\t\t\t\tlastPage = this.total / this.pageSize;\n\t\t\t\tif (lastPage > 0) {\n\t\t\t\t\tlastPage = Math.ceil(lastPage) - 1;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.refreshPage();\n\t\t} else if (this.pageCount !== prevCount || this.currentPage < this.pageCount - 1) {\n\t\t\tif (Object.hasOwn(this.__loadedPages, this.currentPage + 1)) {\n\t\t\t\tthis.refreshPage();\n\t\t\t} else {\n\t\t\t\tdelete this.__loadedPages[this.currentPage];\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate handleRowCountLoaded = (event?: CustomEvent<{ count: number; total: number; skip: number }>) => {\n\t\tif (!event) return;\n\n\t\tconst data = event.detail;\n\t\tthis.total = data.total;\n\t\tthis.updatePageCount();\n\n\t\tlet correctSkip = data.skip % this.pageSize === 0;\n\t\tlet loadedPage = data.skip / this.pageSize;\n\n\t\tif (correctSkip) {\n\t\t\tif (data.skip === 0) {\n\t\t\t\tthis.__loadedPages = {};\n\t\t\t}\n\t\t\tthis.__loadedPages[loadedPage] = true;\n\t\t\tif (this.currentPage === loadedPage) {\n\t\t\t\tthis.refreshPage();\n\t\t\t} else if (this.currentPage === null && loadedPage === 0) {\n\t\t\t\tthis.changePage(0);\n\t\t\t} else if (this.currentPage > 0 && data.skip === 0) {\n\t\t\t\tthis.changePage(0);\n\t\t\t} else if (data.skip === 0) {\n\t\t\t\tif (this.currentPage === 0) {\n\t\t\t\t\tthis.refreshPage();\n\t\t\t\t} else if (this.currentPage < this.pageCount) {\n\t\t\t\t\tthis.internalChangePage(null, this.currentPage);\n\t\t\t\t} else {\n\t\t\t\t\tthis.changePage(Math.max(0, this.pageCount - 1));\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tconsole.warn(\"Incorrect skip parameter received from partial data event\");\n\t\t}\n\t};\n\n\tloadData(forceLoad: boolean) {\n\t\tif (this.dataObject.isDataLoaded() && forceLoad === false) {\n\t\t\tthis.internalChangePage(null, 0);\n\t\t} else if (!this.dataObject.isDataLoading() || forceLoad === true) {\n\t\t\tthis.dataObject.retrievePartial(0, this.pageSize);\n\t\t}\n\t}\n\n\tloadedPages() {\n\t\treturn this.__loadedPages;\n\t}\n}\n", "import { FilterObject, SortOrder } from \"./DataHandler.js\";\nimport { DataObject } from \"./DataObject.js\";\n\nexport class RecordSource> {\n\tprivate dataObject: DataObject;\n\tconstructor(dataObject: DataObject) {\n\t\tthis.dataObject = dataObject;\n\t}\n\n\tgetMaxRecords = () => this.dataObject.getParameter(\"maxRecords\");\n\tgetSortOrder = () => this.dataObject.getParameter(\"sortOrder\");\n\tgetFilterString = () => this.dataObject.getParameter(\"filterString\");\n\tgetFilterObject = () => this.dataObject.getParameter(\"filterObject\");\n\tgetWhereClause = () => this.dataObject.getParameter(\"whereClause\");\n\tgetWhereObject = () => this.dataObject.getParameter(\"whereObject\");\n\tsetMaxRecords = (value: number) => this.dataObject.setParameter(\"maxRecords\", value);\n\tsetSortOrder = (value: Record[]) => this.dataObject.setParameter(\"sortOrder\", value);\n\tsetFilterString = (value: string) => this.dataObject.setParameter(\"filterString\", value);\n\tsetFilterObject = (value: FilterObject | null) => this.dataObject.setParameter(\"filterObject\", value);\n\tsetWhereClause = (value: string) => this.dataObject.setParameter(\"whereClause\", value);\n\tsetWhereObject = (value: FilterObject | null) => this.dataObject.setParameter(\"whereObject\", value);\n}\n", "import { invariant } from \"@olenbetong/appframe-core\";\n\nimport { FieldDefinition } from \"./fields.js\";\nimport { indexError } from \"./utils/index.js\";\n\nexport const uid: unique symbol = Symbol(\"uid\");\n\n/**\n * Storage engine used to store data object data on the client\n */\nexport interface Storage {\n\tcreate(record: T[]): number;\n\tcreate(record: T | null | undefined, uid?: number | string): number;\n\tdestroy: (index?: number) => boolean;\n\tgetNewUid: () => string | number;\n\tnewRow(uid?: string | number): StorageRecord;\n\tlength: number;\n\tretrieve(): StorageArray;\n\tretrieve(index: number): StorageRecord;\n\tretrieve(index: number, field: F): T[F] | null;\n\tupdate: (index: number, data: T) => boolean;\n}\n\nexport type Nullable = { [K in keyof T]: T[K] | null };\nexport type StorageRecord = Readonly & { [uid]: number | string }>;\nexport type StorageArray = Readonly>>;\n\nexport class MemoryStorage implements Storage {\n\t#data: StorageArray = [];\n\t#nextUID: number = Date.now() - 1650000000000;\n\t#fields: FieldDefinition[];\n\n\tconstructor(fields: FieldDefinition[]) {\n\t\tthis.#fields = fields;\n\t}\n\n\tprotected fillRow = (row: Partial | null, recordUid: number | string) => {\n\t\tlet record = (row === null ? { [uid]: recordUid } : { [uid]: recordUid, ...row }) as Partial>;\n\t\tfor (let field of this.#fields) {\n\t\t\tif (!Object.hasOwn(record, field.name)) {\n\t\t\t\t(record as Nullable)[field.name as keyof T] = null;\n\t\t\t}\n\t\t}\n\n\t\treturn record as Readonly>;\n\t};\n\n\tnewRow(rowUid?: string | number) {\n\t\treturn this.fillRow({}, rowUid ?? this.getNewUid());\n\t}\n\n\tcreate(record: T[]): number;\n\tcreate(record: T | null | undefined, uid?: number | string): number;\n\tcreate(data: T[] | T | null | undefined, recordUid?: number | string) {\n\t\tif (Array.isArray(data)) {\n\t\t\tlet newData: StorageRecord[] = new Array(data.length);\n\t\t\tfor (let i = 0; i < data.length; i++) {\n\t\t\t\tnewData[i] = this.fillRow(data[i], (data[i] as any)[\"PrimKey\"] ?? this.getNewUid());\n\t\t\t}\n\n\t\t\tthis.#data = newData;\n\t\t} else {\n\t\t\tlet nextUid = recordUid ?? this.getNewUid();\n\t\t\tlet newData = this.#data.slice();\n\t\t\tnewData.push(this.fillRow(data ?? {}, nextUid));\n\t\t\tthis.#data = newData;\n\t\t}\n\n\t\treturn this.#data.length - 1;\n\t}\n\n\tgetNewUid() {\n\t\treturn this.#nextUID++;\n\t}\n\n\tretrieve(): StorageArray;\n\tretrieve(index: number): StorageRecord;\n\tretrieve(idx: number, field: F): StorageRecord[F] | null;\n\tretrieve(idx?: number, field?: F): StorageArray | StorageRecord | T[F] | null {\n\t\tif (idx == undefined) {\n\t\t\treturn this.#data;\n\t\t}\n\n\t\tinvariant(idx >= 0 && idx < this.#data.length, indexError(idx));\n\n\t\tlet record = this.#data[idx];\n\t\tif (field) {\n\t\t\treturn (record as T)?.[field] ?? null;\n\t\t}\n\n\t\treturn record;\n\t}\n\n\tupdate(idx: number, data: T) {\n\t\tconst current = this.#data[idx];\n\t\tinvariant(idx >= 0 && idx < this.#data.length && current, indexError(idx));\n\n\t\tconst row = this.fillRow(data, current?.[uid] ?? this.getNewUid());\n\t\tthis.#data = this.#data.map((r, index) => (index === idx ? row : r));\n\n\t\treturn true;\n\t}\n\n\tdestroy(idx?: number) {\n\t\tif (idx === undefined || idx === null) {\n\t\t\tthis.#data = [];\n\t\t\treturn true;\n\t\t}\n\n\t\tinvariant(idx >= 0 && idx < this.#data.length && this.#data[idx] !== undefined, indexError(idx));\n\n\t\tthis.#data = this.#data.filter((_, index) => index !== idx);\n\n\t\treturn true;\n\t}\n\n\tget length() {\n\t\treturn this.#data.length;\n\t}\n\n\tset length(newLength: number) {\n\t\tif (newLength > this.#data.length) {\n\t\t\tlet newData = this.#data.slice();\n\t\t\tfor (let i = 0; i < newLength - this.length; i++) {\n\t\t\t\tnewData.push(this.fillRow({}, this.getNewUid()));\n\t\t\t}\n\n\t\t\tthis.#data = newData; // Object.freeze(newData);\n\t\t} else if (newLength < this.#data.length) {\n\t\t\tthis.#data = this.#data.slice(0, newLength);\n\t\t}\n\t}\n}\n", "import { uid } from \"../Storage.js\";\n\n/**\n * Clone any object and it's properties recursively.\n * Not a true deep clone, but only created to be able to clone\n * data object records and parameters.\n *\n * @param {T} object - Object to clone\n * @returns {T} Clone of object\n */\nexport default function naiveDeepClone(object: T): T {\n\tlet objUid: any;\n\tif (typeof object === \"object\" && object) {\n\t\tobjUid = (object as any)[uid];\n\t}\n\n\tif (globalThis.structuredClone) {\n\t\tlet cloned = globalThis.structuredClone(object);\n\t\tif (objUid) (cloned as any)[uid] = objUid;\n\t\treturn cloned;\n\t}\n\n\tif (object instanceof Date) {\n\t\treturn new Date(object.getTime()) as unknown as T;\n\t} else if (object == null) {\n\t\treturn object;\n\t} else if (Array.isArray(object)) {\n\t\treturn object.map(naiveDeepClone) as unknown as T;\n\t} else if (typeof object === \"object\") {\n\t\tlet newObject = {} as any;\n\t\tfor (let key of Object.keys(object)) {\n\t\t\tnewObject[key] = naiveDeepClone((object as any)[key]);\n\t\t}\n\n\t\tif (objUid) newObject[uid] = objUid;\n\n\t\treturn newObject as T;\n\t}\n\n\treturn object;\n}\n", "import { IClient, getDefaultClient } from \"./Client.js\";\nimport { EventTarget } from \"./events.js\";\nimport { handleResponseError } from \"./utils/handleResponseError.js\";\n\nconst isodate = /^(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})(?:\\.(\\d{1,7}))?Z?$/;\nfunction dateReviver(value: any) {\n\t// New method of parsing dates - much faster\n\tif (typeof value === \"string\") {\n\t\tif (value.includes(\"/Date(\")) {\n\t\t\tvalue = new Date(Number(value.substring(6, value.length - 2)));\n\t\t} else if (isodate.test(value)) {\n\t\t\tvalue = new Date(value);\n\t\t}\n\t}\n\treturn value;\n}\n\nfunction reviveTable(table: any) {\n\tif (Array.isArray(table)) {\n\t\tfor (let j = 0; j < table.length; j++) {\n\t\t\tlet record = table[j];\n\t\t\tlet keys = Object.keys(record);\n\t\t\tfor (let key of keys) {\n\t\t\t\trecord[key] = dateReviver(record[key]);\n\t\t\t}\n\t\t}\n\t}\n}\n\nexport type ProcedureParameter = {\n\tcaption?: string;\n\thasDefault?: boolean;\n\tmaxLength?: number;\n\tname: string;\n\trequired?: boolean;\n\ttype?: string;\n};\n\nexport type ProcedureOptions = {\n\tarticleId?: string;\n\tparameters?: Array;\n\tprocedureId: string;\n\ttimeout?: number;\n\tworkingText?: string | null;\n\tclient?: IClient | null;\n\ttransaction?: boolean;\n};\n\nexport type ProcedureEvent = {\n\tonBeforeExecute: any;\n\tonSuccess: any;\n\tonError: any;\n\tonComplete: any;\n\tonCancel: any;\n};\n\nexport type ProcedureEventParams = { [K in keyof ProcedureEvent]: CustomEvent };\n\nexport abstract class ProcedureBase extends EventTarget {\n\treadonly version = __VERSION__;\n\treadonly options: Readonly>;\n\tprivate values: Partial;\n\t#client: IClient | null = null;\n\tget client(): IClient {\n\t\treturn this.#client ?? this.options.client ?? getDefaultClient();\n\t}\n\tset client(value: IClient | null) {\n\t\tthis.#client = value;\n\t}\n\tparameterNames: Array;\n\n\tconstructor(options: ProcedureOptions) {\n\t\tsuper({\n\t\t\tonBeforeExecute: { abortable: true },\n\t\t\tonSuccess: { abortable: false },\n\t\t\tonError: { abortable: false },\n\t\t\tonComplete: { abortable: false },\n\t\t\tonCancel: { abortable: false },\n\t\t});\n\n\t\tthis.options = {\n\t\t\tarticleId: globalThis.af?.article?.id,\n\t\t\tparameters: [],\n\t\t\ttimeout: 0,\n\t\t\tworkingText: null,\n\t\t\tclient: null,\n\t\t\ttransaction: true,\n\t\t\t...options,\n\t\t};\n\n\t\tthis.parameterNames = this.options.parameters.map((p) => p.name.toLowerCase());\n\t\tthis.values = {};\n\t}\n\n\tprotected abstract getRequestUrl(): string;\n\tprotected abstract getRequestBody(params?: TParams): any;\n\n\t/**\n\t * Executes the stored procedure using the supplied parameters\n\t * @param {TParams} parameters The parameters to execute the procedure with\n\t * @returns {Promise}\n\t */\n\tasync execute(parameters?: TParams): Promise {\n\t\tconst controller = new AbortController();\n\n\t\tconst response = await this.client.afFetch(this.getRequestUrl(), {\n\t\t\tbody: JSON.stringify(this.getRequestBody(parameters)),\n\t\t\tsignal: controller.signal,\n\t\t\ttimeout: this.options.timeout,\n\t\t\tmode: \"cors\",\n\t\t\tcredentials: \"include\",\n\t\t});\n\n\t\tif (response.ok && response.headers.get(\"Content-Type\")?.includes(\"application/json\")) {\n\t\t\tlet data = await response.json();\n\t\t\tif (Object.hasOwn(data, \"success\")) {\n\t\t\t\tfor (let key in data.success) {\n\t\t\t\t\treviveTable(data.success[key]);\n\t\t\t\t}\n\n\t\t\t\tthis.fireEvent(\"onSuccess\", data.success as TResult);\n\t\t\t\tthis.fireEvent(\"onComplete\");\n\n\t\t\t\treturn data.success as TResult;\n\t\t\t}\n\t\t}\n\n\t\tconst responseError = await handleResponseError(response);\n\n\t\tif (responseError.canRetry) {\n\t\t\treturn await this.execute(parameters);\n\t\t}\n\n\t\tthis.fireEvent(\"onError\", responseError.message);\n\t\tthrow new Error(responseError.message);\n\t}\n\n\t/**\n\t * Executes the procedure using the parameters stored in the procedure\n\t * instance.\n\t *\n\t * The execution can be stopped in the onBeforeExecute event.\n\t * @returns {Promise} Data returned from the stored procedure\n\t */\n\tasync execute2() {\n\t\tif (this.fireEvent(\"onBeforeExecute\", this.values) !== false) {\n\t\t\treturn await this.execute(this.values as TParams);\n\t\t}\n\t}\n\n\t/**\n\t * Get the currently stored value for a parameter\n\t * @param {K | string} name Name of the parameter to get\n\t */\n\tparameterValue(name: K | string): TParams[K] | undefined;\n\t/**\n\t * Set the internal value for a parameter. This parameter is used\n\t * when executing the procedure using execute2\n\t * @param {K} name Name of the parameter to set\n\t * @param {TParams[K]} value Parameter value\n\t */\n\tparameterValue(name: K, value: TParams[K]): void;\n\tparameterValue(name: K | string, value?: TParams[K]): TParams[K] | undefined {\n\t\tif (name && value) {\n\t\t\tthis.values[name as K] = value;\n\t\t}\n\n\t\treturn this.values[name as K];\n\t}\n\n\t/**\n\t * Returns the parameter values currently stored in the procedure\n\t * instance.\n\t * @returns {Partial} Parameter values\n\t */\n\tgetValues(): Partial {\n\t\treturn this.values;\n\t}\n\n\t/**\n\t * Returns the parameter definitions for the procedure\n\t * @returns {ProcedureParameter[]}\n\t */\n\tgetParameters() {\n\t\treturn [...this.options.parameters];\n\t}\n\n\t/**\n\t * Clears the internal parameter values and fires an onCancel\n\t * event.\n\t *\n\t * NB! Does not cancel an execution that has already been started.\n\t */\n\tcancelExecute() {\n\t\tthis.values = {};\n\t\tthis.fireEvent(\"onCancel\");\n\t}\n\n\t/**\n\t * Checks if any of the procedure parameters are marked as required.\n\t * @returns {boolean} True if any of the parameters are required\n\t */\n\thasRequiredParameters(): boolean {\n\t\tconst { parameters } = this.options;\n\t\tfor (let i = 0; i < parameters.length; i++) {\n\t\t\tif (parameters[i].required) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n}\n\nexport class Procedure extends ProcedureBase {\n\tconstructor(options: ProcedureOptions) {\n\t\tsuper(options);\n\t}\n\n\tprotected getRequestUrl() {\n\t\treturn `/exec/${this.options.articleId}/${this.options.procedureId}`;\n\t}\n\n\tprotected getRequestBody(parameters?: TParams) {\n\t\treturn parameters ?? ({} as TParams);\n\t}\n}\n\nexport class ProcedureAPI extends ProcedureBase {\n\tconstructor(options: ProcedureOptions) {\n\t\tsuper(options);\n\t}\n\n\tprotected getRequestUrl() {\n\t\treturn `/api/data`;\n\t}\n\n\tprotected getRequestBody(parameters?: TParams) {\n\t\tparameters = parameters ?? ({} as TParams);\n\n\t\treturn {\n\t\t\toperation: \"execute\",\n\t\t\tresourceName: this.options.procedureId,\n\t\t\texcludeFieldNames: false,\n\t\t\ttimeout: this.options.timeout,\n\t\t\ttransaction: this.options.transaction,\n\t\t\t...parameters,\n\t\t};\n\t}\n}\n", "import { invariant } from \"@olenbetong/appframe-core\";\n\nimport { IClient, LoginOptions, setDefaultClient } from \"../Client.js\";\nimport { requestTimeout } from \"../utils/index.js\";\n\nexport class Client implements IClient {\n\tprivate __hostname: string = \"\";\n\tget hostname() {\n\t\treturn this.__hostname;\n\t}\n\n\tconstructor(hostname?: string) {\n\t\tthis.setHostname(hostname);\n\t}\n\n\tgetRequestUrl(path: string) {\n\t\tlet newHost = this.__hostname;\n\n\t\tif (!this.__hostname && typeof window == \"undefined\") {\n\t\t\t// We are running in a browser environment, so hostname is not necessary.\n\t\t\treturn path;\n\t\t}\n\n\t\tif (path.startsWith(\"http\")) {\n\t\t\treturn path;\n\t\t}\n\n\t\tlet newPath = path;\n\t\tif (newPath.startsWith(\"/\")) {\n\t\t\tnewPath = newPath.substring(1, newPath.length);\n\t\t}\n\n\t\treturn [newHost, newPath].join(\"/\");\n\t}\n\n\t/**\n\t * Wraps fetch and adds JSON headers (Accept and Content-Type) and X-Requested-With\n\t * which is required by some handlers. If timeout is set in `init`, the request will\n\t * be aborted if not finished by the amount of milliseconds set.\n\t *\n\t * If Content-Type should not be JSON, either pass in another Content-Type, or set\n\t * isJson to false in `init`\n\t */\n\tasync afFetch(url: string, init: RequestInit & { timeout?: number; isJson?: boolean }): Promise {\n\t\tlet requestInit = Object.assign({}, init);\n\t\tlet { timeout = 0, isJson = true } = init;\n\t\tlet controller = new AbortController();\n\n\t\tdelete requestInit.timeout;\n\t\tdelete requestInit.isJson;\n\n\t\tif (requestInit.signal) {\n\t\t\trequestInit.signal.addEventListener(\"abort\", () => {\n\t\t\t\tcontroller.abort();\n\t\t\t});\n\t\t} else {\n\t\t\trequestInit.signal = controller.signal;\n\t\t}\n\n\t\tif (!requestInit.method) {\n\t\t\trequestInit.method = \"POST\";\n\t\t}\n\n\t\tlet afHeaders: HeadersInit = {\n\t\t\tAccept: (init?.headers as any)?.[\"Accept\"] ?? \"application/json, text/javascript, */*; q=0.01\",\n\t\t\t\"X-Requested-With\": \"XMLHttpRequest\",\n\t\t};\n\n\t\tif (isJson) {\n\t\t\tafHeaders[\"Content-Type\"] = (init?.headers as any)?.[\"Content-Type\"] ?? \"application/json; charset=utf-8\";\n\t\t}\n\n\t\trequestInit.headers = new Headers({ ...requestInit.headers, ...afHeaders });\n\n\t\tlet cancelTimeout = controller && timeout > 0 ? requestTimeout(controller, timeout) : () => null;\n\n\t\tlet response = await this.fetch(url, requestInit);\n\t\tcancelTimeout();\n\n\t\tif (controller?.signal?.aborted) {\n\t\t\tthrow new DOMException(\"Request has been aborted\", \"AbortError\");\n\t\t}\n\n\t\treturn response;\n\t}\n\n\tasync fetch(input: any, init: any = {}) {\n\t\tlet url = typeof input === \"string\" ? input : input.url;\n\t\turl = this.getRequestUrl(url);\n\n\t\tinvariant(\n\t\t\turl.startsWith(\"http\") || typeof window !== \"undefined\",\n\t\t\t\"Hostname has not been set in NodeFetch. Use setDefaultClient() to configure a default client with hostname.\",\n\t\t);\n\n\t\tif (url.startsWith(\"http\")) {\n\t\t\tinit.credentials = \"include\";\n\t\t\tinit.mode = \"cors\";\n\t\t}\n\n\t\tif (typeof input === \"string\") {\n\t\t\tinput = url;\n\t\t} else {\n\t\t\tinput = new Request(url, input);\n\t\t}\n\n\t\treturn await fetch(input, init);\n\t}\n\n\tasync login(username: string, password: string, options?: LoginOptions) {\n\t\tlet response = await this.afFetch(\"/login\", {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\tAccept: \"application/json\",\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t},\n\t\t\tbody: JSON.stringify({\n\t\t\t\tusername,\n\t\t\t\tpassword,\n\t\t\t\tremember: options?.remember ?? false,\n\t\t\t}),\n\t\t});\n\n\t\tif (response.ok) {\n\t\t\tlet json = await response.json();\n\t\t\tif (json.success) {\n\t\t\t\treturn json.success;\n\t\t\t} else if (json.error) {\n\t\t\t\tthrow Error(json.error);\n\t\t\t}\n\t\t\treturn true;\n\t\t} else {\n\t\t\tthrow Error(`Login failed: ${response.status} ${response.statusText}`);\n\t\t}\n\t}\n\n\tsetHostname(hostname?: string) {\n\t\tif (hostname) {\n\t\t\tif (!hostname.startsWith(\"http\")) {\n\t\t\t\thostname = \"https://\" + hostname;\n\t\t\t}\n\n\t\t\tif (hostname.endsWith(\"/\")) {\n\t\t\t\thostname = hostname.substring(0, hostname.length - 1);\n\t\t\t}\n\n\t\t\tthis.__hostname = hostname;\n\t\t}\n\t}\n}\n\n// For unknown reasons, Vite still loads this file even if it doesn't use it, and so we\n// still need to make sure window exists before setting a default client.\nif (typeof window !== \"undefined\") {\n\tsetDefaultClient(new Client());\n}\n", "import { IClient } from \"./Client.js\";\nimport { DataProviderHandlerAPI } from \"./DataHandler.js\";\nimport { DataObject, DataObjectOptions } from \"./DataObject.js\";\nimport { FieldDefinition } from \"./fields.js\";\nimport { getFields } from \"./utils/index.js\";\n\nexport type GenerateApiDataObjectOptions> = Omit<\n\tPartial>,\n\t\"fields\"\n> & {\n\tid: string;\n\tdynamicLoading?: boolean;\n\tfields: Array;\n\ttimeout?: number;\n\tclient?: IClient;\n\tresource: string;\n\tuniqueName?: string;\n};\n\nexport type GenerateApiDataHandlerOptions> = Pick<\n\tGenerateApiDataObjectOptions,\n\t\"resource\" | \"groupBy\" | \"timeout\" | \"fields\" | \"client\" | \"uniqueName\"\n>;\n\nexport function generateApiDataHandler>({\n\tresource,\n\ttimeout,\n\tfields,\n\tclient,\n\tgroupBy,\n\tuniqueName,\n}: GenerateApiDataHandlerOptions): DataProviderHandlerAPI {\n\tif (groupBy && !Array.isArray(groupBy)) {\n\t\tgroupBy = [String(groupBy)];\n\t}\n\n\treturn new DataProviderHandlerAPI({\n\t\tdataSourceId: resource,\n\t\ttimeout,\n\t\tfields,\n\t\tclient,\n\t\tgroupBy: groupBy as string[],\n\t\tuniqueName,\n\t});\n}\n\nexport function generateApiDataObject>(options: GenerateApiDataObjectOptions) {\n\tlet { client, dynamicLoading = false, id, timeout, resource, fields, groupBy, uniqueName } = options;\n\tif (groupBy && !Array.isArray(groupBy)) {\n\t\tgroupBy = [String(groupBy)];\n\t}\n\n\tlet dataHandler = generateApiDataHandler({\n\t\tresource,\n\t\ttimeout,\n\t\tfields,\n\t\tclient,\n\t\tgroupBy,\n\t\tuniqueName,\n\t});\n\n\tlet dataObject = new DataObject(\n\t\tObject.assign(options, {\n\t\t\tdataSourceId: id,\n\t\t\tdataHandler,\n\t\t\tfields: getFields(fields),\n\t\t\tdynamicLoading: dynamicLoading === true ? true : false,\n\t\t}),\n\t);\n\n\treturn dataObject;\n}\n", "// This file is the entry point for browser bundles\nimport { getDefaultClient, setDefaultClient } from \"../Client.js\";\nimport { DataHandler, DataProviderHandler, DataProviderHandlerAPI, SortOrder } from \"../DataHandler.js\";\nimport { DataObject } from \"../DataObject.js\";\nimport { FileUploader } from \"../FileUploader.js\";\nimport { Paging } from \"../Paging.js\";\nimport { Procedure, ProcedureAPI } from \"../Procedure.js\";\nimport { MemoryStorage, uid } from \"../Storage.js\";\nimport { Client } from \"../browser/Client.js\";\nimport { generateApiDataHandler, generateApiDataObject } from \"../generateApiDataObject.js\";\n\nexport {\n\tClient,\n\tDataObject,\n\tDataHandler,\n\tDataProviderHandlerAPI,\n\tDataProviderHandler,\n\tFileUploader,\n\tgenerateApiDataHandler,\n\tgenerateApiDataObject,\n\tgetDefaultClient,\n\tsetDefaultClient,\n\tMemoryStorage,\n\tPaging,\n\tProcedure,\n\tProcedureAPI,\n\tSortOrder,\n\tuid,\n};\n\nexport const version = __VERSION__;\n"],
  "mappings": "mpBAAA,IAAAA,EAAAC,GAAA,CAAAC,GAAAC,KAAA,CAAAA,GAAO,QAAU,GAAG,SCApB,IAAAC,GAAA,GAAAC,GAAAD,GAAA,YAAAE,EAAA,gBAAAC,EAAA,eAAAC,EAAA,wBAAAC,EAAA,2BAAAC,EAAA,iBAAAC,EAAA,kBAAAC,EAAA,WAAAC,EAAA,cAAAC,EAAA,iBAAAC,EAAA,cAAAC,GAAA,2BAAAC,GAAA,0BAAAC,GAAA,qBAAAC,EAAA,qBAAAC,EAAA,QAAAC,EAAA,YAAAC,KCAA,IAAAC,EAAwD,SCAxD,IAAAC,GAA0B,SCA1B,IAAAC,GAA0B,SAuBtBC,EAEG,SAASC,GAAmB,CAClC,uBAAUD,EAAe,gCAAgC,EAClDA,CACR,CAEO,SAASE,EAAiBC,EAAiB,CACjDH,EAAgBG,CACjB,CChCO,IAAMC,EAAuB,CAACC,EAAYC,IAChD,GAAGD,CAAE,uCAAuCC,CAAK,iCC6CjDC,EAAAA,CAOA,MAAO,CAINA,IANDA,EAAMA,GAAO,IAAIC,IAchBC,GAAAA,SAA6BC,EAAWC,EAAAA,CACvC,IAAMC,EAAmDL,EAAKM,IAAIH,CAAAA,EAC9DE,EACHA,EAASE,KAAKH,CAAAA,EAEdJ,EAAKQ,IAAIL,EAAM,CAACC,CAAAA,CAAAA,CAAAA,EAWlBK,IAAAA,SAA8BN,EAAWC,EAAAA,CACxC,IAAMC,EAAmDL,EAAKM,IAAIH,CAAAA,EAC9DE,IACCD,EACHC,EAASK,OAAOL,EAASM,QAAQP,CAAAA,IAAa,EAAG,CAAA,EAEjDJ,EAAKQ,IAAIL,EAAM,CAAA,CAAA,EAAA,EAelBS,KAAAA,SAA+BT,EAAWU,EAAAA,CACzC,IAAIR,EAAWL,EAAKM,IAAIH,CAAAA,EACpBE,GACFA,EACCS,MAAAA,EACAC,IAAI,SAACX,EAAAA,CACLA,EAAQS,CAAAA,CAAAA,CAAAA,GAIXR,EAAWL,EAAKM,IAAI,GAAA,IAElBD,EACCS,MAAAA,EACAC,IAAI,SAACX,EAAAA,CACLA,EAAQD,EAAMU,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CC7Db,IAAMG,GAAoE,CAChF,uBAAwB,CAAE,UAAW,EAAK,EAC1C,sBAAuB,CAAE,UAAW,EAAM,EAC1C,sBAAuB,CAAE,UAAW,EAAK,EACzC,qBAAsB,CAAE,UAAW,EAAM,EACzC,qBAAsB,CAAE,UAAW,EAAM,EACzC,qBAAsB,CAAE,UAAW,EAAM,EACzC,YAAa,CAAE,UAAW,EAAK,EAC/B,aAAc,CAAE,UAAW,EAAK,EAChC,aAAc,CAAE,UAAW,EAAK,EAChC,SAAU,CAAE,UAAW,EAAM,EAC7B,YAAa,CAAE,UAAW,EAAM,EAChC,aAAc,CAAE,UAAW,EAAM,EACjC,aAAc,CAAE,UAAW,EAAK,EAChC,aAAc,CAAE,UAAW,EAAM,EACjC,cAAe,CAAE,UAAW,EAAM,EAClC,mBAAoB,CAAE,UAAW,EAAK,EACtC,oBAAqB,CAAE,UAAW,EAAM,EACxC,iBAAkB,CAAE,UAAW,EAAM,EACrC,eAAgB,CAAE,UAAW,EAAM,EACnC,eAAgB,CAAE,UAAW,EAAM,EACnC,mBAAoB,CAAE,UAAW,EAAM,EACvC,gBAAiB,CAAE,UAAW,EAAM,EACpC,kBAAmB,CAAE,UAAW,EAAM,EACtC,iBAAkB,CAAE,UAAW,EAAK,EACpC,gBAAiB,CAAE,UAAW,EAAM,EACpC,iBAAkB,CAAE,UAAW,EAAM,EACrC,iBAAkB,CAAE,UAAW,EAAM,EACrC,cAAe,CAAE,UAAW,EAAM,CACnC,EAIaC,EAAN,KAA0D,CACvD,aACC,OAEV,YAAYC,EAAsD,CACjE,KAAK,aAAeC,GAAK,EACzB,KAAK,OAASD,CACf,CAOQ,kBAAoB,IAAI,IAEhC,YAAc,CACbE,EACAC,EACAC,EAAwB,CAAC,IACP,CAClB,IAAIC,EAA8CF,EAC9CC,EAAQ,OAAS,KACpBC,EAAWC,GAAoC,CAC9CH,EAAKG,CAAI,EACT,KAAK,YAAYJ,EAAOC,CAAI,CAC7B,GAGD,KAAK,kBAAkB,IAAIA,EAAME,CAAO,EACxC,KAAK,aAAa,GAAGH,EAAOG,CAAO,EAEnC,GAAM,CAAE,OAAAE,CAAO,EAAIH,EACnB,GAAIG,EAAQ,CACX,IAAMC,EAAU,IAAM,CACrB,KAAK,YAAYN,EAAOC,CAAI,CAC7B,EACAI,EAAO,iBAAiB,QAASC,EAAS,CAAE,KAAM,EAAK,CAAC,CACzD,CAEA,MAAO,IAAM,KAAK,YAAYN,EAAOG,CAAO,CAC7C,EAEA,YAAc,CAAyBH,EAAUC,IAAmD,CACnG,IAAIE,EAAU,KAAK,kBAAkB,IAAIF,CAAI,EACzCE,IACH,KAAK,aAAa,IAAIH,EAAOG,CAAO,EACpC,KAAK,kBAAkB,OAAOF,CAAI,EAEpC,EAEU,UAAY,CAAyBM,EAAcC,IAAqB,CACjF,IAAIR,EAAQ,IAAI,OAAW,YAAYO,EAAqB,CAC3D,WAAY,KAAK,OAAOA,CAAS,EAAE,UACnC,OAAQC,CACT,CAAC,EACD,YAAK,aAAa,KAAKD,EAAWP,CAAK,EAEhC,CAACA,EAAM,gBACf,CACD,ECrJA,IAAMS,EAAU,CACf,QAAS,qEACT,SAAU,4BACV,iBAAkB,+CAClB,OAAQ,kEACT,EAaO,SAASC,EAAUC,EAAkB,CAG3C,GAAIA,GAAO,KACV,MAAO,SAGR,GAAI,MAAM,QAAQA,CAAG,EACpB,MAAO,QACD,GAAI,OAAOA,GAAQ,SACzB,OAAIF,EAAQ,QAAQ,KAAKE,CAAG,GAAKF,EAAQ,SAAS,KAAKE,CAAG,EAClD,WACGF,EAAQ,iBAAiB,KAAKE,CAAG,EACpC,mBAGD,SACD,GAAIA,aAAe,KACzB,MAAO,WAGR,IAAIC,EAAO,OAAOD,EAClB,MAAI,CAAC,SAAU,SAAU,SAAS,EAAE,SAASC,CAAI,EACzCA,EAGD,QACR,CAUA,SAASC,EAAaC,EAA8B,CACnD,OACCA,IAAQ,MACRA,aAAe,MACd,OAAOA,GAAQ,WAAaC,EAAQ,QAAQ,KAAKD,CAAG,GAAKC,EAAQ,SAAS,KAAKD,CAAG,IACnF,OAAOA,GAAQ,QAEjB,CAEA,IAAME,GAAgB,MAETC,EAAwC,CACpD,OAAQ,CACP,MAAQC,GAAeA,EAAM,SAAS,EACtC,SAAWA,GAAeA,IAAU,MAAQ,OAAOA,GAAU,QAC9D,EACA,OAAQ,CACP,MAAQA,GAAeA,EACvB,SAAWA,GAAeA,IAAU,MAAS,OAAOA,GAAU,UAAY,CAAC,MAAMA,CAAK,CACvF,EACA,QAAS,CACR,MAAQA,GAAeA,EACvB,SAAWA,GAAeA,IAAU,MAAQ,OAAOA,GAAU,SAC9D,EACA,OAAQ,CACP,MAAQA,GAAe,OAAOA,CAAK,EACnC,SAAWA,GACVA,IAAU,MAAQ,OAAOA,GAAU,UAAY,OAAOA,GAAU,UAAY,OAAOA,GAAU,QAC/F,EACA,iBAAkB,CACjB,MAAQA,GAAeA,EACvB,SAAWA,GAAeA,IAAU,MAAS,OAAOA,GAAU,UAAYH,EAAQ,iBAAiB,KAAKG,CAAK,CAC9G,EACA,MAAO,CACN,MAAQA,GAAeA,EACvB,SAAWA,GAAeA,IAAU,MAAQ,MAAM,QAAQA,CAAK,CAChE,EACA,KAAM,CACL,MAAQA,GAAe,CACtB,IAAIC,EAAeF,EAAW,SAAY,MAAMC,CAAK,EAAE,QAAQ,EAE/D,OAAIA,aAAiB,KACpBC,EAAe,CAACD,EACN,OAAOA,GAAU,UAAY,CAACA,EAAM,QAAQ,QAAQ,EAC9DC,EAAe,OAAOD,EAAM,UAAU,EAAGA,EAAM,OAAS,CAAC,CAAC,EAE1DC,EAAe,CAAC,IAAI,KAAKD,CAAK,EAGxB,IAAI,KAAK,CAAC,EAAEC,EAAeH,IAAiBA,EAAa,CACjE,EACA,SAAUH,CACX,EACA,SAAU,CACT,MAAQK,GACHA,aAAiB,KACbA,EACG,OAAOA,GAAU,UAAY,CAACA,EAAM,QAAQ,QAAQ,EACvD,IAAI,KAAK,OAAOA,EAAM,UAAU,EAAGA,EAAM,OAAS,CAAC,CAAC,CAAC,EAEtD,IAAI,KAAKA,CAAK,EAEtB,SAAUL,CACX,EACA,KAAM,CACL,MAAQK,GAAeD,EAAW,SAAY,MAAMC,CAAK,EACzD,SAAUL,CACX,EACA,IAAK,CACJ,MAAQK,GAAeA,EAAM,SAAS,EACtC,SAAWA,GAAeA,IAAU,MAAQ,OAAOA,GAAU,QAC9D,EACA,OAAQ,CACP,MAAQA,GAAe,CACtB,GAAI,CAACA,EACJ,OAAO,KAGR,IAAIE,EAAS,KAAKF,CAAK,EACnBG,EAAQ,IAAI,WAAWD,EAAO,MAAM,EAExC,QAASE,EAAI,EAAGA,EAAIF,EAAO,OAAQE,IAClCD,EAAMC,CAAC,EAAIF,EAAO,WAAWE,CAAC,EAG/B,OAAOD,EAAM,MACd,EACA,SAAWH,GACNA,IAAU,MAAQA,aAAiB,aAAeA,aAAiB,YAAcA,aAAiB,KAC9F,GAGDH,EAAQ,OAAO,KAAKG,CAAK,CAElC,CACD,ECrJA,SAASK,IAA8C,CACtD,OAAO,IAAI,QAASC,GAAY,CAC/B,IAAMC,EAAU,WACf,IAAM,CACLD,EAAQ,EAAK,CACd,EACA,GACD,EAEA,OAAW,IAAI,aAAa,UAAU,IAAM,CAC3C,aAAaC,CAAO,EACpBD,EAAQ,EAAI,CACb,CAAC,CACF,CAAC,CACF,CAaA,SAASE,GAAMC,EAAiE,CAC/E,OAAO,OAAW,iBAAmB,QAAaA,aAAoB,cACvE,CAEA,eAAsBC,EAAoBD,EAA6D,CACtG,IAAME,EAAcH,GAAMC,CAAQ,EAC/BA,EAAS,kBAAkB,cAAc,EACzCA,EAAS,QAAQ,IAAI,cAAc,GAAK,GACvC,CAAE,OAAAG,EAAQ,WAAAC,CAAW,EAAIJ,EACzBK,EAQJ,GANIN,GAAMC,CAAQ,EACjBK,EAAOH,GAAa,SAAS,MAAM,EAAI,KAAK,MAAMF,EAAS,QAAQ,EAAIA,EAAS,SAEhFK,EAAOH,GAAa,SAAS,MAAM,EAAI,MAAMF,EAAS,KAAK,EAAI,MAAMA,EAAS,KAAK,EAGhFG,IAAW,KAAOE,IAAS,kBAC9B,MAAO,CACN,QAAS,GACT,SAAU,MAAMT,GAA0B,EAC1C,MAAOS,EACP,QAASA,EACT,OAAAF,EACA,WAAAC,CACD,EAGD,GAAI,OAAOC,GAAS,UAAY,OAAO,OAAOA,EAAM,OAAO,EAAG,CAC7D,IAAIC,EAAU,OAAOD,EAAK,OAAU,SAAWA,EAAK,MAAM,QAAUA,EAAK,MACrEE,EAAQ,OAAOF,EAAK,OAAU,SAAWA,EAAK,MAAM,WAAaA,EAAK,MACpEG,EAAuB,CAC5B,GAAGH,EACH,QAAS,GACT,SAAU,GACV,QAAAC,EACA,WAAYC,EACZ,MAAAA,CACD,EAEA,OAAI,OAAO,OAAOF,EAAM,OAAO,IAC9B,QAAQ,eAAeA,EAAK,KAAK,EACjC,QAAQ,IAAIA,EAAK,KAAK,EACtB,QAAQ,SAAS,GAGXG,CACR,CAEA,IAAIC,EAAmBP,GAAa,SAAS,WAAW,EAKxD,GAJI,CAACO,GAAoBJ,EAAK,CAAC,GAAK,MACnCI,EAAmB,IAGhBJ,GAAQA,EAAK,OAAS,GAAKI,EAAkB,CAEhD,IAAIC,EADa,yBACW,KAAKL,CAAI,EACjCG,EAAQ;AAAA,yCAAkFL,CAAM,GACpG,OAAIO,IACHF,EAAQE,EAAW,CAAC,GAEd,CACN,QAAS,GACT,SAAU,GACV,MAAAF,EACA,QAASA,EACT,OAAAL,EACA,WAAAC,CACD,CACD,CAEA,IAAIE,EAAkB,CAACD,GAAQF,EAAS,GAAGA,CAAM,IAAIC,CAAU,GAAKC,GAAQ,oBAE5E,MAAO,CACN,QAAS,GACT,SAAU,GACV,MAAOC,EACP,QAAAA,EACA,OAAAH,EACA,WAAAC,CACD,CACD,CC3GO,SAASO,EACfC,EACAC,EAAkB,GACE,CACpB,OAAID,IAAW,KACP,CAAC,EACE,MAAM,QAAQA,CAAM,EACvBA,EAAO,IAAKE,GACd,OAAOA,GAAU,SACbA,EAEA,CAAE,KAAMA,EAAO,SAAUD,CAAgB,CAEjD,EACS,OAAOD,GAAW,SACrB,CAAC,CAAE,KAAMA,CAAO,CAAC,EAGlBA,CACR,CCrBA,SAASG,GAAOC,EAAa,CAC5B,OAAO,OAAO,UAAU,SAAS,KAAKA,CAAM,CAC7C,CAKO,SAASC,EAAQD,EAAaE,EAAY,CAChD,GAAI,CAACF,GAAU,CAACE,EACf,OAAOF,IAAWE,EAGnB,GAAI,OAAOF,GAAW,UAAY,OAAOE,GAAU,SAAU,CAC5D,IAAIC,EAAYJ,GAAOC,CAAM,EACzBI,EAAWL,GAAOG,CAAK,EAE3B,GAAIC,IAAcC,EAAU,CAC3B,GAAID,IAAc,gBACjB,OAAOH,EAAO,QAAQ,IAAME,EAAM,QAAQ,EACpC,GAAIC,IAAc,iBAAkB,CAC1C,GAAIH,EAAO,SAAWE,EAAM,OAC3B,MAAO,GAGR,QAAS,EAAI,EAAG,EAAIF,EAAO,OAAQ,IAClC,GAAI,CAACC,EAAQD,EAAO,CAAC,EAAGE,EAAM,CAAC,CAAC,EAC/B,MAAO,GAIT,MAAO,EACR,CAEA,OAAS,CAACG,EAAKC,CAAK,IAAK,OAAO,QAAQN,CAAM,EAC7C,GAAI,CAACC,EAAQC,EAAMG,CAAG,EAAGC,CAAK,EAC7B,MAAO,GAIT,MAAO,EACR,CAEA,MAAO,EACR,CAEA,OAAON,IAAWE,CACnB,CC9CO,SAASK,EAAeC,EAA6BC,EAAiB,CAC5E,IAAIC,EAAY,GAEVC,EAAI,WAAW,IAAM,CACtB,CAACD,GAAa,CAACF,EAAW,OAAO,SACpCA,EAAW,MAAM,CAEnB,EAAGC,CAAO,EAEV,OAAO,UAAyB,CAC/B,aAAaE,CAAC,EACdD,EAAY,EACb,CACD,CCLO,IAAME,EAAcC,GAAgB,8BAA8BA,CAAG,GVC5E,SAASC,GAAaC,EAAwBC,EAAoB,CACjE,IAAIC,EAAOF,EAAM,MAAQG,EAAUF,CAAK,EACxC,MAAI,CAACD,EAAM,MAAQC,IAAU,OAC5BD,EAAM,KAAOE,GAGPA,CACR,CAMO,SAASE,EAAuBC,EAA2BC,EAAoBC,EAAiC,CACtHA,EAAeA,GAAgB,2BAC/B,cACCF,EAAO,SAAWC,EAAK,OACvB,GAAGC,CAAY,wFAChB,EAEA,IAAIC,EAAc,CAAC,EACnB,QAAS,EAAI,EAAG,EAAIH,EAAO,OAAQ,IAAK,CACvC,IAAII,EAAQH,EAAK,CAAC,EACdI,EAAQL,EAAO,CAAC,EAChBM,EAAOC,GAAaF,EAAOD,CAAK,EAChCI,EAAYC,EAAWH,CAAI,EAE3BE,OACH,cAAUA,EAAU,SAASJ,CAAK,EAAUM,EAAqBR,EAAcG,EAAM,IAAI,CAAC,EAC1FF,EAAOE,EAAM,IAAI,EAAID,IAAU,KAAO,KAAOI,EAAU,MAAMJ,CAAK,EAEpE,CAEA,OAAOD,CACR,CAEO,SAASQ,EAAyBX,EAA2BC,EAAeC,EAAmC,CACrH,OAAOD,EAAK,IAAKE,GAAWJ,EAAoBC,EAAQG,EAAQD,GAAgB,MAAS,CAAC,CAC3F,CAmCO,IAAKU,QACXA,EAAA,IAAM,MACNA,EAAA,KAAO,OACPA,EAAA,aAAe,eACfA,EAAA,eAAiB,iBAJNA,QAAA,IAqJNC,GAA4B,CACjC,UAAW,CAAE,UAAW,EAAM,EAC9B,QAAS,CAAE,UAAW,EAAM,EAC5B,WAAY,CAAE,UAAW,EAAM,CAChC,EAEsBC,EAAf,cAAsEC,CAAsC,CAgBlH,aAAc,CACb,MAAMF,EAAyB,CAChC,CACD,EAEA,SAASG,IAAoB,CAC5B,MAAO,CACN,UAAW,OAAW,IAAI,SAAS,GACnC,aAAc,KACd,QAAS,EACT,OAAQ,CAAC,EACT,QAAS,EACV,CACD,CAEA,IAAeC,EAAf,cAAkFH,CAAe,CACtF,wBAAkD,KACpD,QACR,IAAI,QAAkB,CACrB,OAAO,KAAK,QAAQ,QAAUI,EAAiB,CAChD,CACA,IAAI,OAAOC,EAAuB,CACjC,KAAK,QAAQ,OAASA,CACvB,CAEA,YAAYC,EAAyC,CACpD,MAAM,EACN,KAAK,QAAUA,CAChB,CAEA,MAAM,QACLC,EACAC,EACAF,EAA0B,CAAC,EACP,CACpB,IAAIG,EAAkD,CACrD,KAAM,KAAK,UAAUD,CAAI,EACzB,QAAS,KAAK,QAAQ,QACtB,GAAGF,CACJ,EAEMI,EAAW,MAAM,KAAK,OAAO,QAAQH,EAAKE,CAAW,EAE3D,GAAIC,EAAS,GAAI,CAChB,IAAIF,EAAO,MAAME,EAAS,KAAK,EAC/B,GAAI,OAAO,OAAOF,EAAM,SAAS,EAChC,YAAK,UAAU,YAAaA,EAAK,OAAY,EAEtCA,EAAK,OAEd,CAEA,IAAMG,EAAgB,MAAMC,EAAoBF,CAAQ,EAExD,GAAIC,EAAc,SACjB,OAAO,MAAM,KAAK,QAAQJ,EAAKC,EAAMF,CAAO,EAG7C,WAAK,UAAU,UAAWK,EAAc,OAAO,EAEzC,MAAMA,EAAc,OAAO,CAClC,CACD,EAEaE,EAAN,cACEV,CAET,CACS,SACR,OAEA,YAAYG,EAA2F,CACtG,MAAM,OAAO,OAAO,CAAC,EAAGJ,GAAkB,EAAGI,GAAW,CAAC,EAAG,CAAC,CAAC,EAC9D,KAAK,SAAW,OAAO,OAAO,CAAC,EAAGJ,GAAkB,EAAGI,GAAW,CAAC,EAAG,CAAC,EACvE,KAAK,OAAS,KAAK,SAAS,OAAO,IAAKQ,GACnC,OAAOA,GAAU,SACb,CAAE,KAAMA,CAAM,EAEfA,CACP,CACF,CAEQ,kBAAmB,CAC1B,IAAIC,EAAS,GACb,OAAI,KAAK,SAAS,SACb,KAAK,SAAS,OAAO,OAAS,IACjCA,EAAS,KAAK,SAAS,OAAO,SAAS,EAAE,QAAQ,KAAM,GAAG,GAGvD,KAAK,SAAS,UACjBA,GAAU,IAAM,KAAK,SAAS,UAIzBA,CACR,CAEQ,cAAcC,EAAmBC,EAAgB,GAAO,CAC/D,MAAO,IAAID,CAAI,IAAI,KAAK,SAAS,SAAS,IAAI,KAAK,SAAS,YAAY,IACvEC,EAAgB,KAAK,iBAAiB,EAAI,EAC3C,EACD,CAEQ,cAAe,CACtB,IAAIC,EAAY,KAAK,SAAS,UAC9B,MAAI,WAAW,KAAKA,CAAS,IAC5BA,EAAYA,EAAU,UAAU,EAAGA,EAAU,OAAS,CAAC,GAEjDA,CACR,CAEA,gBAAgBC,EAAiBC,EAAkBJ,EAA4B,OAAQ,CACtF,MAAO,SAASA,CAAI,IAAI,KAAK,aAAa,CAAC,IAAI,KAAK,SAAS,YAAY,IAAIG,CAAO,IAAI,mBACvFC,CACD,CAAC,EACF,CAEA,WAAWD,EAAiBL,EAAeM,EAAkBJ,EAA4B,OAAQ,CAChG,MAAO,YAAY,KAAK,aAAa,CAAC,IAAI,KAAK,SAAS,YAAY,IAAIF,CAAK,IAAIK,CAAO,IAAI,mBAC3FC,CACD,CAAC,EACF,CAEA,MAAM,OAAOZ,EAAsBF,EAA6C,CAC/E,IAAMe,EAAS,MAAM,KAAK,QACzB,WAAW,KAAK,SAAS,SAAS,IAAI,KAAK,SAAS,YAAY,GAChEb,EACAF,CACD,EAEA,OAAIe,IAAW,KAAa,KAErBC,EAAoBd,EAAK,QAAU,KAAK,OAAQa,EAAQ,KAAK,SAAS,cAAgB,EAAE,CAChG,CAIA,MAAM,SAAgBb,EAA0DF,EAA0B,CACzG,IAAMe,EAAS,MAAM,KAAK,QACzB,KAAK,cAAc,UAAoB,EACvCb,EACAF,CACD,EACA,OAAI,MAAM,QAAQe,CAAM,EAChBE,EAAyBf,EAAK,QAAU,KAAK,OAAQa,EAAQ,KAAK,SAAS,YAAY,GAE7FA,EAAe,KAAOE,EAAyBf,EAAK,QAAU,KAAK,OAAQa,EAAO,IAAI,EAChFA,EAET,CAEA,MAAM,SAAyBb,EAA+BF,EAA0B,CACvF,OAAO,KAAK,QAA2C,KAAK,cAAc,UAAoB,EAAGE,EAAMF,CAAO,CAC/G,CAEA,MAAM,OAAOE,EAAsBF,EAA6C,CAC/E,IAAII,EAAW,MAAM,KAAK,QAA6B,KAAK,cAAc,QAAkB,EAAGF,EAAMF,CAAO,EAE5G,OAAOI,GAAWY,EAAoBd,EAAK,QAAU,KAAK,OAAQE,EAAU,KAAK,SAAS,YAAY,CACvG,CAEA,MAAM,QAAQF,EAAsBF,EAA0B,CAC7D,OAAO,KAAK,QAAiB,KAAK,cAAc,SAAmB,EAAGE,EAAMF,CAAO,CACpF,CAEA,MAAM,YAAYE,EAA6BF,EAA0B,CAGxE,OAFa,MAAM,KAAK,QAAiB,KAAK,cAAc,cAAyB,EAAK,EAAGE,EAAMF,CAAO,CAG3G,CAEQ,mBAAsBe,EAAwBN,EAAiC,CACtF,OAAOQ,EAAsBR,GAAU,KAAK,OAAQM,EAAQ,KAAK,SAAS,YAAY,CACvF,CAEA,MAAM,WAAWb,EAAsBF,EAA0B,CAChE,IAAIe,EAAS,MAAM,KAAK,QAAwB,KAAK,cAAc,YAAsB,EAAGb,EAAMF,CAAO,EAGzG,OAFa,KAAK,mBAAmBe,CAAM,CAG5C,CAEA,MAAM,aAAab,EAA+BF,EAA0B,CAC3E,IAAIe,EAAS,MAAM,KAAK,QACvB,aAAa,KAAK,SAAS,SAAS,IAAI,KAAK,SAAS,YAAY,IAAIb,EAAK,WAAW,MAAM,SAASA,EAAK,WAAW,KAAK,GAC1HA,EACAF,CACD,EAGA,OAFa,KAAK,mBAAmBe,CAAM,CAG5C,CACD,EAEaG,EAAN,cACErB,CAET,CACS,SACR,OAEA,YAAYG,EAAwC,CACnD,MAAM,OAAO,OAAO,CAAC,EAAGJ,GAAkB,EAAGI,CAAO,CAAC,EACrD,KAAK,SAAWA,EAChB,KAAK,OAAS,KAAK,SAAS,OAAO,IAAKQ,GACnC,OAAOA,GAAU,SACb,CAAE,KAAMA,CAAM,EAEfA,CACP,CACF,CAEQ,mBAAsBO,EAAwBN,EAAiC,CACtF,OAAOQ,EAAsBR,GAAU,KAAK,OAAQM,EAAQ,KAAK,SAAS,YAAY,CACvF,CAEQ,kBAAkBA,EAAsBN,EAA+B,CAC9E,OAAOO,EAAoBP,GAAU,KAAK,OAAQM,EAAQ,KAAK,SAAS,YAAY,CACrF,CAEQ,cAAcL,EAAmBR,EAAyC,CACjF,IAAIiB,EAA4B,CAC/B,UAAWT,EACX,aAAc,KAAK,SAAS,aAC5B,OAAQU,EAAU,KAAK,SAAS,MAAM,EACtC,kBAAmB,GACnB,GAAGlB,CACJ,EAEA,OAAIQ,IAAS,YAAwB,KAAK,SAAS,UAClDS,EAAO,QAAU,KAAK,SAAS,SAG5B,KAAK,SAAS,aACjBA,EAAO,WAAa,KAAK,SAAS,YAG5BA,CACR,CAEA,gBAAgBN,EAAiBC,EAAkBJ,EAA4B,OAAQ,CACtF,MAAO,kBAAkBA,CAAI,IAAI,KAAK,SAAS,YAAY,IAAIG,CAAO,IAAI,mBAAmBC,CAAQ,CAAC,EACvG,CAEA,WAAWD,EAAiBL,EAAeM,EAAkBJ,EAA4B,OAAQ,CAChG,MAAO,kBAAkB,KAAK,SAAS,YAAY,IAAIG,CAAO,IAAIL,CAAK,IAAI,mBAAmBM,CAAQ,CAAC,EACxG,CAEA,MAAM,OAAOZ,EAAsBF,EAA6C,CAC/E,IAAIe,EAAS,MAAM,KAAK,QACvB,YACA,KAAK,cAAc,SAAoBb,CAAI,EAC3CF,CACD,EACA,OAAOe,GAAU,KAAO,KAAO,KAAK,kBAAkBA,EAAQb,EAAK,MAAM,CAC1E,CAIA,MAAM,SAASA,EAAsBF,EAA0B,CAC9D,IAAIe,EAAS,MAAM,KAAK,QACvB,YACA,KAAK,cAAc,WAAsBb,CAAI,EAC7CF,CACD,EACIqB,EACJ,OAAI,MAAM,QAAQN,CAAM,EACvBM,EAASJ,EAAsBf,EAAK,QAAU,KAAK,OAAQa,EAAQ,KAAK,SAAS,YAAY,EAE7FM,EAAS,CACR,GAAGN,EACH,KAAME,EAAsBf,EAAK,QAAU,KAAK,OAAQa,EAAO,KAAM,KAAK,SAAS,YAAY,CAChG,EAEMM,CACR,CAEA,MAAM,SAASnB,EAAsBF,EAA0B,CAO9D,OANa,MAAM,KAAK,QACvB,YACA,KAAK,cAAc,WAAsBE,CAAI,EAC7CF,CACD,CAGD,CAEA,MAAM,OAAOE,EAAsBF,EAA6C,CAC/E,IAAIe,EAAS,MAAM,KAAK,QACvB,YACA,KAAK,cAAc,SAAoBb,CAAI,EAC3CF,CACD,EAGA,OAFce,GAAkB,KAAK,kBAAkBA,EAAQb,EAAK,MAAM,CAG3E,CAEA,MAAM,QAAQA,EAAsBF,EAA0B,CAE7D,OADa,MAAM,KAAK,QAAiB,YAAa,KAAK,cAAc,UAAqBE,CAAI,EAAGF,CAAO,CAE7G,CAEA,MAAM,YAAYE,EAA6BF,EAA0B,CAGxE,OAFa,MAAM,KAAK,QAAiB,YAAa,KAAK,cAAc,cAAyBE,CAAI,EAAGF,CAAO,CAGjH,CAEA,MAAM,WAAWE,EAAsBF,EAA0B,CAChE,IAAIe,EAAS,MAAM,KAAK,QACvB,YACA,KAAK,cAAc,aAAwBb,CAAI,EAC/CF,CACD,EAEA,OADa,KAAK,mBAAmBe,EAAQb,EAAK,MAAM,CAEzD,CAEA,MAAM,aAAaA,EAA+BF,EAA0B,CAC3E,IAAIsB,EAAa,KAAK,cAAc,eAA0BpB,CAAI,EAClEoB,EAAW,aAAe,GAC1B,IAAIP,EAAS,MAAM,KAAK,QAAwB,YAAaO,EAAYtB,CAAO,EAGhF,OAFa,KAAK,mBAAmBe,CAAM,CAG5C,CACD,EWpkBA,IAAAQ,GAA0B,SAqCnB,IAAMC,GAAwE,CACpF,eAAgB,CAAE,UAAW,EAAK,EAClC,WAAY,CAAE,UAAW,EAAM,EAC/B,eAAgB,CAAE,UAAW,EAAM,EACnC,WAAY,CAAE,UAAW,EAAM,CAChC,EAEaC,EAAN,cAA2BC,CAAyC,CAClE,UACA,WACA,UACA,QACA,QACR,IAAI,QAAkB,CACrB,OAAO,KAAK,QAAQ,QAAUC,EAAiB,CAChD,CACA,IAAI,OAAOC,EAAuB,CACjC,KAAK,QAAQ,OAASA,CACvB,CAEA,YAAYC,EAA8B,CACzC,MAAML,EAAkB,EACxB,KAAK,UAAYK,EAAQ,WAAa,OAAW,IAAI,SAAS,GAC9D,KAAK,WAAaA,EAAQ,WAC1B,KAAK,UAAYA,EAAQ,UACzB,KAAK,QAAUA,EAAQ,QACvB,KAAK,QAAU,CAAE,GAAGA,CAAQ,CAC7B,CAEQ,iBAAkB,CACzB,OAAO,OAAO,KAAK,YAAe,SAAW,KAAK,WAAa,KAAK,YAAY,gBAAgB,CACjG,CAEA,cAAuB,CACtB,IAAIC,EAAM,KAAK,QAAQ,OAAS,gBAAgB,KAAK,SAAS,IAAI,KAAK,gBAAgB,CAAC,GAExF,OAAI,KAAK,YACRA,GAAO,IAAM,KAAK,WAGf,KAAK,UACRA,GAAO,IAAM,KAAK,SAGZA,CACR,CAEA,MAAM,OAAOC,EAAyBC,EAA8BC,EAAqC,CACxG,KAAK,UAAU,iBAAkB,IAAI,EAErC,IAAMC,EACL,OAAO,KAAK,YAAe,SACxB,CAAC,EACA,KAAK,YAAY,aAAa,qBAAqB,EAEpDF,GAAS,UACZ,KAAK,QAAUA,EAAO,QACtB,OAAOA,EAAO,SAGf,IAAMG,EAAY,CACjB,GAAGD,EACH,GAAGF,CACJ,EAEA,GAAI,OAAW,eAAgB,CAC9B,IAAMI,EAAO,IAAI,OAAW,SAE5B,OAAS,CAACC,EAAOT,CAAK,IAAK,OAAO,QAAQO,CAAS,EAClDC,EAAK,OAAOC,EAAOT,CAAK,EAGzB,OAAAQ,EAAK,OACJ,KAAK,WAAa,OAClBL,EACAA,aAAsB,KAAOA,EAAW,KAAOE,GAAY,MAC5D,EAsCO,MApCY,IAAI,QAAQ,CAACK,EAASC,IAAW,CACnD,IAAMC,EAAU,IAAI,eAEpBA,EAAQ,OAAO,iBAAiB,WAAaC,GAAQ,CACpD,KAAK,UAAU,aAAc,CAC5B,OAAQA,EAAI,OACZ,MAAOA,EAAI,KACZ,CAAC,CACF,CAAC,EAEDD,EAAQ,iBAAiB,mBAAoB,IAAM,CAClD,GAAIA,EAAQ,aAAe,EAC1B,GAAIA,EAAQ,SAAW,IACtB,KAAK,UAAU,aAAc,IAAI,EACjCF,EAAQE,EAAQ,QAAQ,MAExB,IAAI,CACH,IAAME,EAAS,KAAK,MAAMF,EAAQ,QAAQ,EAE1C,sBAAU,CAACE,EAAO,MAAOA,EAAO,KAAK,EAC/B,MAAM,kBAAoBF,EAAQ,OAAS,IAAMA,EAAQ,QAAQ,CACxE,OAASG,EAAO,CACf,KAAK,UAAU,iBAAkB,CAChC,MAAAA,CACD,CAAC,EACDJ,EAAOI,CAAK,CACb,CAGH,CAAC,EAEDH,EAAQ,KAAK,OAAQ,KAAK,aAAa,CAAC,EACxCA,EAAQ,iBAAiB,SAAU,kBAAkB,EACrDA,EAAQ,iBAAiB,mBAAoB,gBAAgB,EAC7DA,EAAQ,KAAKJ,CAAgB,CAC9B,CAAC,CAEF,KACC,IAAI,CACH,IAAMQ,EAAkB,YAClB,CAAE,SAAAC,CAAS,EAAI,MAAM,OAAoDD,GACzER,EAAO,IAAIS,EAEjB,OAAS,CAACR,EAAOT,CAAK,IAAK,OAAO,QAAQO,CAAS,EAClDC,EAAK,OAAOC,EAAOT,CAAK,EAGzBQ,EAAK,OACJ,KAAK,WAAa,OAClBL,EACCA,GAAqB,MAAYA,GAAqB,UAAe,MACvE,EAEA,IAAID,EAAM,KAAK,aAAa,EACxBgB,EAAW,MAAM,KAAK,OAAO,QAAQhB,EAAK,CAC7C,OAAQ,OACR,QAAS,CACR,OAAQ,kBACT,EACA,KAAMM,EACN,OAAQ,EACT,CAAC,EAED,GAAIU,EAAS,GAAI,CAChB,IAAMJ,EAAU,MAAMI,EAAS,KAAK,KAGpC,cAAU,CAACJ,EAAO,MAAOA,EAAO,KAAK,CACtC,KAAO,CACN,GAAI,CAAE,QAAAK,CAAQ,EAAI,MAAMC,EAAoBF,CAAQ,EACpD,MAAM,MAAMC,CAAO,CACpB,CACD,OAASJ,EAAO,CACf,WAAK,UAAU,iBAAkB,CAAE,MAAAA,CAAM,CAAC,EACpCA,CACP,CAEF,CACD,ECnKA,IAAMM,GAA4D,CACjE,iBAAkB,CAAE,UAAW,EAAK,EACpC,kBAAmB,CAAE,UAAW,EAAK,EACrC,WAAY,CAAE,UAAW,EAAM,EAC/B,gBAAiB,CAAE,UAAW,EAAM,EACpC,YAAa,CAAE,UAAW,EAAM,CACjC,EAEaC,EAAN,cAAwDC,CAA0B,CAChF,YAAyC,KACzC,YAAc,EACd,WACA,cAAqC,CAAC,EACtC,QACA,UACA,SACA,MAER,YAAYC,EAA4B,CACvC,MAAMH,EAAY,EAClB,KAAK,QAAU,CAAE,GAAGG,CAAS,EAE7B,KAAK,WAAa,KAAK,QAAQ,WAC/B,KAAK,SAAW,KAAK,WAAW,aAAa,YAAY,GAAK,GAC9D,KAAK,MAAQ,KAAK,WAAW,cAAc,EAC3C,KAAK,UAAY,KAAK,WAAa,GAAK,EAAI,KAAK,KAAK,KAAK,MAAQ,KAAK,QAAQ,EAEhF,KAAK,WAAa,KAAK,WAAW,KAAK,IAAI,EAC3C,KAAK,aAAe,KAAK,aAAa,KAAK,IAAI,EAC/C,KAAK,eAAiB,KAAK,eAAe,KAAK,IAAI,EACnD,KAAK,eAAiB,KAAK,eAAe,KAAK,IAAI,EACnD,KAAK,SAAW,KAAK,SAAS,KAAK,IAAI,EACvC,KAAK,YAAc,KAAK,YAAY,KAAK,IAAI,EAC7C,KAAK,YAAc,KAAK,YAAY,KAAK,IAAI,EAC7C,KAAK,wBAA0B,KAAK,wBAAwB,KAAK,IAAI,EACrE,KAAK,uBAAyB,KAAK,uBAAuB,KAAK,IAAI,EACnE,KAAK,oBAAsB,KAAK,oBAAoB,KAAK,IAAI,EAE7D,KAAK,aAAa,EAEd,KAAK,WAAW,aAAa,GAChC,KAAK,mBAAmB,KAAM,CAAC,CAEjC,CAEQ,iBAAkB,CACzB,IAAIC,EAAY,KAAK,KAAK,KAAK,MAAQ,KAAK,QAAQ,EAChD,KAAK,YAAcA,IAIvB,KAAK,UAAYA,EACjB,KAAK,UAAU,kBAAmB,CAAE,UAAAA,CAAU,CAAC,EAChD,CAEQ,mBAAmBC,EAAyBC,EAAkB,CACrE,IAAIC,EAA2B,CAAC,EAC5BC,EAAaF,EAAW,KAAK,SAC7BG,EAAYD,EAAa,KAAK,SAKlC,GAHIC,EAAY,KAAK,QACpBA,EAAY,KAAK,OAEd,CAAC,OAAO,OAAO,KAAK,cAAeH,CAAQ,EAC9C,KAAK,WAAW,gBAAgBA,EAAW,KAAK,SAAU,KAAK,QAAQ,EACvE,KAAK,cAAcA,CAAQ,EAAI,GAC/B,KAAK,YAAc,aACT,KAAK,cAAcA,CAAQ,IAAM,GAAM,CACjD,QAASI,EAAIF,EAAYE,EAAID,EAAWC,IACvCH,EAAK,KAAK,KAAK,WAAW,QAAQG,CAAC,CAAC,EAGrC,KAAK,YAAcH,CACpB,MACC,KAAK,YAAc,KAGpB,KAAK,YAAcD,EAEfD,IAAa,MAAQ,KAAK,cAAcA,CAAQ,IAAM,IACzD,OAAO,KAAK,cAAcA,CAAQ,CAEpC,CAEA,OAA6CM,EAAcC,EAA2C,CACrG,OAAO,KAAK,YAAYD,EAAWC,CAAO,CAC3C,CAEA,OAA6CD,EAAcC,EAA2C,CACrG,OAAO,KAAK,YAAYD,EAAWC,CAAO,CAC3C,CAEA,MAAM,WAAWC,EAAe,CAC/B,GAAI,KAAK,WAAW,QAAQ,EAC3B,OAGD,GAAI,KAAK,WAAW,gBAAgB,IAAM,GACzC,GAAI,CACH,MAAM,KAAK,WAAW,QAAQ,CAC/B,MAAY,CACX,MACD,CAGD,GAAI,KAAK,cAAgBA,EAAO,CAC/B,IAAIC,EAAO,CAAE,QAAS,KAAK,YAAa,QAASD,CAAM,EAGvD,GAAI,CAFS,KAAK,UAAU,mBAAoBC,CAAI,EAGnD,MAAO,GAGR,KAAK,mBAAmBA,EAAK,QAASA,EAAK,OAAO,EAClD,KAAK,UAAU,aAAcA,CAAI,CAClC,CAGI,KAAK,YAAc,IAAM,KAAK,WAAW,gBAAgB,GAAK,KAAK,WAAW,gBAAgB,IACpF,KAAK,WAAW,QAAQ,EAEhC,QAAQ,CAACC,EAAMC,IAAU,CACzB,KAAK,WAAW,QAAQA,CAAK,GAAK,KAAK,WAAW,YAAYA,CAAK,GACtE,KAAK,WAAW,UAAUA,CAAK,CAEjC,CAAC,EAGF,IAAIC,EAAW,KAAK,WAAW,aAAa,YAAY,GAAK,GAE5D,KAAK,WAAW,cAAc,EAAI,GAClC,KAAK,MAAM,KAAK,YAAcA,CAAQ,IAAM,KAAK,WAAW,gBAAgB,GAC5E,KAAK,WAAW,gBAAgB,IAAM,IAEtC,KAAK,WAAW,gBAAgB,KAAK,YAAcA,CAAQ,CAE7D,CAEA,aAAc,CACb,IAAIC,EAAY,CAAE,KAAM,KAAK,WAAY,EAGzC,GAAI,CAFS,KAAK,UAAU,oBAAqBA,CAAS,EAGzD,OAGD,KAAK,YAAc,CAAC,EAEpB,IAAMV,EAAa,KAAK,YAAc,KAAK,SACvCC,EAAYD,EAAa,KAAK,SAC9BC,EAAY,KAAK,QACpBA,EAAY,KAAK,OAGlB,QAASC,EAAIF,EAAYE,EAAID,EAAWC,IACvC,KAAK,YAAY,KAAK,KAAK,WAAW,QAAQA,CAAC,CAAC,EAGjD,KAAK,UAAU,cAAeQ,CAAS,EAEvC,IAAIC,EAAe,KAAK,WAAW,gBAAgB,EAC/CF,EAAW,KAAK,WAAW,aAAa,YAAY,GAAK,GAC7D,GAAI,KAAK,WAAW,cAAc,EAAI,GAAKE,IAAiB,IAAMF,GAAY,EAAG,CAChF,IAAIG,EAAc,KAAK,YAAcH,EACjCI,GAAY,KAAK,YAAc,GAAKJ,GACpCE,EAAeC,GAAeD,GAAgBE,IACjD,KAAK,WAAW,gBAAgB,KAAK,YAAcJ,CAAQ,CAE7D,CACD,CAEA,cAAe,CACd,OAAO,KAAK,SACb,CAEA,gBAAiB,CAChB,OAAO,KAAK,WACb,CAEA,gBAAyC,CACxC,OAAO,KAAK,WACb,CAEQ,wBAAwBK,EAAyD,CACxF,GAAI,CAACA,EAAO,OAEZ,IAAIf,EAAOe,EAAM,OAEjB,GAAI,CAACf,EAAM,OAEX,IAAMgB,EAAchB,EAAK,KAAO,KAAK,WAAa,EAC5CiB,EAAajB,EAAK,KAAO,KAAK,SAEhCA,EAAK,OAAS,IACjB,KAAK,MAAQA,EAAK,OAGfgB,GACChB,EAAK,OAAS,IACjB,KAAK,cAAgB,CAAC,GAGvB,KAAK,cAAciB,CAAU,EAAI,GAE7B,KAAK,cAAgBA,GACxB,KAAK,YAAY,GAGlB,QAAQ,KAAK,2DAA2D,CAE1E,CAEQ,uBACPF,EACC,CACD,GAAI,CAACA,EAAO,OAEZ,GAAI,CAAE,OAAQG,CAAM,EAAIH,EACpBI,EAAW,EACf,GAAID,GAAO,OAAS,aAAc,CACjC,IAAIE,EAAcF,EAAM,OAAY,GACpC,GAAI,KAAK,WAAaE,EAAa,CAGlC,GAFA,KAAK,SAAWA,EAEZ,CAAC,KAAK,WAAW,aAAa,EACjC,OAGD,KAAK,gBAAgB,EAEjB,KAAK,aAAe,KAAK,MAAQ,KAAK,UACrC,KAAK,SAAW,IACnBD,EAAW,KAAK,MAAQ,KAAK,SACzBA,EAAW,IACdA,EAAW,KAAK,KAAKA,CAAQ,EAAI,IAInC,KAAK,WAAWA,CAAQ,IAExB,KAAK,cAAgB,CAAC,EACtB,KAAK,mBAAmB,KAAK,YAAa,KAAK,WAAW,EAE5D,CACD,CACD,CAEQ,cAAe,CACtB,KAAK,WAAW,YAAY,sBAAuB,KAAK,uBAAuB,EAC/E,KAAK,WAAW,YAAY,qBAAsB,KAAK,sBAAsB,EAC7E,KAAK,WAAW,YAAY,kBAAmB,KAAK,mBAAmB,EACvE,KAAK,WAAW,YAAY,mBAAoB,KAAK,oBAAoB,EACzE,KAAK,WAAW,YAAY,oBAAqB,KAAK,WAAW,EACjE,KAAK,WAAW,YAAY,kBAAmB,IAAM,CACpD,KAAK,OACN,CAAC,CACF,CAEQ,qBAAsB,CAC7B,IAAIE,EAAY,KAAK,UACjBF,EAAW,EAEf,KAAK,QACL,KAAK,gBAAgB,EAEjB,KAAK,aAAe,KAAK,MAAQ,KAAK,UACrC,KAAK,SAAW,IACnBA,EAAW,KAAK,MAAQ,KAAK,SACzBA,EAAW,IACdA,EAAW,KAAK,KAAKA,CAAQ,EAAI,IAInC,KAAK,YAAY,IACP,KAAK,YAAcE,GAAa,KAAK,YAAc,KAAK,UAAY,KAC1E,OAAO,OAAO,KAAK,cAAe,KAAK,YAAc,CAAC,EACzD,KAAK,YAAY,EAEjB,OAAO,KAAK,cAAc,KAAK,WAAW,EAG7C,CAEQ,qBAAwBN,GAAwE,CACvG,GAAI,CAACA,EAAO,OAEZ,IAAMf,EAAOe,EAAM,OACnB,KAAK,MAAQf,EAAK,MAClB,KAAK,gBAAgB,EAErB,IAAIgB,EAAchB,EAAK,KAAO,KAAK,WAAa,EAC5CiB,EAAajB,EAAK,KAAO,KAAK,SAE9BgB,GACChB,EAAK,OAAS,IACjB,KAAK,cAAgB,CAAC,GAEvB,KAAK,cAAciB,CAAU,EAAI,GAC7B,KAAK,cAAgBA,EACxB,KAAK,YAAY,EACP,KAAK,cAAgB,MAAQA,IAAe,EACtD,KAAK,WAAW,CAAC,EACP,KAAK,YAAc,GAAKjB,EAAK,OAAS,EAChD,KAAK,WAAW,CAAC,EACPA,EAAK,OAAS,IACpB,KAAK,cAAgB,EACxB,KAAK,YAAY,EACP,KAAK,YAAc,KAAK,UAClC,KAAK,mBAAmB,KAAM,KAAK,WAAW,EAE9C,KAAK,WAAW,KAAK,IAAI,EAAG,KAAK,UAAY,CAAC,CAAC,IAIjD,QAAQ,KAAK,2DAA2D,CAE1E,EAEA,SAASsB,EAAoB,CACxB,KAAK,WAAW,aAAa,GAAKA,IAAc,GACnD,KAAK,mBAAmB,KAAM,CAAC,GACrB,CAAC,KAAK,WAAW,cAAc,GAAKA,IAAc,KAC5D,KAAK,WAAW,gBAAgB,EAAG,KAAK,QAAQ,CAElD,CAEA,aAAc,CACb,OAAO,KAAK,aACb,CACD,ECpWO,IAAMC,EAAN,KAAsD,CACpD,WACR,YAAYC,EAA2B,CACtC,KAAK,WAAaA,CACnB,CAEA,cAAgB,IAAM,KAAK,WAAW,aAAa,YAAY,EAC/D,aAAe,IAAM,KAAK,WAAW,aAAa,WAAW,EAC7D,gBAAkB,IAAM,KAAK,WAAW,aAAa,cAAc,EACnE,gBAAkB,IAAM,KAAK,WAAW,aAAa,cAAc,EACnE,eAAiB,IAAM,KAAK,WAAW,aAAa,aAAa,EACjE,eAAiB,IAAM,KAAK,WAAW,aAAa,aAAa,EACjE,cAAiBC,GAAkB,KAAK,WAAW,aAAa,aAAcA,CAAK,EACnF,aAAgBA,GAAwC,KAAK,WAAW,aAAa,YAAaA,CAAK,EACvG,gBAAmBA,GAAkB,KAAK,WAAW,aAAa,eAAgBA,CAAK,EACvF,gBAAmBA,GAA+B,KAAK,WAAW,aAAa,eAAgBA,CAAK,EACpG,eAAkBA,GAAkB,KAAK,WAAW,aAAa,cAAeA,CAAK,EACrF,eAAkBA,GAA+B,KAAK,WAAW,aAAa,cAAeA,CAAK,CACnG,ECrBA,IAAAC,EAA0B,SAKnB,IAAMC,EAAqB,OAAO,KAAK,EAsBjCC,EAAN,KAA6C,CACnDC,GAAyB,CAAC,EAC1BC,GAAmB,KAAK,IAAI,EAAI,OAChCC,GAEA,YAAYC,EAA2B,CACtC,KAAKD,GAAUC,CAChB,CAEU,QAAU,CAACC,EAAwBC,IAA+B,CAC3E,IAAIC,EAAUF,IAAQ,KAAO,CAAE,CAACN,CAAG,EAAGO,CAAU,EAAI,CAAE,CAACP,CAAG,EAAGO,EAAW,GAAGD,CAAI,EAC/E,QAASG,KAAS,KAAKL,GACjB,OAAO,OAAOI,EAAQC,EAAM,IAAI,IACnCD,EAAuBC,EAAM,IAAe,EAAI,MAInD,OAAOD,CACR,EAEA,OAAOE,EAA0B,CAChC,OAAO,KAAK,QAAQ,CAAC,EAAGA,GAAU,KAAK,UAAU,CAAC,CACnD,CAIA,OAAOC,EAAkCJ,EAA6B,CACrE,GAAI,MAAM,QAAQI,CAAI,EAAG,CACxB,IAAIC,EAA8B,IAAI,MAAMD,EAAK,MAAM,EACvD,QAAS,EAAI,EAAG,EAAIA,EAAK,OAAQ,IAChCC,EAAQ,CAAC,EAAI,KAAK,QAAQD,EAAK,CAAC,EAAIA,EAAK,CAAC,EAAU,SAAc,KAAK,UAAU,CAAC,EAGnF,KAAKT,GAAQU,CACd,KAAO,CACN,IAAIC,EAAUN,GAAa,KAAK,UAAU,EACtCK,EAAU,KAAKV,GAAM,MAAM,EAC/BU,EAAQ,KAAK,KAAK,QAAQD,GAAQ,CAAC,EAAGE,CAAO,CAAC,EAC9C,KAAKX,GAAQU,CACd,CAEA,OAAO,KAAKV,GAAM,OAAS,CAC5B,CAEA,WAAY,CACX,OAAO,KAAKC,IACb,CAKA,SAA4BW,EAAcL,EAA6D,CACtG,GAAIK,GAAO,KACV,OAAO,KAAKZ,MAGb,aAAUY,GAAO,GAAKA,EAAM,KAAKZ,GAAM,OAAQa,EAAWD,CAAG,CAAC,EAE9D,IAAIN,EAAS,KAAKN,GAAMY,CAAG,EAC3B,OAAIL,EACKD,IAAeC,CAAK,GAAK,KAG3BD,CACR,CAEA,OAAOM,EAAaH,EAAS,CAC5B,IAAMK,EAAU,KAAKd,GAAMY,CAAG,KAC9B,aAAUA,GAAO,GAAKA,EAAM,KAAKZ,GAAM,QAAUc,EAASD,EAAWD,CAAG,CAAC,EAEzE,IAAMR,EAAM,KAAK,QAAQK,EAAMK,IAAUhB,CAAG,GAAK,KAAK,UAAU,CAAC,EACjE,YAAKE,GAAQ,KAAKA,GAAM,IAAI,CAACe,EAAGC,IAAWA,IAAUJ,EAAMR,EAAMW,CAAE,EAE5D,EACR,CAEA,QAAQH,EAAc,CACrB,OAAyBA,GAAQ,MAChC,KAAKZ,GAAQ,CAAC,EACP,QAGR,aAAUY,GAAO,GAAKA,EAAM,KAAKZ,GAAM,QAAU,KAAKA,GAAMY,CAAG,IAAM,OAAWC,EAAWD,CAAG,CAAC,EAE/F,KAAKZ,GAAQ,KAAKA,GAAM,OAAO,CAACiB,EAAGD,IAAUA,IAAUJ,CAAG,EAEnD,GACR,CAEA,IAAI,QAAS,CACZ,OAAO,KAAKZ,GAAM,MACnB,CAEA,IAAI,OAAOkB,EAAmB,CAC7B,GAAIA,EAAY,KAAKlB,GAAM,OAAQ,CAClC,IAAIU,EAAU,KAAKV,GAAM,MAAM,EAC/B,QAASmB,EAAI,EAAGA,EAAID,EAAY,KAAK,OAAQC,IAC5CT,EAAQ,KAAK,KAAK,QAAQ,CAAC,EAAG,KAAK,UAAU,CAAC,CAAC,EAGhD,KAAKV,GAAQU,CACd,MAAWQ,EAAY,KAAKlB,GAAM,SACjC,KAAKA,GAAQ,KAAKA,GAAM,MAAM,EAAGkB,CAAS,EAE5C,CACD,EC1He,SAARE,EAAmCC,EAAc,CACvD,IAAIC,EAKJ,GAJI,OAAOD,GAAW,UAAYA,IACjCC,EAAUD,EAAeE,CAAG,GAGzB,OAAW,gBAAiB,CAC/B,IAAIC,EAAS,OAAW,gBAAgBH,CAAM,EAC9C,OAAIC,IAASE,EAAeD,CAAG,EAAID,GAC5BE,CACR,CAEA,GAAIH,aAAkB,KACrB,OAAO,IAAI,KAAKA,EAAO,QAAQ,CAAC,EAC1B,GAAIA,GAAU,KACpB,OAAOA,EACD,GAAI,MAAM,QAAQA,CAAM,EAC9B,OAAOA,EAAO,IAAID,CAAc,EAC1B,GAAI,OAAOC,GAAW,SAAU,CACtC,IAAII,EAAY,CAAC,EACjB,QAASC,KAAO,OAAO,KAAKL,CAAM,EACjCI,EAAUC,CAAG,EAAIN,EAAgBC,EAAeK,CAAG,CAAC,EAGrD,OAAIJ,IAAQG,EAAUF,CAAG,EAAID,GAEtBG,CACR,CAEA,OAAOJ,CACR,ChBRA,SAASM,EAAWC,EAAa,CAChC,OAAO,OAAO,KAAKA,CAAM,EAAE,OAAS,CACrC,CAoGO,IAAMC,EAAN,cACEC,CAET,CACU,QAAU,OAAW,YACrB,YACA,iBACA,QACA,aACA,cACT,IAAI,QAA4B,CAC/B,OAAO,KAAK,QAAQ,MACrB,CACU,gBAEA,aACA,WACA,YACA,WACA,aACA,aACA,WACA,UACA,kBACA,cACA,0BACA,0BACA,0BAEV,YAAYC,EAA+B,CAC1C,MAAMC,EAAgB,EACtB,IAAIC,EAAW,KAAK,kBAAkB,EACtC,KAAK,QAAU,CACd,GAAGA,EACH,GAAGF,EACH,WAAY,OAAO,OAAO,CAAC,EAAGG,EAAMD,EAAS,UAAU,EAAGC,EAAMH,EAAQ,UAAU,CAAC,CACpF,EAEA,KAAK,WAAa,KAAK,WAAW,KAAK,IAAI,EAC3C,KAAK,QAAU,KAAK,QAAQ,KAAK,IAAI,EACrC,KAAK,eAAiB,KAAK,eAAe,KAAK,IAAI,EACnD,KAAK,UAAY,KAAK,UAAU,KAAK,IAAI,EACzC,KAAK,aAAe,KAAK,aAAa,KAAK,IAAI,EAC/C,KAAK,cAAgB,KAAK,cAAc,KAAK,IAAI,EACjD,KAAK,YAAc,KAAK,YAAY,KAAK,IAAI,EAC7C,KAAK,gBAAkB,KAAK,gBAAgB,KAAK,IAAI,EACrD,KAAK,SAAW,KAAK,SAAS,KAAK,IAAI,EACvC,KAAK,aAAe,KAAK,aAAa,KAAK,IAAI,EAC/C,KAAK,gBAAkB,KAAK,gBAAgB,KAAK,IAAI,EAErD,KAAK,cAAgB,IAAII,EAAiB,KAAK,MAAM,EACrD,KAAK,aAAe,GACpB,KAAK,WAAa,KAClB,KAAK,YAAc,GACnB,KAAK,WAAa,GAClB,KAAK,aAAe,CAAC,EACrB,KAAK,aAAe,CAAC,EACrB,KAAK,WAAa,KAAK,QAAQ,OAAO,IAAKC,GAAUA,EAAM,IAAe,EAC1E,KAAK,UAAY,CAAE,CAACC,CAAG,EAAG,KAAK,cAAc,UAAU,CAAE,EACzD,KAAK,kBAAoB,GACzB,KAAK,cAAgB,CAAC,EACtB,KAAK,0BAA4B,GACjC,KAAK,0BAA4B,GACjC,KAAK,0BAA4B,GAEjC,KAAK,aAAe,IAAIC,EAAa,IAAI,EAEzC,KAAK,YAAc,KAAK,wBAAwB,KAAK,OAAO,EAC5D,KAAK,iBAAmB,KAAK,6BAA6B,CAC3D,CAEA,qBAAuB,IAAe,KAAK,kBAC3C,iBAAmB,IAAeX,EAAW,KAAK,aAAa,EAE/D,MAAM,cAAe,CACpB,MAAO,EACR,CAEA,eAAiB,IAAY,IAAI,KAAK,KAAK,YAAc,CAAC,EAC1D,gBAAkB,IAAc,KAAK,aACrC,cAAgB,IAAc,KAAK,cAAc,EAKjD,cAAgB,IAAc,KAAK,QAAQ,WAAW,YAAc,GAEpE,mBAAqB,KACf,KAAK,kBACT,KAAK,gBAAkB,IAAIY,EAAO,CAAE,WAAY,IAAK,CAAC,GAGhD,KAAK,iBAGb,gBAAkB,IAAeZ,EAAW,KAAK,YAAY,EAE7D,SAAYa,GACP,KAAK,aAAaA,CAAK,EACnB,KAAK,aAAaA,CAAK,EAEvB,GAIT,aAAe,IAAe,KAAK,aAAe,KAClD,cAAgB,IAAe,KAAK,YACpC,iBAAmB,IAAe,KAAK,QAAQ,eAO/C,YAAeA,GACV,OAAOA,GAAU,UAAYA,EAAQ,IAAM,EAC1CA,IAAU,GACN,GAGJ,KAAK,WAAW,QAAQ,KAAK,QAAQ,aAAa,IAAM,GACpD,GAGD,KAAK,cAAcA,EAAO,KAAK,QAAQ,aAAa,IAAM,KAG3D,GAKR,gBACCC,EACAC,EACAC,EAA4B,OACnB,CACT,OAAI,OAAOF,GAAoB,SAC1B,OAAO,OAAOA,EAAiB,SAAS,GAAK,OAAO,OAAOA,EAAiB,UAAU,EAClF,KAAK,YAAY,gBACvBA,EAAgB,QAChBA,EAAgB,SAChBC,CACD,EAGM,GAED,KAAK,YAAY,gBAAgBD,EAAiBC,GAAkB,OAAQC,CAAI,CACxF,CAIA,WACCF,EACAL,EACAM,EACAC,EAA4B,OAC3B,CACD,OAAI,OAAOF,GAAoB,SAC1B,OAAO,OAAOA,EAAiB,SAAS,GAAK,OAAO,OAAOA,EAAiB,UAAU,EAClF,KAAK,YAAY,WACvBA,EAAgB,QAChBL,EACAK,EAAgB,SAChBC,CACD,EAGM,GAGD,KAAK,YAAY,WAAWD,EAAiBL,EAAOM,GAAkB,OAAQC,CAAI,CAC1F,CAEU,cAAgB,CAACC,EAAiBP,IAAkC,KAAK,cAAc,OAAOO,EAAMP,CAAG,EAKvG,gBACTG,EACAJ,EACmD,CACnD,OAAI,OAAOI,GAAU,SACb,KAAK,cAAc,SAAS,EACxBJ,EAGJI,IAAU,GAAK,KAAO,KAAK,cAAc,SAASA,EAAOJ,CAAK,EAF9DI,IAAU,GAAK,KAAK,cAAc,OAAO,KAAK,UAAUH,CAAG,CAAC,EAAI,KAAK,cAAc,SAASG,CAAK,CAI1G,CAEU,cAAgB,CAACA,EAAeI,IAAqB,KAAK,cAAc,OAAOJ,EAAOI,CAAI,EAC1F,eAAkBJ,GAA4B,KAAK,cAAc,QAAQA,CAAK,EAC9E,cAAgB,IAAc,KAAK,cAAc,OAE3D,WAAa,IAAe,CAC3B,IAAMK,EAAW,KAAK,QAAQ,EAC9B,YAAK,UAAU,KAAK,YAAY,EAE5BA,GACH,KAAK,UAAU,eAAgB,KAAK,YAAY,EAG1CA,CACR,EAEQ,uBAAyB,CAACT,EAAwBU,EAA6B,KAAmB,CACzG,GAAI,CAACA,GACJ,GAAI,KAAK,YAAY,KAAK,YAAY,GACrC,GAAI,KAAK,QAAQ,UAChB,MAAO,WAGJ,KAAK,QAAQ,UAChB,MAAO,GAIV,OAAQV,EAAM,UAAYA,EAAM,WAAa,EAC9C,EAEA,YAAc,IAAY,CACzB,KAAK,cAAc,CAAE,aAAc,KAAM,aAAc,EAAG,CAAC,EAC3D,KAAK,UAAU,eAAe,CAC/B,EAqBA,WAAWA,EAAiBW,EAAiE,CAC5F,GAAIX,IAAU,QAAaW,IAAU,OACpC,OAAOb,EAAM,KAAK,eAAe,CAAC,EAC5B,GAAIE,GAASW,IAAU,OAC7B,OAAOb,EAAM,KAAK,eAAeE,CAAK,CAAC,EACjC,GAAIA,GAASW,IAAU,OAAW,CACxC,GAAM,CAAE,aAAAC,CAAa,EAAI,KAAK,QAE9B,OAAI,KAAK,YAAY,KAAK,YAAY,KACrC,aACC,KAAK,gBAAgB,EACrB,eAAe,KAAK,qBAAqB,EAAI,GAAK,YAAY,mBAAmBA,CAAY,EAC9F,KAEA,aACC,KAAK,gBAAgB,EACrB,cAAc,KAAK,qBAAqB,EAAI,GAAK,YAAY,mBAAmBA,CAAY,EAC7F,EAGmB,KAAK,SAASZ,EAAOW,CAAK,CAG/C,CAEA,OAAO,IACR,CAEQ,YAAeH,GAClB,MAAM,QAAQA,CAAI,EACd,GACG,OAAOA,GAAS,SACnB,OAAOA,EAAK,MAAS,WAAa,MAAM,QAAQA,EAAK,IAAI,GAAK,OAAOA,EAAK,OAAU,UAGrF,GAGA,wBAA2BK,GAAkB,CACpD,GAAI,CACH,OAAW,UAAUA,EAAG,QAASA,EAAG,SAAUA,EAAG,WAAYA,EAAG,aAAcA,CAAE,CACjF,MAAc,CAEd,CAE6B,IAAI,OAAcC,EAAqB,KAAK,sBAAsB,EAAG,OAAO,CAAC,EAAE,KAC3GD,EAAG,OACJ,IAGCA,EAAG,QAAU,sKAGd,KAAK,UAAU,mBAAoBA,EAAG,OAAO,CAC9C,EAEQ,aAAe,IAA6B,CACnD,IAAIE,EAAuB,KAAK,kBAChC,YAAK,kBAAoB,GAElB,CACN,OAAQ,IAAM,CACb,KAAK,kBAAoBA,CAC1B,CACD,CACD,EAEQ,wBAAkD,KAClD,oBAAsB,MAAOC,GAA8E,CAClH,GAAM,CAAE,OAAAC,CAAO,EAAI,KAAK,aAAa,EAGrC,GAFoB,KAAK,UAAU,eAAgBD,CAAM,IAErC,GAAO,CAG1B,KAAK,UAAU,mBAAoB,IAAI,EACvCC,EAAO,EACP,MACD,CAEA,GAAI,KAAK,WAAY,CACpB,IAAMC,EAAiB,OAAO,OAAO,KAAK,aAAa,EAEvD,MAAM,QAAQ,IAAIA,EAAe,OAAQ,GAAM,EAAE,iBAAmB,IAAI,EAAE,IAAK,GAAM,EAAE,cAAc,CAAC,CACvG,CAEA,IAAIC,EAAuB,GAC3B,GAAI,CACH,IAAMC,EAAa,IAAI,gBAEnB,KAAK,0BAA4B,MACpC,KAAK,wBAAwB,MAAM,EAEpC,KAAK,wBAA0BA,EAE/B,KAAK,YAAc,GACnB,KAAK,UAAU,gBAAiB,IAAI,EAEpC,IAAIC,EAAS,MAAM,KAAK,YAAY,SAAS,CAAE,GAAGL,EAAQ,YAAa,EAAM,EAAG,CAAE,OAAQI,EAAW,MAAO,CAAC,EAY7G,GAVI,KAAK,0BAA4BA,EACpC,KAAK,wBAA0B,KAE/BD,EAAuB,GAGpBA,IACH,KAAK,YAAc,IAGhB,CAACC,EAAW,OAAO,QAAS,IAC/B,aACC,KAAK,YAAYC,CAAM,EACvB,kEAAkE,OAAOA,CAAM,EAChF,EAEA,GAAI,CACH,KAAK,mBAAmBA,CAAM,EAE1B,CAAC,MAAM,QAAQA,CAAM,GAAK,OAAQA,EAAoC,MAAS,UAClF,KAAK,2BAA2BL,EAAsCK,CAAM,CAE9E,OAASR,EAAS,CACjB,WAAK,wBAAwBA,CAAE,EAEzB,IAAI,MAAMA,EAAG,OAAO,CAC3B,CACD,CAEA,MACD,OAASA,EAAS,CAIjB,GAHIM,IACH,KAAK,YAAc,IAEhBN,EAAG,OAAS,aACf,OAGDI,EAAO,EAGN,QAAQ,MAAMJ,CAAE,KAChB,YAASA,CAAE,EAMZ,KAAK,UAAU,mBAAoBA,EAAG,OAAO,CAC9C,CACD,EAEQ,wBAAkD,KAC1D,2BAA6B,MAC5BG,EACAM,IACmB,CACf,KAAK,YAER,MAAM,QAAQ,IACb,OAAO,OAAO,KAAK,aAAa,EAC9B,OAAQC,GAAWA,EAAO,iBAAmB,IAAI,EACjD,IAAKA,GAAWA,EAAO,cAAc,CACxC,EAGD,GAAI,CACH,IAAMH,EAAa,IAAI,gBAEnB,KAAK,0BAA4B,MACpC,KAAK,wBAAwB,MAAM,EAEpC,KAAK,wBAA0BA,EAE/B,IAAMC,EAAU,MAAM,KAAK,YAAY,SAASL,EAAQ,CAAE,OAAQI,EAAW,MAAO,CAAC,EAQrF,GAJI,KAAK,0BAA4BA,IACpC,KAAK,wBAA0B,MAG5BA,EAAW,OAAO,QACrB,UAGD,aAAU,KAAK,YAAYC,CAAM,EAAG,uDAAuD,EAC3F,GAAI,CACH,IAAIG,EAAa,KAAK,cAAc,EAChCH,EAAO,MAAQG,IAClB,KAAK,cAAc,OAASH,EAAO,OAGpC,KAAK,WAAa,KAAK,IAAI,EAC3B,KAAK,UAAU,mBAAoB,CAClC,KAAMA,EAAO,KACb,MAAOC,EAAS,KAAK,OACrB,MAAOD,EAAO,KACf,CAAC,CACF,OAASR,EAAS,CACjB,WAAK,wBAAwBA,CAAE,EAEzB,IAAI,MAAMA,EAAG,OAAO,CAC3B,CACD,OAASA,EAAS,CACjB,GAAIA,EAAG,OAAS,aACf,OAKD,KAAK,UAAU,mBAAoBA,EAAG,OAAO,EAE7C,MACD,CAGD,EAEQ,kBAAoB,IAAqC,CAChE,GAAM,CAAE,GAAAY,CAAG,EAAI,OAEf,MAAO,CACN,UAAWA,GAAI,SAAS,GACxB,QAAS,EACT,WAAY,KACZ,gBAAiB,GACjB,eAAgB,GAChB,YAAa,GACb,YAAa,GACb,YAAa,GACb,eAAgB,GAChB,kBAAmB,GACnB,UAAW,GACX,UAAW,GACX,UAAW,GACX,WAAY,CACX,aAAc,GACd,YAAa,GACb,aAAc,KACd,YAAa,KACb,UAAW,CAAC,EACZ,WAAY,GACZ,aAAc,GACd,oBAAqB,CAAC,CACvB,EACA,iBAAkB,CAAC,EACnB,iBAAkB,KAClB,QAAS,KACT,cAAe,UACf,OAAQ,CAAC,CACV,CACD,EAQA,iBAAmB,IAA+B,KAAK,UAAU,KAAK,YAAY,EAElF,UAAY,MAAOrB,GAA2C,IAC7D,aAAU,CAAC,KAAK,qBAAqB,EAAG,4CAA4C,KACpF,aAAU,KAAK,gBAAgB,EAAG,sDAAsD,EAExF,IAAMsB,EAAc,KAAK,UAAU,mBAAoBtB,CAAK,EACtD,CAAE,cAAAuB,CAAc,EAAI,KAAK,QAE/B,GAAID,IAAgB,GACnB,MAAO,GAGR,IAAME,EAAW,KAAK,gBAAgBxB,EAAOuB,CAAa,EAE1D,GAAIC,IAAa,KAChB,YAAK,UAAUxB,CAAK,EAEbA,EACD,CACN,IAAMyB,EAA4B,CAAC,EAGnC,GAFAA,EAAcF,CAAa,EAAIC,EAE3B,MAAM,KAAK,YAAY,QAAQC,CAAa,EAAG,CAClD,IAAMC,EAAU,KAAK,gBAAgB,EAErC,QAASC,EAAI,EAAGA,EAAID,EAAQ,OAAQC,IAAK,CACxC,IAAIC,EAAMF,EAAQC,CAAC,EACnB,GAAIE,EAAQD,EAAIL,CAAa,EAAGC,CAAQ,EACvC,YAAK,UAAUG,CAAC,EAETA,CAET,CACD,CACD,CAEA,MAAO,EACR,EAUA,OAAUvB,IACR,CACA,CAACP,CAAG,EAAG,KAAK,cAAc,UAAU,EACpC,GAAGO,CACJ,GAOD,OAAS,MAAOwB,GAAiF,IAChG,aACC,KAAK,gBAAgB,EACrB,eAAe,KAAK,qBAAqB,EAAI,GAAK,YAAY,mBAAmB,KAAK,gBAAgB,CAAC,EACxG,EAEA,IAAIE,EAAKF,EAAI/B,CAAG,EACZkC,EAAS,CACZ,GAAG,KAAK,QAAQ,WAAW,oBAC3B,GAAGH,CACJ,EAGA,GAFkB,KAAK,UAAU,eAAgBG,CAAM,IAEnC,GACnB,OAAO,KAGR,IAAIZ,EAAS,MAAM,KAAK,YAAY,OAAOY,CAAM,EAEjD,GAAIZ,EAAQ,CACX,IAAInB,EAAQ,KAAK,cAAc,OAAOmB,EAAQW,CAAE,EAChD,YAAK,UAAU,kBAAmB9B,CAAK,EACvC,KAAK,UAAU,cAAeA,CAAK,EAC5B,KAAK,QAAQA,CAAK,CAC1B,CAEA,OAAOmB,CACR,EAEA,QAAU,SAAgC,CACzC,GAAI,CAAC,KAAK,QAAQ,EACjB,MAAO,GAGJ,KAAK,QAAQ,mBAAqB,MAAQ,KAAK,QAAQ,iBAAiB,QAAQ,GACnF,MAAM,KAAK,QAAQ,iBAAiB,QAAQ,EAG7C,IAAInB,EAAQ,KAAK,aACjB,GAAIA,IAAU,IAAM,OAAO,OAAO,KAAK,cAAeA,CAAK,GACtD,KAAK,cAAcA,CAAK,EAAE,YAC7B,aAAM,KAAK,cAAcA,CAAK,EAAE,eACzB,KAAK,QAAQ,EAItB,IAAIgC,EAAiB,KAAK,IAAI,EAC1BC,EAAU,KAAK,QAAQ,cACvBC,EAAa,KAAK,WAAW,QAAQD,CAAO,GAAK,EACjDH,EAAK9B,IAAU,GAAK,KAAO,KAAK,cAAcA,EAAOiC,CAAO,EAC5DE,EACAhB,EACAiB,EAEJ,GAAIN,IAAO,KACVK,EAAcnC,IAAU,GAAK,KAAK,UAAY,KAAK,aAAaA,CAAK,EACrEmB,EAAS,OAAO,OAAO,CAAC,EAAGgB,EAAa,KAAK,QAAQ,WAAW,mBAAmB,EACnFC,EAAkB,aACZ,CACND,EAAc,KAAK,aAAanC,CAAK,EACrCmB,EAAS,OAAO,OAAO,CAAC,EAAGgB,CAAW,EACtC,IAAIE,EAAU,KAAK,cAAcrC,EAAOiC,CAAO,EAC3CI,IAAY,OACflB,EAAOc,CAAO,EAAII,GAGnBD,EAAkB,QACnB,CAEA,IAAId,EAAc,KAAK,UAAU,eAAgBH,CAAM,EACnDmB,EAAmB,KAAK,QAAQ,iBAAiB,SAAe,UAMpE,GAJI,KAAK,QAAQ,oBAAsB,IAAQ,KAAK,WAAW,QAAQA,CAAgB,IAAM,IAAMtC,IAAU,KAC5GmB,EAAOmB,CAAgB,EAAI,KAAK,WAAWA,CAAgB,GAGxDhB,IAAgB,GACnB,MAAO,GAGR,KAAK,UAAU,UAAU,EAEzB,IAAIiB,EAAmB,KAAK,mBAAmBpB,CAAM,EACrD,GAAIoB,EACH,WAAK,UAAU,eAAgBvC,CAAK,EAC9B,IAAI,MAAMuC,CAAgB,EAGjC,IAAIC,EAAe,OAAO,OAAO,CAAC,EAAGL,CAAW,EAehD,GAZA,KAAK,OAAO,QAASvC,GAAU,CAC1BA,EAAM,UACLA,EAAM,OAAS,KAAK,QAAQ,eAAiB,OAAO,OAAOuB,EAAQvB,EAAM,IAAI,GAChF,OAAOuB,EAAOvB,EAAM,IAAe,EAGhC,OAAO,OAAO4C,EAAc5C,EAAM,IAAI,GACzC,OAAO4C,EAAa5C,EAAM,IAAe,EAG5C,CAAC,EAEG,OAAO,KAAK4C,CAAY,EAAE,OAAS,EAAG,CACzC,IAAIC,EACAzC,IAAU,IACbyC,EAAW,KAAK,cAAc,KAAM,KAAK,UAAU5C,CAAG,CAAC,EACvD,OAAO,KAAK,aAAa4C,CAAQ,EACjC,KAAK,aAAeA,EACpB,KAAK,UAAU,kBAAmBA,CAAQ,EAC1C,KAAK,UAAU,EAAE,IAEjBA,EAAWzC,EACX,OAAO,KAAK,aAAaA,CAAK,GAG/B,IAAI0C,EACC,OAAO,OAAO,KAAK,cAAeD,CAAQ,GAO9CC,EAAc,KAAK,cAAc1C,CAAK,EACtC0C,EAAY,gBAPZA,EAAc,CACb,YAAa,EACb,eAAgB,IACjB,EACA,KAAK,cAAc1C,CAAK,EAAI0C,GAM7B,KAAK,WAAa,GAClBA,EAAY,eAAiB,KAAK,YAAYN,CAAe,EAAEjB,EAAQ,MAAS,EAEhF,IAAIwB,GAAqB,IAAM,CAC1BF,IAAa,MAChB,OAAO,KAAK,cAAcA,CAAQ,EAG/B,OAAO,KAAK,KAAK,aAAa,EAAE,SAAW,IAC9C,KAAK,WAAa,GAEpB,EAEIxB,EACJ,GAAI,CAkBH,GAjBAA,EAAS,MAAMyB,EAAY,eAIvBV,GAAkB,KAAK,YAAc,KACpCF,IAAO,KAIVW,EAAW,MAEPA,GAAY,KAAK,cAAc,GAAMP,GAAc,KAAK,gBAAgBO,EAAUR,CAAO,IAAMH,KAClGW,EAAW,KAAK,qBAAqBX,CAAE,IAKtCW,IAAa,KAAM,CAEtB,OAAO,KAAK,aAAazC,CAAK,EAE1BiB,IAAW,KACd,KAAK,cAAcwB,EAAUxB,CAAM,EAEnC,QAAQ,KAAK,0DAA0D,EAGxE,IAAIb,EAAO,KAAK,gBAAgBqC,CAAQ,EAExC,OAAK,KAAK,QAAQA,CAAQ,GACzB,KAAK,UAAUA,EAAU,EAAI,EAG9BE,GAAmB,EACnB,KAAK,UAAU,cAAeF,CAAQ,EAE/BrC,CACR,MACC,OAAO,KAAK,aAAaJ,CAAK,CAEhC,OAAS4C,EAAO,CAqBf,GApBIH,IAAa,MAAQ,CAAC,KAAK,QAAQA,CAAQ,IAC9C,KAAK,aAAaA,CAAQ,EAAIN,GAG3BM,IAAa,OACZP,GAAc,KAAK,gBAAgBO,EAAUR,CAAO,IAAMH,IAC7DW,EAAW,KAAK,qBAAqBX,CAAgB,GAElDW,IACH,KAAK,aAAaA,CAAQ,EAAIN,IAIhCQ,GAAmB,EAEfF,GAAY,OACf,KAAK,aAAaA,CAAQ,EAAI,GAC9B,KAAK,UAAU,eAAgBA,CAAQ,GAGnCG,GAAe,OAAS,aAC5B,MAAMA,CAER,QAAE,CACDF,EAAY,eAAiB,KAC7BA,EAAY,aACb,CACD,KACC,aAAK,UAAU1C,CAAK,EACb,GAGR,MAAO,EACR,EAQA,YAAeJ,GACd,KAAK,SAASA,EAAO,KAAK,cAAc,KAAK,aAAcA,CAAK,CAAe,EACtE,cAAiBiD,GAA+B,KAAK,OAAO,UAAWC,GAAMA,EAAE,OAASD,CAAS,EAE3G,mBAAsBjD,GAA+C,KAAK,OAAO,KAAMkD,GAAMA,EAAE,OAASlD,CAAK,EAe7G,UAAUiD,EAA+E,CACxF,GAAIA,EAAW,CACd,QAASlB,EAAI,EAAGA,EAAI,KAAK,OAAO,OAAQA,IAAK,CAC5C,IAAI/B,EAAQ,KAAK,OAAO+B,CAAC,EACzB,GAAI/B,EAAM,OAASiD,EAClB,OAAO,OAAO,OAAO,CAAC,EAAGjD,EAAO,CAC/B,WAAS,sBAAmBA,EAAM,SAAWA,EAAM,IAAI,CACxD,CAAC,CAEH,CAEA,MACD,KACC,QAAO,KAAK,OAAO,IAAKA,GACvB,OAAO,OAAO,CAAC,EAAGA,EAAO,CACxB,WAAS,sBAAmBA,EAAM,SAAWA,EAAM,IAAI,CACxD,CAAC,CACF,CAEF,CASA,YAAYiD,EAAoB,CAC/B,IAAIE,EAAY,KAAK,QAAQ,UAE7B,MAAI,WAAW,KAAKA,CAAS,IAC5BA,EAAYA,EAAU,UAAU,EAAGA,EAAU,OAAS,CAAC,GAGjD,IAAIC,EAAa,CAAE,WAAY,KAAM,UAAAD,EAAW,UAAAF,CAAU,CAAC,CACnE,CAEA,SAAYA,GAA+B,KAAK,OAAO,KAAMC,GAAMA,EAAE,OAASD,CAAS,EAKvF,WAAcA,GAA+B,CAC5C,QAASjD,KAAS,KAAK,OACtB,GAAIA,EAAM,OAASiD,EAClB,OAAO,KAAK,uBAAuBjD,CAAK,EAI1C,MAAO,EACR,EAEQ,SAA4BA,EAAUW,EAAsB,CACnE,IAAM0C,EAAa,KAAK,cAAcrD,CAAK,EACrCsD,EAAkB,KAAK,OAAOD,CAAU,KAE9C,aAAUC,EAAiB,UAAUtD,CAAe,qCAAqC,EAGrF,OAAOW,GAAU,UAAYA,IAAU,KACzCA,EAAwB,SAI1B,aACC4C,EAAW,KAAK,aAAaD,EAAiB3C,CAAK,CAAC,EAAE,SAASA,CAAK,EACpE,mBAAmBX,CAAe,yBACnC,EAEA,IAAIuC,EAAc,KAAK,eAAiB,GAAK,KAAK,UAAY,KAAK,aAAa,KAAK,YAAY,EAE3FiB,EAAa,KAAK,gBAAgB,KAAK,aAAcxD,CAAK,EAEhE,GAAIiC,EAAQuB,EAAY7C,CAAK,EAC5B,OAAI,KAAK,QAAQ2C,EAAgB,IAAI,GACpC,OAAOf,EAAYe,EAAgB,IAAe,EAC7C/D,EAAWgD,CAAW,IACtB,KAAK,eAAiB,IACzB,OAAO,KAAK,aAAa,KAAK,YAAY,EAE3C,KAAK,UAAU,iBAAkB,EAAK,GAEvC,KAAK,UAAU,iBAAkB,CAChC,KAAMvC,EACN,MAAAW,CACD,CAAC,EAEM,IAEA,GAGR,GAAI4B,GAAeN,EAAQM,EAAYe,EAAgB,IAAe,EAAG3C,CAAK,EAC7E,MAAO,GACD,CACN,IAAMF,EAAW8B,GAAehD,EAAWgD,CAAW,EAEtD,OAAI,KAAK,eAAiB,IAAM,CAACA,IAChC,KAAK,aAAa,KAAK,YAAY,EAAIA,EAAc,CAAC,GAGvDA,EAAYe,EAAgB,IAAe,EAAI3C,EAE1CF,GACJ,KAAK,UAAU,iBAAkB,EAAI,EAGtC,KAAK,UAAU,iBAAkB,CAChC,KAAMT,EACN,MAAAW,CACD,CAAC,EAEM,EACR,CAEF,CAEQ,cAAiCP,EAAeJ,EAAuB,CAC9E,OAAO,KAAK,gBAAgBI,EAAOJ,CAAK,CACzC,CAkBA,QAA2BI,EAAgB6C,EAAe,CACzD,OAAI7C,IAAU,QACb,KAAK,gBAAgBA,CAAK,EACtB6C,IAAc,WACjB,aACC,KAAK,SAASA,CAAmB,EACjC,GAAG,KAAK,sBAAsB,CAAC,iCAAiCA,CAAmB,GACpF,EAEO,KAAK,gBAAgB7C,EAAO6C,CAAS,GAErC,KAAK,gBAAgB7C,CAAK,GAG3B,KAAK,gBAAgB,CAE9B,CAEU,sBAAwB,IAC7B,KAAK,QAAQ,aACT,mBAAqB,KAAK,QAAQ,aAElC,mBAMT,eAAkCJ,EAAwC,CACzE,IAAMuC,GACJ,KAAK,eAAiB,GAAK,KAAK,UAAY,KAAK,aAAa,KAAK,YAAY,IAAO,CAAC,EAEzF,GAAI,OAAOvC,GAAU,SAAU,CAC9B,IAAIyD,EAAe,KAAK,gBAAgB,KAAK,YAAY,GAAM,CAAC,EAEhE,MAAO,CACN,GAAGA,EACH,GAAGlB,EACH,CAACtC,CAAG,EAAGwD,IAAUxD,CAAG,GAAMsC,EAA0CtC,CAAG,CACxE,CACD,KACC,QAAI,OAAO,OAAOsC,EAAavC,CAAK,EAC5BuC,EAAYvC,CAAK,GAAK,KAEtB,KAAK,gBAAgB,KAAK,aAAcA,CAAK,CAGvD,CAEA,qBAAwB4B,GAAwC,CAC/D,IAAM8B,EAAW,KAAK,cAAc,EAEpC,QAAS3B,EAAI,EAAGA,EAAI2B,EAAU3B,IAC7B,GAAI,KAAK,gBAAgBA,EAAG,KAAK,QAAQ,aAAa,IAAMH,EAC3D,OAAOG,EAIT,OAAO,IACR,EAEQ,wBAA2BpC,GAAkD,CACpF,GAAM,CAAE,UAAAwD,EAAW,YAAAQ,EAAa,aAAA/C,EAAc,QAAAgD,CAAQ,EAAIjE,EAG1D,GAAIgE,aAAuBE,EAC1B,OAAOF,EAIR,GAAIA,GAAe,OAAOA,GAAgB,UACrC,OAAO,OAAOA,EAAa,MAAM,GAAK,OAAO,OAAOA,EAAa,SAAS,EAAG,CAChF,GAAM,CAAE,QAAAhE,EAAS,KAAAY,CAAK,EAAIoD,EAE1B,GAAI,OAAOpD,GAAS,YAAc,OAAW,IAAI,KAAM,CACtD,IAAMuD,EAAW,OAAW,GAAG,KAAavD,CAAI,EAEhD,GAAI,OAAOuD,GAAY,WAEtB,OAAO,IAAIA,EAAQnE,CAAO,CAE5B,SAAW,OAAOY,GAAS,WAAY,CACtC,IAAMuD,EAAUvD,EAChB,OAAO,IAAIuD,EAAQnE,CAAO,CAC3B,CACD,CAGD,OAAO,IAAIoE,EAAoB,CAAE,UAAAZ,EAAW,aAAAvC,EAAc,OAAQjB,EAAQ,OAAQ,QAAAiE,CAAQ,CAAC,CAC5F,EAEQ,mBAAsBtC,GAAkC,CAC/D,IAAMb,EAAW,KAAK,QAAQ,EAC9B,GAAI,MAAM,QAAQa,CAAQ,EACzB,KAAK,eAAe,EACpB,KAAK,aAAe,CAAC,EACrB,KAAK,cAAc,OAAOA,CAAQ,EAElC,KAAK,WAAa,KAAK,IAAI,EAC3B,KAAK,aAAe,KAAK,QAAQ,gBAAkBA,EAAS,OAAS,EAAI,GAEzE,KAAK,UAAU,eAAgBA,EAAS,MAAM,EAC9C,KAAK,UAAU,wBAAyB,KAAK,YAAY,EAErDb,GACH,KAAK,UAAU,iBAAkB,EAAK,UAE7B,OAAOa,EAAS,MAAS,UAAY,MAAM,QAAQA,EAAS,IAAI,EAC1E,GAAIA,EAAS,OAAS,EAAG,CACxB,KAAK,eAAe,EACpB,KAAK,aAAe,CAAC,EACrB,IAAM0C,EAAe,CAAC,EAEtB,QAAS,EAAI,EAAG,EAAI1C,EAAS,KAAK,OAAQ,IACzC0C,EAAQ,EAAI1C,EAAS,IAAI,EAAIA,EAAS,KAAK,CAAC,EAG7C,QAASC,KAAUyC,EAClB,KAAK,cAAczC,CAAM,EAG1B,KAAK,WAAa,KAAK,IAAI,EAE3B,KAAK,UAAU,sBAAuB,CACrC,KAAMD,EAAS,KACf,MAAOA,EAAS,KAAK,OACrB,MAAOA,EAAS,KACjB,CAAC,EAED,KAAK,WAAW,KAAK,QAAQ,gBAAkB0C,EAAQ,OAAS,EAAI,EAAE,EAElEvD,GACH,KAAK,UAAU,iBAAkB,EAAK,CAExC,KAAO,CACN,QAASsB,EAAI,EAAGA,EAAIT,EAAS,KAAK,OAAQS,IACzC,KAAK,cAAcA,EAAIT,EAAS,KAAMA,EAAS,KAAKS,CAAC,CAAC,EACtD,OAAO,KAAK,aAAaA,EAAIT,EAAS,IAAI,EAG3C,KAAK,WAAa,KAAK,IAAI,EAC3B,KAAK,UAAU,sBAAuB,CACrC,KAAMA,EAAS,KACf,MAAOA,EAAS,KAAK,OACrB,MAAOA,EAAS,KACjB,CAAC,CACF,KAEA,OAAM,IAAI,UAAU,sDAAsD,CAE5E,EASA,KACC2C,GAC+B,KAAK,QAAQ,EAAE,KAAKA,CAAS,EAS7D,UAAaA,GACZ,KAAK,QAAQ,EAAE,UAAUA,CAAS,EAMnC,OAAUA,GACT,KAAK,QAAQ,EAAE,OAAOA,CAAS,EAMhC,IAAUC,GACT,KAAK,QAAQ,EAAE,IAAIA,CAAU,EAM9B,QAAWC,GACV,KAAK,QAAQ,EAAE,QAAQA,CAAU,EAElC,QAAWC,GAAgD,CAC1D,GAAIA,IAAqB,OAAW,CACnC,IAAM7B,EAAc,KAAK,eAAiB,GAAK,KAAK,UAAY,KAAK,aAAa,KAAK,YAAY,EAEnG,MAAO,CAAC,EAAEA,GAAehD,EAAWgD,CAAW,EAChD,CAEA,GAAI,OAAO6B,GAAqB,UAAYA,EAAmB,IAAM,EAAG,CACvE,IAAM7B,EAAc6B,IAAqB,GAAK,KAAK,UAAY,KAAK,aAAaA,CAAgB,EAEjG,MAAO,CAAC,EAAE7B,GAAehD,EAAWgD,CAAW,EAChD,SAAW,OAAO6B,GAAqB,SAAU,CAChD,IAAM7B,EAAc,KAAK,eAAiB,GAAK,KAAK,UAAY,KAAK,aAAa,KAAK,YAAY,EAEnG,MAAO,CAAC,EAAEA,GAAe,OAAO,OAAOA,EAAa6B,CAAgB,EACrE,CAEA,MAAO,EACR,EAEA,SAAYhE,GACPA,IAAU,OACN,OAAO,OAAO,KAAK,cAAe,KAAK,YAAY,EAGvD,OAAOA,GAAU,UAAYA,EAAQ,IAAM,EACvC,OAAO,OAAO,KAAK,cAAeA,CAAK,EAGxC,GAGA,UAAY,CAACiE,EAAiBC,IAAwB,CAC7D,IAAMlE,EAAQiE,IAAW,OAAYA,EAAS,KAAK,gBAAgB,EAC7D5D,EAAW6D,IAAc,OAAYA,EAAY,KAAK,QAAQ,EAEpE,GAAIlE,IAAU,GACb,KAAK,UAAY,CAAE,CAACH,CAAG,EAAG,KAAK,cAAc,UAAU,CAAE,MACnD,CACN,GAAM,CAAE,cAAA0B,CAAc,EAAI,KAAK,QAG/B,GAFyB,KAAK,WAAW,SAASA,CAAa,GAEvC,KAAK,cAAcvB,EAAOuB,CAAa,IAAM,KAAM,CAC1E,KAAK,UAAUvB,CAAK,EAEpB,MACD,MACC,OAAO,KAAK,aAAaA,CAAK,EAC9B,OAAO,KAAK,aAAaA,CAAK,CAEhC,CAEIA,IAAU,KAAK,cAAgBK,GAClC,KAAK,UAAU,iBAAkB,EAAK,EAGvC,KAAK,UAAU,oBAAqBL,CAAK,CAC1C,EAEA,oBAAsB,IAA8B,KAAK,QAAQ,iBAEzD,2BAA8BmE,GAAwC,CAC7E,GAAM,CAAE,WAAAC,EAAY,WAAAC,CAAW,EAAI,KAAK,QAClCC,EAAkCD,EAAW,qBAAuB,CAAC,EACrEE,EAAYJ,EAAiB,WAAW,EAC1CK,EAAU,GAGd,MADA,aAAUJ,EAAY,iDAAiD,EACnE,MAAM,QAAQA,CAAU,EAC3B,QAASvB,KAAauB,EACjB,OAAO,OAAOG,EAAW1B,CAAS,GAAKyB,EAAoBzB,CAAoB,IAAM0B,EAAU1B,CAAS,IAC3GyB,EAAoBzB,CAAS,EAAI0B,EAAU1B,CAAS,EACpD2B,EAAU,QAIZ,SAASC,KAAa,OAAO,KAAKL,CAAU,EAAG,CAC9C,IAAIM,EAAaN,EAAWK,CAAoB,EAE/C,OAAO,OAAOF,EAAWG,CAAU,GACnCJ,EAAoBG,CAAoB,IAAMF,EAAUG,CAAU,IAElEJ,EAAoBG,CAAoB,EAAIF,EAAUG,CAAU,EAChEF,EAAU,GAEZ,CAGGA,IACH,KAAK,QAAQ,WAAW,oBAAsBF,EAC9C,KAAK,kBAAoB,GACzB,KAAK,UAAU,qBAAsB,CACpC,KAAM,sBACN,MAAOA,CACR,CAAC,EAEH,EAEQ,aAAgBH,GAAwC,CAC/DA,EAAiB,YAAY,yBAA0B,MAAOQ,GAA+B,CAC5F,GAAI,CAAE,OAAQ3E,CAAM,EAAI2E,EAExB,GADgB,KAAK,UAAU,wBAAyB3E,CAAK,IAC3C,GACjB,MAAO,GAGR,GAAI,CACH,MAAM,KAAK,QAAQ,CACpB,MAAgB,CACf,MAAO,EACR,CACD,CAAC,EAEDmE,EAAiB,YAAY,eAAgB,SAAY,CAExD,GADgB,KAAK,UAAU,qBAAsB,IAAI,IACvC,GACjB,MAAO,GAGR,GAAI,CACH,MAAM,KAAK,QAAQ,CACpB,MAAgB,CACf,MAAO,EACR,CACD,CAAC,EAEDA,EAAiB,YAAY,wBAAyB,MAAOQ,GAA+B,CAC3F,GAAI,CAAE,OAAQ3E,CAAM,EAAI2E,EAGxB,GAFA,KAAK,2BAA2BR,CAAgB,EAE5CnE,IAAU,GAAI,CAIjB,GAFgB,KAAK,UAAU,eAAgB,KAAK,QAAQ,UAAU,IAEpD,GACjB,MAAO,GAGR,KAAK,yBAAyB,MAAM,EACpC,KAAK,yBAAyB,MAAM,EACpC,KAAK,mBAAmB,CAAC,CAAC,CAC3B,MAAW,KAAK,QAAQ,kBAAoB,IAC3C,KAAK,kBAAkB,CAEzB,CAAC,EAEDmE,EAAiB,YAAY,iBAAkB,IAAM,CACpD,KAAK,2BAA2BA,CAAgB,CACjD,CAAC,EAEDA,EAAiB,YAAY,cAAgBQ,GAA+B,CAC3E,GAAI,CAAE,OAAQ3E,CAAM,EAAI2E,EAEpB,KAAK,gBAAgB,IAAM3E,IAC9B,KAAK,2BAA2BmE,CAAgB,EAE5C,KAAK,qBAAqB,GAAK,KAAK,QAAQ,kBAAoB,IACnE,KAAK,kBAAkB,EAG1B,CAAC,EAED,KAAK,2BAA2BA,CAAgB,CACjD,EAEQ,6BAA+B,IAA8B,CAEpE,GAAI,CAAE,WAAAC,EAAY,iBAAAD,CAAiB,EAAI,KAAK,QAE5C,GAAI,KAAK,QAAQ,iBAAkB,CAUlC,GARC,OAAOA,GAAqB,UAC5B,OAAO,OAAO,OAAYA,CAAgB,GAC1C,OAAO,OAAWA,CAAgB,GAAM,WAExC,KAAK,QAAQ,iBAAmB,OAAWA,CAAgB,MAG5D,aAAUC,EAAY,6CAA6C,EAC/D,MAAM,QAAQA,CAAU,KAC3B,aAAUA,EAAW,SAAW,EAAG,yCAAyC,UAClE,OAAOA,GAAe,YAChC,aAAU,OAAO,KAAKA,CAAU,EAAE,SAAW,EAAG,yCAAyC,MAEzF,OAAM,IAAI,UAAU,iDAAiD,EAGtE,YAAK,aAAa,KAAK,QAAQ,gBAAgB,EAExC,KAAK,QAAQ,gBACrB,CAEA,OAAO,IACR,EAKA,gBAAkB,IAAc,KAAK,QAAQ,aAK7C,cAAgB,IAAgE,KAAK,QAAQ,WAK7F,iBAAmB,IAAe,KAAK,QAAQ,cAE/C,mBAAqB,IAAe,KAAK,QAAQ,gBAIjD,YAA+BxE,EAAqB,CACnD,OAAIA,IAAU,OACN,KAAK,gBAAgB,KAAK,YAAY,EAEtC,KAAK,cAAc,KAAK,aAAcA,CAAK,CAEpD,CAOA,aAAoDgF,EAAmC,CACtF,GAAM,CAAE,WAAAP,CAAW,EAAI,KAAK,QAC5B,sBAAU,OAAO,OAAOA,EAAYO,CAAI,EAAG,4DAA4D,EAChGlF,EAAM2E,EAAWO,CAAI,CAAC,CAC9B,CAQA,aAAoDA,EAASrE,EAAuC,CACnG,GAAM,CAAE,WAAA8D,CAAW,EAAI,KAAK,QAE5B,GAAIO,IAAS,gBAAkBA,IAAS,cAAe,CACjDrE,IACJA,EAAQ,IAGT,IAAMsE,EAAYD,IAAS,eAAiB,eAAiB,cAC7D,KAAK,aAAaC,EAAW,IAAI,CAClC,IAEA,aACC,OAAO,OAAOR,EAAYO,CAAI,GAAKA,IAAS,sBAC5C,0DAA4DA,CAC7D,EAEA,IAAMC,EAAaR,EAAmBO,CAAI,KAE1C,aAAU,OAAOC,GAAc,OAAOtE,EAAO,iDAAmD,OAAOA,CAAK,EAEvGsB,EAAQgD,EAAWtE,CAAK,IAC5B8D,EAAWO,CAAI,EAAIrE,EACnB,KAAK,kBAAoB,GAErBqE,IAAS,cACZ,OAAW,IAAI,OAAO,aAAa,IAClC,GAAG,OAAW,IAAI,QAAQ,EAAE,IAAI,KAAK,gBAAgB,CAAC,YACtDrE,EACA,EACD,EAGD,KAAK,UAAU,qBAAsB,CAAE,KAAAqE,EAAM,MAAArE,CAAM,CAAC,EAEtD,CAEA,cAAc8D,EAAkD,CAC/D,OAAS,CAACQ,EAAWtE,CAAK,IAAK,OAAO,QAAQ8D,CAAU,EACvD,KAAK,aAAaQ,EAAWtE,CAAK,CAEpC,CAEQ,aAAaX,EAAwBW,EAAoB,CAChE,IAAIJ,EAAOP,EAAM,MAAQkF,EAAUvE,CAAK,EACxC,MAAI,CAACX,EAAM,MAAQW,IAAU,OAC5BX,EAAM,KAAOO,GAGPA,CACR,CAEA,oBAAsB,IAAe,KAAK,aAAa,KAAK,YAAY,EAExE,aAAgBH,GACX,KAAK,YAAYA,CAAK,EAClB,KAAK,gBAAgB,EAErB,KAAK,gBAAgB,EAI9B,qBAAuB,IAAe,CAAC,KAAK,QAAQ,YACpD,qBAAuB,IAAe,CAAC,KAAK,QAAQ,YACpD,qBAAuB,IAAe,CAAC,KAAK,QAAQ,YAOpD,gBAAkB,IAAe,KAAK,QAAQ,aAAe,CAAC,KAAK,0BAOnE,gBAAkB,IAAe,KAAK,QAAQ,aAAe,CAAC,KAAK,0BAOnE,gBAAkB,IAAe,KAAK,QAAQ,aAAe,CAAC,KAAK,0BAEnE,eAAkB+E,GAAyB,CAC1C,IAAMC,EAAW,CAACD,EACd,KAAK,4BAA8BC,IACtC,KAAK,0BAA4BA,EACjC,KAAK,UAAU,uBAAwB,CAACA,CAAQ,EAElD,EAEA,eAAkBD,GAAyB,CAC1C,IAAMC,EAAW,CAACD,EACd,KAAK,4BAA8BC,IACtC,KAAK,0BAA4BA,EACjC,KAAK,UAAU,uBAAwB,CAACA,CAAQ,EAElD,EAEA,eAAkBD,GAAyB,CAC1C,IAAMC,EAAW,CAACD,EACd,KAAK,4BAA8BC,IACtC,KAAK,0BAA4BA,EACjC,KAAK,UAAU,uBAAwB,CAACA,CAAQ,EAElD,EAEA,kBAAoB,SAA+B,MAAM,KAAK,WAAW,KAAK,YAAY,EAElF,kBAAoB,SAAY,CACvC,IAAIhE,EAAa,IAAI,gBACjB,CAAE,OAAAiE,CAAO,EAAIjE,EAEbkE,EAAO,IAAI,QAAc,CAACC,EAASC,IAAW,CACjD,KAAK,YAAY,eAAgB,IAAMD,EAAQ,EAAG,CAAE,OAAAF,CAAO,CAAC,EAC5D,KAAK,YAAY,sBAAuB,IAAME,EAAQ,EAAG,CAAE,OAAAF,CAAO,CAAC,EACnE,KAAK,YAAY,mBAAqBI,GAAQD,EAAOC,EAAI,MAAM,EAAG,CAAE,OAAAJ,CAAO,CAAC,CAC7E,CAAC,EAED,GAAI,CACH,MAAMC,CACP,OAAStC,EAAO,CACf,MAAMA,CACP,QAAE,CACD5B,EAAW,MAAM,CAClB,CACD,EAEA,kBAAoB,MAAOzB,EAAuC,CAAC,IAAqB,CAKvF,GAJIA,EAAQ,YACX,KAAK,cAAcA,EAAQ,UAAU,EAGlC,OAAK,QAAQ,GAEZ,CADiB,MAAM,KAAK,aAAa,KAAK,IAAI,GAMvD,IAAI,KAAK,cAAc,GAAK,CAAC,KAAK,qBAAqB,EACtD,GAAI,CACH,OAAO,MAAM,KAAK,kBAAkB,CACrC,MAAgB,CACf,MACD,CAGG,KAAK,QAAQ,iBAAmB,GACnC,KAAK,gBAAgB,EAAG,KAAK,QAAQ,WAAW,YAAc,EAAE,EAAE,MAAM,IAAM,IAAI,EAElF,KAAK,oBAAoB,CAAE,GAAG,KAAK,QAAQ,UAAW,CAAC,EAAE,MAAM,IAAM,IAAI,EAG1E,GAAI,CACH,MAAM,KAAK,kBAAkB,CAC9B,OAASqD,EAAO,CACf,GAAIrD,EAAQ,MACX,MAAMqD,CAER,EACD,EAEA,WAAa,MAAO5C,GAAqC,CAExD,GAAI,KAAK,cAAc,EACtB,OAGD,IAAMsF,EAAQ,KAAK,IAAI,EACjBrD,EAAU,KAAK,QAAQ,cACvBH,EAAK,KAAK,cAAc9B,EAAOiC,CAAO,EACtCrB,EAAsE,CAC3E,aAAc,GACd,YAAa,GACb,UAAW,CAAC,EACZ,oBAAqB,CAAC,EACtB,YAAa,EACd,EAEAA,EAAO,oBAAoBqB,CAAO,EAAIH,EAEtC,GAAI,CACH,IAAMb,EAAS,MAAM,KAAK,YAAY,SAASL,CAAM,EAIrD,GAAI,KAAK,aAAe,MAAQ0E,EAAQ,KAAK,WAAY,CAExD,GAAItF,GAAS,KAAK,cAAc,GAAK,KAAK,gBAAgBA,EAAOiC,CAAO,IAAMH,EAAI,CACjF,IAAIyD,EAAc,KAAK,qBAAqBzD,CAAE,EAE9C,GAAIyD,IAAgB,KACnB,OAGDvF,EAAQuF,CACT,CAGA,GAAIvF,IAAU,KACb,MAEF,IAEA,aAAU,MAAM,QAAQiB,CAAM,EAAG,6DAA6D,OAAOA,CAAM,EAAE,KAC7G,aAAUA,EAAO,SAAW,EAAG,iDAAiDA,EAAO,MAAM,QAAQ,EACrG,IAAMW,EAAMX,EAAO,CAAC,EAEpB,sBACCW,GAAOC,EAAQD,EAAIK,CAAO,EAAGH,CAAE,EAC/B,wCAAwCG,CAAiB,QAAQH,CAAE,WAAWG,CAAiB,QAC9FL,EAAIK,CAAO,CACZ,GACD,EAEA,KAAK,cAAcjC,EAAO4B,CAAG,EAC7B,KAAK,UAAU5B,CAAK,EAEbiB,EAAO,CAAC,CAChB,OAAS2B,EAAY,CACpB,GAAIA,EAAM,OAAS,aAClB,WAAK,UAAU,mBAAoBA,EAAM,OAAO,EAC1CA,CAER,CACD,EAEA,UAAa5C,GAAkB,CAC9B,IAAIwF,EAAe,KAAK,gBAAgBxF,CAAK,EACzCyF,EACAD,IAAiB,OACpBC,EAASD,EAAkC3F,CAAG,EAC9C,KAAK,eAAeG,CAAK,GAG1B,OAAO,KAAK,aAAaA,CAAK,EAE1BA,IAAU,KAAK,cAGd,KAAK,cAAc,GAAKA,GAC3B,KAAK,eAGN,KAAK,UAAU,kBAAmBA,CAAK,EACvC,KAAK,UAAU,mBAAoB,CAAE,MAAAA,EAAO,IAAKyF,CAAM,CAAC,EAExD,KAAK,UAAU,wBAAyB,KAAK,YAAY,IAGrDzF,EAAQ,KAAK,cAChB,KAAK,eAGN,KAAK,UAAU,kBAAmBA,CAAK,EACvC,KAAK,UAAU,mBAAoB,CAAE,MAAAA,EAAO,IAAKyF,CAAM,CAAC,EAG1D,EAEA,gBAAkB,MAAOC,EAAcC,IAAsC,CAC5E,IAAMtB,EAAa,CAClB,GAAG,KAAK,QAAQ,WAChB,KAAAqB,EACA,WAAAC,CACD,EAEA,MAAM,KAAK,oBAAoBtB,CAAU,CAC1C,EAEA,KAAO,MAAOjE,GAAyC,CACtD,QAASR,KAASQ,EACjB,KAAK,WAAWR,EAAOQ,EAAKR,CAAK,CAAe,EAGjD,OAAO,MAAM,KAAK,QAAQ,CAC3B,EAqDA,gBACCgG,EACAC,EAC6B,CAC7B,IAAI7F,EAAgB,OAAO4F,GAAqB,WAAa,KAAK,UAAUA,CAAgB,EAAIA,EAKhG,GAHA,KAAK,gBAAgB5F,CAAK,EAET,KAAK,QAAQ,GACd,KAAK,eAAiBA,EAAO,CAC5C,IAAM8F,EAAO,KAAK,QAAQ,EAE1B,GAAID,EACH,OAAOC,EAAK,KAAM7E,GACZA,EAIE,KAAK,WAAWjB,CAAK,EAHpB,EAIR,CAEH,CAEA,OAAO,KAAK,WAAWA,CAAK,CAC7B,CAEQ,WAAa,MAAOA,IAC3B,KAAK,gBAAgBA,CAAK,EAER,KAAK,UAAU,yBAA0BA,CAAK,IAE5C,GACZ,IAGR,KAAK,aAAeA,EACpB,KAAK,UAAU,wBAAyB,KAAK,YAAY,EAElD,KAGA,gBAAmBA,GAAkB,IAC5C,aAAUA,GAAS,IAAMA,EAAQ,KAAK,cAAc,EAAG,0CAA0CA,CAAK,EAAE,CACzG,EAEA,cAAcJ,EAAiCW,EAA2B,CACzE,IAAIwF,EAAW,OAAOnG,GAAU,SAAW,KAAK,mBAAmBA,CAAe,EAAIA,EACtF,OAAKmG,EAIDxF,IAAU,MAAQ,CAAC,KAAK,uBAAuBwF,CAAQ,EACnDA,EAAS,KAAO,mBAGpBA,EAAS,MAAQ,CAAC5C,EAAW4C,EAAS,IAAI,EAAE,SAASxF,CAAK,EACtDwF,EAAS,KAAO,yBAGjB,GAXC,UAAUnG,CAAK,kBAYxB,CAEQ,mBAAmBuB,EAAoB,CAC9C,IAAI6E,EAAmB,OAAO,KAAK7E,CAAM,EAErCF,EAAS,KAAK,OAChB,IAAKrB,GAAU,CACf,GAAI,OAAO,OAAOuB,EAAQvB,EAAM,IAAI,EAAG,CAItC,GAFAoG,EAAmBA,EAAiB,OAAQpB,GAAShF,EAAM,OAASgF,CAAI,EAEpEzD,EAAOvB,EAAM,IAAe,IAAM,MAAQ,CAAC,KAAK,uBAAuBA,CAAK,EAC/E,OAAOA,EAAM,KAAO,mBAGrB,GAAIA,EAAM,MAAQ,CAACuD,EAAWvD,EAAM,IAAI,EAAE,SAASuB,EAAOvB,EAAM,IAAe,CAAC,EAC/E,OAAOA,EAAM,KAAO,wBAEtB,CACD,CAAC,EACA,OAAQW,GAAU,CAAC,CAACA,CAAK,EAGvB,CAAE,WAAA6D,CAAW,EAAI,KAAK,QAC1B,GAAIA,IAAe,KAAM,CACxB,IAAI6B,EAAS,MAAM,QAAQ7B,CAAU,EAAIA,EAAc,OAAO,KAAKA,CAAU,EAC7E4B,EAAmBA,EAAiB,OAAQpB,GAAS,CAACqB,EAAO,SAASrB,CAAI,CAAC,CAC5E,CAGA,OAAIoB,EAAiB,OACb/E,EAAO,OAAO+E,EAAiB,IAAKpB,GAAS,GAAGA,CAAc,4BAA4B,CAAC,EAAE,KAAK;AAAA,CAAI,EAEtG3D,EAAO,KAAK;AAAA,CAAI,CAEzB,CAEA,YAAc,MAAOiF,GAAyB,MAAM,KAAK,YAAY,YAAY,CAAE,SAAUA,CAAS,CAAC,EAEvG,WAAa,MAAOD,EAA2B7F,EAAW+F,EAAO,GAAOC,IAAc,CACjFH,GAAU,CAACG,GACdH,EAAO,QAAQ,SAAUI,EAAM,IAC9B,aAAUA,EAAK,MAAQA,EAAK,KAAM,yDAAyD,CAC5F,CAAC,EAGF,IAAMC,EAAW,CAChB,KAAMlG,EACN,OAAQ6F,CACT,EAEIG,IACHE,EAAI,KAAOF,GAGRD,IACHG,EAAI,KAAO,QAGZ,IAAMlC,EAAa,KAAK,cAAc,EAChCD,EAAmB,KAAK,oBAAoB,EAElD,GAAIA,GAAoBC,EACvB,GAAI,MAAM,QAAQA,CAAU,EAC3B,QAASxE,KAASwE,EACjBkC,EAAI1G,CAAK,EAAIuE,EAAiB,WAAWvE,CAAK,MAG/C,QAAS,CAAC2G,EAAYC,CAAW,IAAK,OAAO,QAAQpC,CAAU,EAC9DkC,EAAIC,CAAU,EAAIpC,EAAiB,WAAWqC,CAAsB,EAOvE,OAFa,MAAM,KAAK,YAAY,WAAWF,CAAG,CAGnD,CACD,EiB/7DA,IAAMG,GAAU,sEAChB,SAASC,GAAYC,EAAY,CAEhC,OAAI,OAAOA,GAAU,WAChBA,EAAM,SAAS,QAAQ,EAC1BA,EAAQ,IAAI,KAAK,OAAOA,EAAM,UAAU,EAAGA,EAAM,OAAS,CAAC,CAAC,CAAC,EACnDF,GAAQ,KAAKE,CAAK,IAC5BA,EAAQ,IAAI,KAAKA,CAAK,IAGjBA,CACR,CAEA,SAASC,GAAYC,EAAY,CAChC,GAAI,MAAM,QAAQA,CAAK,EACtB,QAASC,EAAI,EAAGA,EAAID,EAAM,OAAQC,IAAK,CACtC,IAAIC,EAASF,EAAMC,CAAC,EAChBE,EAAO,OAAO,KAAKD,CAAM,EAC7B,QAASE,KAAOD,EACfD,EAAOE,CAAG,EAAIP,GAAYK,EAAOE,CAAG,CAAC,CAEvC,CAEF,CA+BO,IAAeC,EAAf,cAAuDC,CAA4B,CAChF,QAAU,QACV,QACD,OACRC,GAA0B,KAC1B,IAAI,QAAkB,CACrB,OAAO,KAAKA,IAAW,KAAK,QAAQ,QAAUC,EAAiB,CAChE,CACA,IAAI,OAAOV,EAAuB,CACjC,KAAKS,GAAUT,CAChB,CACA,eAEA,YAAYW,EAA2B,CACtC,MAAM,CACL,gBAAiB,CAAE,UAAW,EAAK,EACnC,UAAW,CAAE,UAAW,EAAM,EAC9B,QAAS,CAAE,UAAW,EAAM,EAC5B,WAAY,CAAE,UAAW,EAAM,EAC/B,SAAU,CAAE,UAAW,EAAM,CAC9B,CAAC,EAED,KAAK,QAAU,CACd,UAAW,OAAW,IAAI,SAAS,GACnC,WAAY,CAAC,EACb,QAAS,EACT,YAAa,KACb,OAAQ,KACR,YAAa,GACb,GAAGA,CACJ,EAEA,KAAK,eAAiB,KAAK,QAAQ,WAAW,IAAKC,GAAMA,EAAE,KAAK,YAAY,CAAC,EAC7E,KAAK,OAAS,CAAC,CAChB,CAUA,MAAM,QAAQC,EAAwC,CACrD,IAAMC,EAAa,IAAI,gBAEjBC,EAAW,MAAM,KAAK,OAAO,QAAQ,KAAK,cAAc,EAAG,CAChE,KAAM,KAAK,UAAU,KAAK,eAAeF,CAAU,CAAC,EACpD,OAAQC,EAAW,OACnB,QAAS,KAAK,QAAQ,QACtB,KAAM,OACN,YAAa,SACd,CAAC,EAED,GAAIC,EAAS,IAAMA,EAAS,QAAQ,IAAI,cAAc,GAAG,SAAS,kBAAkB,EAAG,CACtF,IAAIC,EAAO,MAAMD,EAAS,KAAK,EAC/B,GAAI,OAAO,OAAOC,EAAM,SAAS,EAAG,CACnC,QAASV,KAAOU,EAAK,QACpBf,GAAYe,EAAK,QAAQV,CAAG,CAAC,EAG9B,YAAK,UAAU,YAAaU,EAAK,OAAkB,EACnD,KAAK,UAAU,YAAY,EAEpBA,EAAK,OACb,CACD,CAEA,IAAMC,EAAgB,MAAMC,EAAoBH,CAAQ,EAExD,GAAIE,EAAc,SACjB,OAAO,MAAM,KAAK,QAAQJ,CAAU,EAGrC,WAAK,UAAU,UAAWI,EAAc,OAAO,EACzC,IAAI,MAAMA,EAAc,OAAO,CACtC,CASA,MAAM,UAAW,CAChB,GAAI,KAAK,UAAU,kBAAmB,KAAK,MAAM,IAAM,GACtD,OAAO,MAAM,KAAK,QAAQ,KAAK,MAAiB,CAElD,CAcA,eAAwCE,EAAkBnB,EAA4C,CACrG,OAAImB,GAAQnB,IACX,KAAK,OAAOmB,CAAS,EAAInB,GAGnB,KAAK,OAAOmB,CAAS,CAC7B,CAOA,WAA8B,CAC7B,OAAO,KAAK,MACb,CAMA,eAAgB,CACf,MAAO,CAAC,GAAG,KAAK,QAAQ,UAAU,CACnC,CAQA,eAAgB,CACf,KAAK,OAAS,CAAC,EACf,KAAK,UAAU,UAAU,CAC1B,CAMA,uBAAiC,CAChC,GAAM,CAAE,WAAAN,CAAW,EAAI,KAAK,QAC5B,QAASO,EAAI,EAAGA,EAAIP,EAAW,OAAQO,IACtC,GAAIP,EAAWO,CAAC,EAAE,SACjB,MAAO,GAIT,MAAO,EACR,CACD,EAEaC,EAAN,cAA0Cd,CAAgC,CAChF,YAAYI,EAA2B,CACtC,MAAMA,CAAO,CACd,CAEU,eAAgB,CACzB,MAAO,SAAS,KAAK,QAAQ,SAAS,IAAI,KAAK,QAAQ,WAAW,EACnE,CAEU,eAAeE,EAAsB,CAC9C,OAAOA,GAAe,CAAC,CACxB,CACD,EAEaS,EAAN,cAA6Cf,CAAgC,CACnF,YAAYI,EAA2B,CACtC,MAAMA,CAAO,CACd,CAEU,eAAgB,CACzB,MAAO,WACR,CAEU,eAAeE,EAAsB,CAC9C,OAAAA,EAAaA,GAAe,CAAC,EAEtB,CACN,UAAW,UACX,aAAc,KAAK,QAAQ,YAC3B,kBAAmB,GACnB,QAAS,KAAK,QAAQ,QACtB,YAAa,KAAK,QAAQ,YAC1B,GAAGA,CACJ,CACD,CACD,ECzPA,IAAAU,GAA0B,SAKnB,IAAMC,EAAN,KAAgC,CAC9B,WAAqB,GAC7B,IAAI,UAAW,CACd,OAAO,KAAK,UACb,CAEA,YAAYC,EAAmB,CAC9B,KAAK,YAAYA,CAAQ,CAC1B,CAEA,cAAcC,EAAc,CAC3B,IAAIC,EAAU,KAAK,WAOnB,GALI,CAAC,KAAK,YAAc,OAAO,OAAU,KAKrCD,EAAK,WAAW,MAAM,EACzB,OAAOA,EAGR,IAAIE,EAAUF,EACd,OAAIE,EAAQ,WAAW,GAAG,IACzBA,EAAUA,EAAQ,UAAU,EAAGA,EAAQ,MAAM,GAGvC,CAACD,EAASC,CAAO,EAAE,KAAK,GAAG,CACnC,CAUA,MAAM,QAAQC,EAAaC,EAA+E,CACzG,IAAIC,EAAc,OAAO,OAAO,CAAC,EAAGD,CAAI,EACpC,CAAE,QAAAE,EAAU,EAAG,OAAAC,EAAS,EAAK,EAAIH,EACjCI,EAAa,IAAI,gBAErB,OAAOH,EAAY,QACnB,OAAOA,EAAY,OAEfA,EAAY,OACfA,EAAY,OAAO,iBAAiB,QAAS,IAAM,CAClDG,EAAW,MAAM,CAClB,CAAC,EAEDH,EAAY,OAASG,EAAW,OAG5BH,EAAY,SAChBA,EAAY,OAAS,QAGtB,IAAII,EAAyB,CAC5B,OAASL,GAAM,SAAkB,QAAa,iDAC9C,mBAAoB,gBACrB,EAEIG,IACHE,EAAU,cAAc,EAAKL,GAAM,UAAkB,cAAc,GAAK,mCAGzEC,EAAY,QAAU,IAAI,QAAQ,CAAE,GAAGA,EAAY,QAAS,GAAGI,CAAU,CAAC,EAE1E,IAAIC,EAAgBF,GAAcF,EAAU,EAAIK,EAAeH,EAAYF,CAAO,EAAI,IAAM,KAExFM,EAAW,MAAM,KAAK,MAAMT,EAAKE,CAAW,EAGhD,GAFAK,EAAc,EAEVF,GAAY,QAAQ,QACvB,MAAM,IAAI,aAAa,2BAA4B,YAAY,EAGhE,OAAOI,CACR,CAEA,MAAM,MAAMC,EAAYT,EAAY,CAAC,EAAG,CACvC,IAAID,EAAM,OAAOU,GAAU,SAAWA,EAAQA,EAAM,IACpD,OAAAV,EAAM,KAAK,cAAcA,CAAG,KAE5B,cACCA,EAAI,WAAW,MAAM,GAAK,OAAO,OAAW,IAC5C,6GACD,EAEIA,EAAI,WAAW,MAAM,IACxBC,EAAK,YAAc,UACnBA,EAAK,KAAO,QAGT,OAAOS,GAAU,SACpBA,EAAQV,EAERU,EAAQ,IAAI,QAAQV,EAAKU,CAAK,EAGxB,MAAM,MAAMA,EAAOT,CAAI,CAC/B,CAEA,MAAM,MAAMU,EAAkBC,EAAkBC,EAAwB,CACvE,IAAIJ,EAAW,MAAM,KAAK,QAAQ,SAAU,CAC3C,OAAQ,OACR,QAAS,CACR,OAAQ,mBACR,eAAgB,kBACjB,EACA,KAAM,KAAK,UAAU,CACpB,SAAAE,EACA,SAAAC,EACA,SAAUC,GAAS,UAAY,EAChC,CAAC,CACF,CAAC,EAED,GAAIJ,EAAS,GAAI,CAChB,IAAIK,EAAO,MAAML,EAAS,KAAK,EAC/B,GAAIK,EAAK,QACR,OAAOA,EAAK,QACN,GAAIA,EAAK,MACf,MAAM,MAAMA,EAAK,KAAK,EAEvB,MAAO,EACR,KACC,OAAM,MAAM,iBAAiBL,EAAS,MAAM,IAAIA,EAAS,UAAU,EAAE,CAEvE,CAEA,YAAYb,EAAmB,CAC1BA,IACEA,EAAS,WAAW,MAAM,IAC9BA,EAAW,WAAaA,GAGrBA,EAAS,SAAS,GAAG,IACxBA,EAAWA,EAAS,UAAU,EAAGA,EAAS,OAAS,CAAC,GAGrD,KAAK,WAAaA,EAEpB,CACD,EAII,OAAO,OAAW,KACrBmB,EAAiB,IAAIpB,CAAQ,EClIvB,SAASqB,GAA0D,CACzE,SAAAC,EACA,QAAAC,EACA,OAAAC,EACA,OAAAC,EACA,QAAAC,EACA,WAAAC,CACD,EAAgE,CAC/D,OAAID,GAAW,CAAC,MAAM,QAAQA,CAAO,IACpCA,EAAU,CAAC,OAAOA,CAAO,CAAC,GAGpB,IAAIE,EAAuB,CACjC,aAAcN,EACd,QAAAC,EACA,OAAAC,EACA,OAAAC,EACA,QAASC,EACT,WAAAC,CACD,CAAC,CACF,CAEO,SAASE,GAAyDC,EAA0C,CAClH,GAAI,CAAE,OAAAL,EAAQ,eAAAM,EAAiB,GAAO,GAAAC,EAAI,QAAAT,EAAS,SAAAD,EAAU,OAAAE,EAAQ,QAAAE,EAAS,WAAAC,CAAW,EAAIG,EACzFJ,GAAW,CAAC,MAAM,QAAQA,CAAO,IACpCA,EAAU,CAAC,OAAOA,CAAO,CAAC,GAG3B,IAAIO,EAAcZ,GAAuB,CACxC,SAAAC,EACA,QAAAC,EACA,OAAAC,EACA,OAAAC,EACA,QAAAC,EACA,WAAAC,CACD,CAAC,EAWD,OATiB,IAAIO,EACpB,OAAO,OAAOJ,EAAS,CACtB,aAAcE,EACd,YAAAC,EACA,OAAQE,EAAUX,CAAM,EACxB,eAAgBO,IAAmB,EACpC,CAAC,CACF,CAGD,CCzCO,IAAMK,GAAU,QrBxBvB,OAAW,GAAK,OAAW,IAAM,CAAC,EAClC,OAAW,GAAK,OAAW,IAAM,CAAC,EAClC,OAAW,GAAG,WAAaC,EAC3B,OAAW,GAAG,UAAYC,EAC1B,OAAW,GAAG,aAAeC",
  "names": ["require_appframe_core", "__commonJSMin", "exports", "module", "browser_exports", "__export", "Client", "DataHandler", "DataObject", "DataProviderHandler", "DataProviderHandlerAPI", "FileUploader", "MemoryStorage", "Paging", "Procedure", "ProcedureAPI", "SortOrder", "generateApiDataHandler", "generateApiDataObject", "getDefaultClient", "setDefaultClient", "uid", "version", "import_appframe_core", "import_appframe_core", "import_appframe_core", "defaultClient", "getDefaultClient", "setDefaultClient", "client", "incorrectTypeOfField", "id", "field", "all", "Map", "on", "type", "handler", "handlers", "get", "push", "set", "off", "splice", "indexOf", "emit", "evt", "slice", "map", "DataObjectEvents", "EventTarget", "events", "mitt_default", "event", "func", "options", "handler", "data", "signal", "onAbort", "eventName", "args", "regexes", "guessType", "val", "type", "validateDate", "val", "regexes", "ONE_DAY_IN_MS", "fieldTypes", "value", "milliseconds", "binStr", "bytes", "i", "userSessionExpiredPromise", "resolve", "timeout", "isXHR", "response", "handleResponseError", "contentType", "status", "statusText", "data", "message", "stack", "error", "contentMaybeHtml", "regExArray", "getFields", "fields", "defaultNullable", "field", "getTag", "object", "isEqual", "other", "tagObject", "tagOther", "key", "value", "requestTimeout", "controller", "timeout", "cancelled", "t", "indexError", "idx", "getFieldType", "field", "value", "type", "guessType", "arrayRecordToObject", "fields", "data", "dataSourceId", "record", "value", "field", "type", "getFieldType", "fieldType", "fieldTypes", "incorrectTypeOfField", "arrayRecordsToObjects", "SortOrder", "DataProviderHandlerEvents", "DataHandler", "EventTarget", "getDefaultOptions", "DataProviderHandlerBase", "getDefaultClient", "value", "options", "url", "data", "requestInit", "response", "responseError", "handleResponseError", "DataProviderHandler", "field", "fields", "type", "includeFields", "articleId", "primKey", "fileName", "result", "arrayRecordToObject", "arrayRecordsToObjects", "DataProviderHandlerAPI", "params", "getFields", "parsed", "parameters", "import_appframe_core", "FileUploaderEvents", "FileUploader", "EventTarget", "getDefaultClient", "value", "options", "url", "fileOrBlob", "fields", "fileName", "masterCriteria", "allFields", "data", "field", "resolve", "reject", "request", "evt", "result", "error", "nodeFetchModule", "FormData", "response", "message", "handleResponseError", "PagingEvents", "Paging", "EventTarget", "pOptions", "pageCount", "pOldPage", "pNewPage", "data", "startIndex", "stopIndex", "i", "eventName", "handler", "pPage", "args", "item", "index", "pageSize", "eventData", "currentIndex", "firstRecord", "nextPage", "event", "correctSkip", "loadedPage", "param", "lastPage", "newPageSize", "prevCount", "forceLoad", "RecordSource", "dataObject", "value", "import_appframe_core", "uid", "MemoryStorage", "#data", "#nextUID", "#fields", "fields", "row", "recordUid", "record", "field", "rowUid", "data", "newData", "nextUid", "idx", "indexError", "current", "r", "index", "_", "newLength", "i", "naiveDeepClone", "object", "objUid", "uid", "cloned", "newObject", "key", "objHasKeys", "object", "DataObject", "EventTarget", "options", "DataObjectEvents", "defaults", "naiveDeepClone", "MemoryStorage", "field", "uid", "RecordSource", "Paging", "index", "primKeyOrRecord", "fileNameOrType", "type", "data", "wasDirty", "skipInsteadOfTriggerChecks", "value", "dataSourceId", "ex", "incorrectTypeOfField", "parametersWasChanged", "params", "revert", "savingStatuses", "shouldSetDataLoading", "controller", "result", "response", "record", "dataLength", "af", "eventResult", "uniqueIdField", "uniqueId", "destroyParams", "records", "i", "row", "isEqual", "id", "newRow", "startTimestamp", "idField", "hasIdField", "dirtyRecord", "dataHandlerFunc", "savedId", "updatedFieldName", "validationResult", "normalRecord", "newIndex", "savingState", "processSavingState", "error", "fieldName", "f", "articleId", "FileUploader", "fieldIndex", "fieldDefinition", "fieldTypes", "fieldValue", "current", "rowCount", "dataHandler", "timeout", "DataHandler", "Handler", "DataProviderHandler", "newData", "predicate", "callbackfn", "callbackFn", "indexOrFieldName", "pIndex", "pWasDirty", "masterDataObject", "linkFields", "parameters", "masterChildCriteria", "masterRow", "changed", "childName", "masterName", "event", "name", "parameter", "guessType", "allow", "disallow", "signal", "load", "resolve", "reject", "evt", "start", "indexFromId", "storedRecord", "rowId", "skip", "maxRecords", "indexOrPredicate", "waitForSave", "save", "fieldDef", "recordFieldNames", "fields", "primKeys", "bulk", "json", "item", "obj", "childField", "masterField", "isodate", "dateReviver", "value", "reviveTable", "table", "j", "record", "keys", "key", "ProcedureBase", "EventTarget", "#client", "getDefaultClient", "options", "p", "parameters", "controller", "response", "data", "responseError", "handleResponseError", "name", "i", "Procedure", "ProcedureAPI", "import_appframe_core", "Client", "hostname", "path", "newHost", "newPath", "url", "init", "requestInit", "timeout", "isJson", "controller", "afHeaders", "cancelTimeout", "requestTimeout", "response", "input", "username", "password", "options", "json", "setDefaultClient", "generateApiDataHandler", "resource", "timeout", "fields", "client", "groupBy", "uniqueName", "DataProviderHandlerAPI", "generateApiDataObject", "options", "dynamicLoading", "id", "dataHandler", "DataObject", "getFields", "version", "DataObject", "Procedure", "ProcedureAPI"]
}