UNPKG

ngx-json-treeview

Version:

A simple Angular component to display object data in an expandable JSON tree view.

1 lines 32.6 kB
{"version":3,"file":"ngx-json-treeview.mjs","sources":["../../../projects/ngx-json-treeview/src/lib/handlers.ts","../../../projects/ngx-json-treeview/src/lib/services/id-generator.ts","../../../projects/ngx-json-treeview/src/lib/util.ts","../../../projects/ngx-json-treeview/src/lib/ngx-json-treeview/ngx-json-treeview.component.ts","../../../projects/ngx-json-treeview/src/lib/ngx-json-treeview/ngx-json-treeview.component.html","../../../projects/ngx-json-treeview/src/public-api.ts","../../../projects/ngx-json-treeview/src/ngx-json-treeview.ts"],"sourcesContent":["import { ValueClickHandler } from './types';\n\n/**\n * A handler that checks if a segment's value is a string that looks like an\n * HTTP/HTTPS link. If it is, it opens the link in a new tab.\n */\nexport const followLinkHandler: ValueClickHandler = {\n canHandle: (segment) => {\n if (typeof segment.value === 'string' && segment.value.startsWith('http')) {\n try {\n const url = new URL(segment.value); // Validate the URL.\n return url.protocol === 'http:' || url.protocol === 'https:';\n } catch (e) {\n // Invalid URL.\n }\n }\n return false;\n },\n handler: (segment) => {\n window.open(segment.value, '_blank', 'noopener,noreferrer');\n },\n};\n\n/**\n * A collection of built-in value click handlers.\n * This array can be used to easily apply all default handlers.\n */\nexport const VALUE_CLICK_HANDLERS: readonly ValueClickHandler[] = [\n followLinkHandler,\n];\n\n/**\n * A namespace for individual value click handlers.\n * This allows for easy discovery and individual import of handlers.\n */\nexport const ValueClickHandlers = {\n followLinkHandler,\n};\n","import { InjectionToken } from '@angular/core';\n\n/**\n * Interface for a service that generates unique IDs.\n * @docs-private\n */\nexport interface IdGenerator {\n next(): string;\n}\n\n/**\n * Default implementation of `IdGenerator` for client-side applications.\n * This implementation is not safe for server-side rendering, as the counter\n * is shared across all requests.\n */\nclass DefaultIdGenerator implements IdGenerator {\n private nextId = 0;\n\n next(): string {\n return `ngx-json-treeview-${this.nextId++}`;\n }\n}\n\n/**\n * Injection token for the `IdGenerator` service.\n *\n * For server-side rendering, it's crucial to provide this token at a request level\n * to ensure that IDs are unique per request. Failure to do so will result in\n * ID mismatches between the server-rendered HTML and the client-side application,\n * breaking hydration.\n *\n * Example for server-side provider in `server.ts` or equivalent:\n *\n * ```typescript\n * // In your server-side providers:\n * { provide: ID_GENERATOR, useClass: ServerIdGenerator }\n * ```\n */\nexport const ID_GENERATOR = new InjectionToken<IdGenerator>('ID_GENERATOR', {\n providedIn: 'root',\n factory: () => new DefaultIdGenerator(),\n});\n","/**\n * Generates a preview string representation of an object.\n *\n * @param obj The object to preview.\n * @param limit The maximum length of the preview string. Defaults to 200.\n * @param stringsLimit The maximum length of a string to display before\n * truncating. Defaults to 10.\n * @returns A preview string representation of the object.\n */\nexport function previewString(obj: any, limit = 200, stringsLimit = 10) {\n let result = '';\n\n if (obj === null) {\n result += 'null';\n } else if (obj === undefined) {\n result += 'undefined';\n } else if (typeof obj === 'string') {\n if (obj.length > stringsLimit) {\n result += `\"${obj.substring(0, stringsLimit)}…\"`;\n } else {\n result += `\"${obj}\"`;\n }\n } else if (typeof obj === 'boolean') {\n result += `${obj ? 'true' : 'false'}`;\n } else if (typeof obj === 'number') {\n result += `${obj}`;\n } else if (typeof obj === 'object') {\n if (obj instanceof Date) {\n result += `\"${obj.toISOString()}\"`;\n } else if (Array.isArray(obj)) {\n result += `Array[${obj.length}] [`;\n for (const key in obj) {\n if (result.length >= limit) {\n break;\n }\n result += previewString(obj[key], limit - result.length);\n result += ',';\n }\n if (result.endsWith(',')) {\n result = result.slice(0, -1);\n }\n result += ']';\n } else {\n result += 'Object {';\n for (const key in obj) {\n if (result.length >= limit) {\n break;\n }\n if (obj[key] !== undefined) {\n result += `\"${key}\":`;\n result += previewString(obj[key], limit - result.length);\n result += ',';\n }\n }\n if (result.endsWith(',')) {\n result = result.slice(0, -1);\n }\n result += '}';\n }\n } else if (typeof obj === 'function') {\n result += 'Function';\n }\n\n if (result.length >= limit) {\n return result.substring(0, limit) + '…';\n }\n\n return result;\n}\n\n/**\n * Decycles a JavaScript object by replacing circular references with `$ref`\n * properties. This is useful for serializing objects that contain circular\n * references, preventing infinite loops.\n *\n * Original: https://github.com/douglascrockford/JSON-js/blob/master/cycle.js\n *\n * @param object The object to decycle.\n * @returns A decycled version of the object.\n */\nexport function decycle(object: any): any {\n const objects = new WeakMap();\n return (function derez(value, path) {\n let old_path;\n let nu: any;\n\n if (\n typeof value === 'object' &&\n value !== null &&\n !(value instanceof Boolean) &&\n !(value instanceof Date) &&\n !(value instanceof Number) &&\n !(value instanceof RegExp) &&\n !(value instanceof String)\n ) {\n old_path = objects.get(value);\n if (old_path !== undefined) {\n return { $ref: old_path };\n }\n objects.set(value, path);\n\n if (Array.isArray(value)) {\n nu = [];\n value.forEach(function (element, i) {\n nu[i] = derez(element, path + '[' + i + ']');\n });\n } else {\n nu = {};\n Object.keys(value).forEach(function (name) {\n nu[name] = derez(\n value[name],\n path + '[' + JSON.stringify(name) + ']'\n );\n });\n }\n return nu;\n }\n return value;\n })(object, '$');\n}\n","import { Component, computed, inject, input, output } from '@angular/core';\nimport { VALUE_CLICK_HANDLERS } from '../handlers';\nimport { ID_GENERATOR } from '../services/id-generator';\nimport { IsClickableValueFn, Segment, ValueClickHandler } from '../types';\nimport { decycle, previewString } from '../util';\n\n/**\n * Renders JSON data in an expandable and collapsible tree structure.\n * Allows users to navigate complex data hierarchies visually.\n */\n@Component({\n selector: 'ngx-json-treeview',\n imports: [],\n templateUrl: './ngx-json-treeview.component.html',\n styleUrls: ['./ngx-json-treeview.component.scss'],\n})\nexport class NgxJsonTreeviewComponent {\n /**\n * The JSON object or array to display in the tree view.\n * @required\n */\n json = input.required<any>();\n\n /**\n * Controls the default expansion state for all expandable segments\n * i.e. objects and arrays.\n * - If `true`, nodes are expanded down to the specified `depth`.\n * - If `false`, all nodes start collapsed.\n * @default true\n */\n expanded = input<boolean>(true);\n\n /**\n * Determines the maximum nesting level automatically expanded when `expanded`\n * is `true`.\n * - `-1`: Infinite depth (all levels expanded).\n * - `0`: Only the root node is expanded (if applicable).\n * - `n`: Root and nodes down to `n` levels are expanded.\n * @default -1\n */\n depth = input<number>(-1);\n\n /**\n * If `true`, values are clickable when there is a corresponding handler\n * in the `valueClickHandlers` array that can process it.\n *\n * This allows for use cases such as:\n * - Following hyperlinks.\n * - Copying a value to the clipboard.\n * - Triggering custom actions based on the value's content or type.\n * @default false\n */\n enableClickableValues = input<boolean>(false);\n\n /**\n * @deprecated Use `valueClickHandlers` instead. This input will be removed\n * in a future version.\n *\n * A function that determines if a specific value node should be considered\n * clickable. This provides more granular control than the global\n * `enableClickableValues` flag.\n *\n * The function receives the `Segment` object and should return `true` if the\n * value is clickable, `false` otherwise. This check is only performed if\n * `enableClickableValues` is also `true`.\n *\n * @param segment - The segment being evaluated.\n * @returns `true` if the segment's value should be clickable, `false`\n * otherwise.\n */\n isClickableValue = input<IsClickableValueFn>();\n\n /**\n * @deprecated Use `valueClickHandlers` instead. This output will be removed\n * in a future version.\n *\n * If `enableClickableValues` is set to `true`, emits a `Segment` object when\n * a value node is clicked. The emitted `Segment` contains details about the\n * clicked node (key, value, type, path, etc.).\n */\n onValueClick = output<Segment>();\n\n /**\n * An array of handler functions to be executed when a value node is clicked.\n * Only the first handler in the array for which `isClickable` returns `true`\n * will be executed.\n *\n * If `enableClickableValues` is set to true, but `valueClickHandlers` is\n * omitted, the built-in `VALUE_CLICK_HANDLERS` will be used as the default.\n */\n valueClickHandlers = input<ValueClickHandler[]>();\n\n /**\n * *Internal* input representing the parent segment in the tree hierarchy.\n * Primrily used for calculating paths.\n * @internal\n */\n _parent = input<Segment>();\n\n /**\n * *Internal* input representing the current nesting depth. Used in\n * conjunction with the `depth` input to control expansion.\n * @internal\n */\n _currentDepth = input<number>(0);\n\n private internalValueClickHandlers = computed<ValueClickHandler[]>(() => {\n const handlers: ValueClickHandler[] = [];\n const legacyIsClickableFn = this.isClickableValue();\n\n if (legacyIsClickableFn) {\n handlers.push({\n canHandle: legacyIsClickableFn,\n handler: (segment) => this.onValueClick.emit(segment),\n });\n }\n\n handlers.push(...(this.valueClickHandlers() ?? VALUE_CLICK_HANDLERS));\n return handlers;\n });\n\n rootType = computed<string>(() => {\n if (this.json() === null) {\n return 'null';\n } else if (Array.isArray(this.json())) {\n return 'array';\n } else return typeof this.json();\n });\n segments = computed<Segment[]>(() => {\n const json = decycle(this.json());\n if (typeof json === 'object' && json != null) {\n return Object.keys(json).map((key) => this.parseKeyValue(key, json[key]));\n }\n return [];\n });\n isExpanded = computed<boolean>(\n () =>\n this.expanded() &&\n !(this.depth() > -1 && this._currentDepth() >= this.depth())\n );\n openingBrace = computed<string>(() => {\n if (this.rootType() === 'array') {\n return '[';\n } else return '{';\n });\n closingBrace = computed<string>(() => {\n if (this.rootType() === 'array') {\n return ']';\n } else return '}';\n });\n asString = computed<string>(() =>\n JSON.stringify(this.json(), null, 2).trim()\n );\n primitiveSegmentClass = computed<string>(() => {\n const type = this.rootType();\n if (['object', 'array'].includes(type)) {\n return 'punctuation';\n }\n return 'segment-type-' + type;\n });\n private primitiveSegment = computed<Segment | null>(() => {\n if (this.segments().length > 0) return null;\n return {\n key: '',\n value: this.json(),\n type: this.rootType(),\n description: this.asString(),\n expanded: false,\n path: this._parent()?.path ?? '',\n };\n });\n isClickablePrimitive = computed<boolean>(() => {\n const segment = this.primitiveSegment();\n return !!segment && this.isClickable(segment);\n });\n isArrayElement = computed<boolean>(() => this.rootType() === 'array');\n\n private readonly idGenerator = inject(ID_GENERATOR);\n public readonly id = this.idGenerator.next();\n\n isExpandable(segment: Segment) {\n return (\n (segment.type === 'object' && Object.keys(segment.value).length > 0) ||\n (segment.type === 'array' && segment.value.length > 0)\n );\n }\n\n isEmpty(segment: Segment) {\n return (\n (segment.type === 'object' && Object.keys(segment.value).length === 0) ||\n (segment.type === 'array' && segment.value.length === 0)\n );\n }\n\n isClickable(segment: Segment): boolean {\n if (!this.enableClickableValues()) {\n return false;\n }\n\n return this.internalValueClickHandlers().some((handler) => {\n try {\n return handler.canHandle(segment);\n } catch (e) {\n return false;\n }\n });\n }\n\n toggle(segment: Segment) {\n if (this.isExpandable(segment)) {\n segment.expanded = !segment.expanded;\n }\n }\n\n onPrimitiveClick(): void {\n const segment = this.primitiveSegment();\n if (segment) {\n this.onValueClickHandler(segment);\n }\n }\n\n onValueClickHandler(segment: Segment) {\n for (const handler of this.internalValueClickHandlers()) {\n try {\n if (handler.canHandle(segment)) {\n try {\n handler.handler(segment);\n } catch (e) {\n console.error('Error executing click handler:', e);\n }\n return; // Stop after the first handler is executed.\n }\n } catch (e) {\n // in case of any error, continue to the next handler\n }\n }\n }\n\n openingBraceForSegment(segment: Segment) {\n if (segment.type === 'array') {\n return '[';\n } else if (segment.type === 'object') {\n return '{';\n }\n\n return undefined;\n }\n\n closingBraceForSegment(segment: Segment) {\n if (segment.type === 'array') {\n return ']';\n } else if (segment.type === 'object') {\n return '}';\n }\n\n return undefined;\n }\n\n private getPath(key: string): string {\n const parent = this._parent();\n let path: string;\n\n if (parent) {\n if (parent.type === 'array') {\n path = `${parent.path}[${key}]`;\n } else {\n path = `${parent.path}.${key}`;\n }\n } else {\n path = key;\n }\n\n return path;\n }\n\n private parseKeyValue(key: any, value: any): Segment {\n const segment: Segment = {\n parent: this._parent(),\n path: this.getPath(key),\n key: key,\n value: value,\n type: undefined,\n description: '' + value,\n expanded: this.isExpanded(),\n };\n\n switch (typeof segment.value) {\n case 'number':\n segment.type = 'number';\n break;\n case 'boolean':\n segment.type = 'boolean';\n break;\n case 'function':\n segment.type = 'function';\n break;\n case 'string':\n segment.type = 'string';\n segment.description = JSON.stringify(segment.value);\n break;\n case 'undefined':\n segment.type = 'undefined';\n segment.description = 'undefined';\n break;\n case 'object':\n if (segment.value === null) {\n segment.type = 'null';\n segment.description = 'null';\n } else if (Array.isArray(segment.value)) {\n segment.type = 'array';\n segment.description = previewString(segment.value);\n } else if (segment.value instanceof Date) {\n segment.type = 'date';\n segment.description = `\"${segment.value.toISOString()}\"`;\n } else {\n segment.type = 'object';\n segment.description = previewString(segment.value);\n }\n break;\n default:\n console.error('Unknown type parsing json key/value.');\n }\n\n return segment;\n }\n}\n","<section\n class=\"ngx-json-treeview\"\n [attr.role]=\"_currentDepth() === 0 ? 'tree' : null\">\n @if (segments().length === 0) {\n <div [class]=\"primitiveSegmentClass()\">\n <button\n type=\"button\"\n class=\"segment-primitive\"\n [class.clickable]=\"isClickablePrimitive()\"\n (click)=\"onPrimitiveClick()\"\n [disabled]=\"!isClickablePrimitive()\">\n {{ asString() }}\n </button>\n </div>\n } @else {\n @if (_currentDepth() === 0) {\n <span class=\"punctuation\">{{ openingBrace() }}</span>\n }\n @for (\n segment of segments();\n track segment;\n let i = $index;\n let len = $count\n ) {\n @let needsComma = i < len - 1;\n @let expandable = isExpandable(segment);\n @let empty = isEmpty(segment);\n @let openingBrace = openingBraceForSegment(segment);\n @let closingBrace = closingBraceForSegment(segment);\n @let clickableValue = isClickable(segment);\n @let nodeId = id + '-node-label-' + _currentDepth() + '-' + i;\n\n <div\n [class]=\"'segment segment-type-' + segment.type\"\n role=\"treeitem\"\n [attr.aria-expanded]=\"expandable ? segment.expanded : undefined\"\n [attr.aria-level]=\"_currentDepth() + 1\"\n [attr.aria-setsize]=\"len\"\n [attr.aria-posinset]=\"i + 1\"\n [attr.aria-labelledby]=\"nodeId\">\n <div class=\"segment-main\">\n <button\n [id]=\"nodeId\"\n type=\"button\"\n [class.expandable]=\"expandable\"\n [class.expanded]=\"segment.expanded\"\n (click)=\"toggle(segment)\"\n [disabled]=\"!expandable\">\n @if (expandable) {\n <div class=\"toggler\"></div>\n }\n @if (isArrayElement()) {\n <span class=\"segment-label\">{{ segment.key }}</span>\n } @else {\n <span class=\"segment-key\">{{ `\"${segment.key}\"` }}</span>\n }\n </button>\n <span\n [class.segment-label]=\"isArrayElement()\"\n [class.punctuation]=\"!isArrayElement()\"\n >:\n </span>\n @if (empty) {\n <span class=\"punctuation\"\n >{{ openingBrace }}{{ closingBrace\n }}{{ needsComma ? ',' : '' }}</span\n >\n } @else if (!expandable || !segment.expanded) {\n <button\n type=\"button\"\n [class.segment-label]=\"expandable\"\n [class.segment-value]=\"!expandable\"\n [class.clickable]=\"clickableValue\"\n (click)=\"onValueClickHandler(segment)\"\n [disabled]=\"!clickableValue\">\n {{ segment.description }}\n </button>\n <span class=\"punctuation\">{{ needsComma ? ',' : '' }}</span>\n } @else {\n <span class=\"punctuation\">\n {{ openingBrace }}\n </span>\n }\n </div>\n @if (expandable && segment.expanded) {\n <div class=\"children\" role=\"group\">\n <ngx-json-treeview\n [json]=\"segment.value\"\n [expanded]=\"expanded()\"\n [depth]=\"depth()\"\n [enableClickableValues]=\"enableClickableValues()\"\n [valueClickHandlers]=\"valueClickHandlers()\"\n [isClickableValue]=\"isClickableValue()\"\n (onValueClick)=\"onValueClickHandler($event)\"\n [_parent]=\"segment\"\n [_currentDepth]=\"_currentDepth() + 1\" />\n <span class=\"punctuation\">\n {{ closingBrace }}{{ needsComma ? ',' : '' }}\n </span>\n </div>\n }\n </div>\n }\n @if (_currentDepth() === 0) {\n <span class=\"punctuation\">{{ closingBrace() }}</span>\n }\n }\n</section>\n","/*\n * Public API Surface of ngx-json-treeview\n */\n\nexport {\n VALUE_CLICK_HANDLERS,\n ValueClickHandlers,\n followLinkHandler,\n} from './lib/handlers';\nexport * from './lib/ngx-json-treeview/ngx-json-treeview.component';\nexport * from './lib/types';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;AAEA;;;AAGG;AACU,MAAA,iBAAiB,GAAsB;AAClD,IAAA,SAAS,EAAE,CAAC,OAAO,KAAI;AACrB,QAAA,IAAI,OAAO,OAAO,CAAC,KAAK,KAAK,QAAQ,IAAI,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE;AACzE,YAAA,IAAI;gBACF,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;gBACnC,OAAO,GAAG,CAAC,QAAQ,KAAK,OAAO,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ;;YAC5D,OAAO,CAAC,EAAE;;;;AAId,QAAA,OAAO,KAAK;KACb;AACD,IAAA,OAAO,EAAE,CAAC,OAAO,KAAI;QACnB,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,qBAAqB,CAAC;KAC5D;;AAGH;;;AAGG;AACU,MAAA,oBAAoB,GAAiC;IAChE,iBAAiB;;AAGnB;;;AAGG;AACU,MAAA,kBAAkB,GAAG;IAChC,iBAAiB;;;AC1BnB;;;;AAIG;AACH,MAAM,kBAAkB,CAAA;IACd,MAAM,GAAG,CAAC;IAElB,IAAI,GAAA;AACF,QAAA,OAAO,qBAAqB,IAAI,CAAC,MAAM,EAAE,EAAE;;AAE9C;AAED;;;;;;;;;;;;;;AAcG;AACI,MAAM,YAAY,GAAG,IAAI,cAAc,CAAc,cAAc,EAAE;AAC1E,IAAA,UAAU,EAAE,MAAM;AAClB,IAAA,OAAO,EAAE,MAAM,IAAI,kBAAkB,EAAE;AACxC,CAAA,CAAC;;ACzCF;;;;;;;;AAQG;AACG,SAAU,aAAa,CAAC,GAAQ,EAAE,KAAK,GAAG,GAAG,EAAE,YAAY,GAAG,EAAE,EAAA;IACpE,IAAI,MAAM,GAAG,EAAE;AAEf,IAAA,IAAI,GAAG,KAAK,IAAI,EAAE;QAChB,MAAM,IAAI,MAAM;;AACX,SAAA,IAAI,GAAG,KAAK,SAAS,EAAE;QAC5B,MAAM,IAAI,WAAW;;AAChB,SAAA,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE;AAClC,QAAA,IAAI,GAAG,CAAC,MAAM,GAAG,YAAY,EAAE;YAC7B,MAAM,IAAI,CAAI,CAAA,EAAA,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,YAAY,CAAC,CAAA,EAAA,CAAI;;aAC3C;AACL,YAAA,MAAM,IAAI,CAAA,CAAA,EAAI,GAAG,CAAA,CAAA,CAAG;;;AAEjB,SAAA,IAAI,OAAO,GAAG,KAAK,SAAS,EAAE;AACnC,QAAA,MAAM,IAAI,CAAA,EAAG,GAAG,GAAG,MAAM,GAAG,OAAO,CAAA,CAAE;;AAChC,SAAA,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE;AAClC,QAAA,MAAM,IAAI,CAAA,EAAG,GAAG,CAAA,CAAE;;AACb,SAAA,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE;AAClC,QAAA,IAAI,GAAG,YAAY,IAAI,EAAE;AACvB,YAAA,MAAM,IAAI,CAAI,CAAA,EAAA,GAAG,CAAC,WAAW,EAAE,GAAG;;AAC7B,aAAA,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;AAC7B,YAAA,MAAM,IAAI,CAAS,MAAA,EAAA,GAAG,CAAC,MAAM,KAAK;AAClC,YAAA,KAAK,MAAM,GAAG,IAAI,GAAG,EAAE;AACrB,gBAAA,IAAI,MAAM,CAAC,MAAM,IAAI,KAAK,EAAE;oBAC1B;;AAEF,gBAAA,MAAM,IAAI,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC;gBACxD,MAAM,IAAI,GAAG;;AAEf,YAAA,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;gBACxB,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;;YAE9B,MAAM,IAAI,GAAG;;aACR;YACL,MAAM,IAAI,UAAU;AACpB,YAAA,KAAK,MAAM,GAAG,IAAI,GAAG,EAAE;AACrB,gBAAA,IAAI,MAAM,CAAC,MAAM,IAAI,KAAK,EAAE;oBAC1B;;AAEF,gBAAA,IAAI,GAAG,CAAC,GAAG,CAAC,KAAK,SAAS,EAAE;AAC1B,oBAAA,MAAM,IAAI,CAAA,CAAA,EAAI,GAAG,CAAA,EAAA,CAAI;AACrB,oBAAA,MAAM,IAAI,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC;oBACxD,MAAM,IAAI,GAAG;;;AAGjB,YAAA,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;gBACxB,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;;YAE9B,MAAM,IAAI,GAAG;;;AAEV,SAAA,IAAI,OAAO,GAAG,KAAK,UAAU,EAAE;QACpC,MAAM,IAAI,UAAU;;AAGtB,IAAA,IAAI,MAAM,CAAC,MAAM,IAAI,KAAK,EAAE;QAC1B,OAAO,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,GAAG;;AAGzC,IAAA,OAAO,MAAM;AACf;AAEA;;;;;;;;;AASG;AACG,SAAU,OAAO,CAAC,MAAW,EAAA;AACjC,IAAA,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE;AAC7B,IAAA,OAAO,CAAC,SAAS,KAAK,CAAC,KAAK,EAAE,IAAI,EAAA;AAChC,QAAA,IAAI,QAAQ;AACZ,QAAA,IAAI,EAAO;QAEX,IACE,OAAO,KAAK,KAAK,QAAQ;AACzB,YAAA,KAAK,KAAK,IAAI;AACd,YAAA,EAAE,KAAK,YAAY,OAAO,CAAC;AAC3B,YAAA,EAAE,KAAK,YAAY,IAAI,CAAC;AACxB,YAAA,EAAE,KAAK,YAAY,MAAM,CAAC;AAC1B,YAAA,EAAE,KAAK,YAAY,MAAM,CAAC;AAC1B,YAAA,EAAE,KAAK,YAAY,MAAM,CAAC,EAC1B;AACA,YAAA,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;AAC7B,YAAA,IAAI,QAAQ,KAAK,SAAS,EAAE;AAC1B,gBAAA,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE;;AAE3B,YAAA,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC;AAExB,YAAA,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;gBACxB,EAAE,GAAG,EAAE;AACP,gBAAA,KAAK,CAAC,OAAO,CAAC,UAAU,OAAO,EAAE,CAAC,EAAA;AAChC,oBAAA,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,GAAG,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;AAC9C,iBAAC,CAAC;;iBACG;gBACL,EAAE,GAAG,EAAE;gBACP,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,UAAU,IAAI,EAAA;oBACvC,EAAE,CAAC,IAAI,CAAC,GAAG,KAAK,CACd,KAAK,CAAC,IAAI,CAAC,EACX,IAAI,GAAG,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,GAAG,CACxC;AACH,iBAAC,CAAC;;AAEJ,YAAA,OAAO,EAAE;;AAEX,QAAA,OAAO,KAAK;AACd,KAAC,EAAE,MAAM,EAAE,GAAG,CAAC;AACjB;;ACjHA;;;AAGG;MAOU,wBAAwB,CAAA;AACnC;;;AAGG;AACH,IAAA,IAAI,GAAG,KAAK,CAAC,QAAQ,EAAO;AAE5B;;;;;;AAMG;AACH,IAAA,QAAQ,GAAG,KAAK,CAAU,IAAI,CAAC;AAE/B;;;;;;;AAOG;AACH,IAAA,KAAK,GAAG,KAAK,CAAS,CAAC,CAAC,CAAC;AAEzB;;;;;;;;;AASG;AACH,IAAA,qBAAqB,GAAG,KAAK,CAAU,KAAK,CAAC;AAE7C;;;;;;;;;;;;;;;AAeG;IACH,gBAAgB,GAAG,KAAK,EAAsB;AAE9C;;;;;;;AAOG;IACH,YAAY,GAAG,MAAM,EAAW;AAEhC;;;;;;;AAOG;IACH,kBAAkB,GAAG,KAAK,EAAuB;AAEjD;;;;AAIG;IACH,OAAO,GAAG,KAAK,EAAW;AAE1B;;;;AAIG;AACH,IAAA,aAAa,GAAG,KAAK,CAAS,CAAC,CAAC;AAExB,IAAA,0BAA0B,GAAG,QAAQ,CAAsB,MAAK;QACtE,MAAM,QAAQ,GAAwB,EAAE;AACxC,QAAA,MAAM,mBAAmB,GAAG,IAAI,CAAC,gBAAgB,EAAE;QAEnD,IAAI,mBAAmB,EAAE;YACvB,QAAQ,CAAC,IAAI,CAAC;AACZ,gBAAA,SAAS,EAAE,mBAAmB;AAC9B,gBAAA,OAAO,EAAE,CAAC,OAAO,KAAK,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC;AACtD,aAAA,CAAC;;AAGJ,QAAA,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,kBAAkB,EAAE,IAAI,oBAAoB,CAAC,CAAC;AACrE,QAAA,OAAO,QAAQ;AACjB,KAAC,CAAC;AAEF,IAAA,QAAQ,GAAG,QAAQ,CAAS,MAAK;AAC/B,QAAA,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,IAAI,EAAE;AACxB,YAAA,OAAO,MAAM;;aACR,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE;AACrC,YAAA,OAAO,OAAO;;;AACT,YAAA,OAAO,OAAO,IAAI,CAAC,IAAI,EAAE;AAClC,KAAC,CAAC;AACF,IAAA,QAAQ,GAAG,QAAQ,CAAY,MAAK;QAClC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QACjC,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,IAAI,IAAI,EAAE;YAC5C,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,IAAI,CAAC,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;;AAE3E,QAAA,OAAO,EAAE;AACX,KAAC,CAAC;IACF,UAAU,GAAG,QAAQ,CACnB,MACE,IAAI,CAAC,QAAQ,EAAE;QACf,EAAE,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,aAAa,EAAE,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC,CAC/D;AACD,IAAA,YAAY,GAAG,QAAQ,CAAS,MAAK;AACnC,QAAA,IAAI,IAAI,CAAC,QAAQ,EAAE,KAAK,OAAO,EAAE;AAC/B,YAAA,OAAO,GAAG;;;AACL,YAAA,OAAO,GAAG;AACnB,KAAC,CAAC;AACF,IAAA,YAAY,GAAG,QAAQ,CAAS,MAAK;AACnC,QAAA,IAAI,IAAI,CAAC,QAAQ,EAAE,KAAK,OAAO,EAAE;AAC/B,YAAA,OAAO,GAAG;;;AACL,YAAA,OAAO,GAAG;AACnB,KAAC,CAAC;IACF,QAAQ,GAAG,QAAQ,CAAS,MAC1B,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAC5C;AACD,IAAA,qBAAqB,GAAG,QAAQ,CAAS,MAAK;AAC5C,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE;QAC5B,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE;AACtC,YAAA,OAAO,aAAa;;QAEtB,OAAO,eAAe,GAAG,IAAI;AAC/B,KAAC,CAAC;AACM,IAAA,gBAAgB,GAAG,QAAQ,CAAiB,MAAK;AACvD,QAAA,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC,MAAM,GAAG,CAAC;AAAE,YAAA,OAAO,IAAI;QAC3C,OAAO;AACL,YAAA,GAAG,EAAE,EAAE;AACP,YAAA,KAAK,EAAE,IAAI,CAAC,IAAI,EAAE;AAClB,YAAA,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE;AACrB,YAAA,WAAW,EAAE,IAAI,CAAC,QAAQ,EAAE;AAC5B,YAAA,QAAQ,EAAE,KAAK;YACf,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE,IAAI,IAAI,EAAE;SACjC;AACH,KAAC,CAAC;AACF,IAAA,oBAAoB,GAAG,QAAQ,CAAU,MAAK;AAC5C,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,gBAAgB,EAAE;QACvC,OAAO,CAAC,CAAC,OAAO,IAAI,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC;AAC/C,KAAC,CAAC;AACF,IAAA,cAAc,GAAG,QAAQ,CAAU,MAAM,IAAI,CAAC,QAAQ,EAAE,KAAK,OAAO,CAAC;AAEpD,IAAA,WAAW,GAAG,MAAM,CAAC,YAAY,CAAC;AACnC,IAAA,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE;AAE5C,IAAA,YAAY,CAAC,OAAgB,EAAA;QAC3B,QACE,CAAC,OAAO,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC;AACnE,aAAC,OAAO,CAAC,IAAI,KAAK,OAAO,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;;AAI1D,IAAA,OAAO,CAAC,OAAgB,EAAA;QACtB,QACE,CAAC,OAAO,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC;AACrE,aAAC,OAAO,CAAC,IAAI,KAAK,OAAO,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC;;AAI5D,IAAA,WAAW,CAAC,OAAgB,EAAA;AAC1B,QAAA,IAAI,CAAC,IAAI,CAAC,qBAAqB,EAAE,EAAE;AACjC,YAAA,OAAO,KAAK;;QAGd,OAAO,IAAI,CAAC,0BAA0B,EAAE,CAAC,IAAI,CAAC,CAAC,OAAO,KAAI;AACxD,YAAA,IAAI;AACF,gBAAA,OAAO,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC;;YACjC,OAAO,CAAC,EAAE;AACV,gBAAA,OAAO,KAAK;;AAEhB,SAAC,CAAC;;AAGJ,IAAA,MAAM,CAAC,OAAgB,EAAA;AACrB,QAAA,IAAI,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE;AAC9B,YAAA,OAAO,CAAC,QAAQ,GAAG,CAAC,OAAO,CAAC,QAAQ;;;IAIxC,gBAAgB,GAAA;AACd,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,gBAAgB,EAAE;QACvC,IAAI,OAAO,EAAE;AACX,YAAA,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC;;;AAIrC,IAAA,mBAAmB,CAAC,OAAgB,EAAA;QAClC,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,0BAA0B,EAAE,EAAE;AACvD,YAAA,IAAI;AACF,gBAAA,IAAI,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE;AAC9B,oBAAA,IAAI;AACF,wBAAA,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC;;oBACxB,OAAO,CAAC,EAAE;AACV,wBAAA,OAAO,CAAC,KAAK,CAAC,gCAAgC,EAAE,CAAC,CAAC;;AAEpD,oBAAA,OAAO;;;YAET,OAAO,CAAC,EAAE;;;;;AAMhB,IAAA,sBAAsB,CAAC,OAAgB,EAAA;AACrC,QAAA,IAAI,OAAO,CAAC,IAAI,KAAK,OAAO,EAAE;AAC5B,YAAA,OAAO,GAAG;;AACL,aAAA,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE;AACpC,YAAA,OAAO,GAAG;;AAGZ,QAAA,OAAO,SAAS;;AAGlB,IAAA,sBAAsB,CAAC,OAAgB,EAAA;AACrC,QAAA,IAAI,OAAO,CAAC,IAAI,KAAK,OAAO,EAAE;AAC5B,YAAA,OAAO,GAAG;;AACL,aAAA,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE;AACpC,YAAA,OAAO,GAAG;;AAGZ,QAAA,OAAO,SAAS;;AAGV,IAAA,OAAO,CAAC,GAAW,EAAA;AACzB,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE;AAC7B,QAAA,IAAI,IAAY;QAEhB,IAAI,MAAM,EAAE;AACV,YAAA,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO,EAAE;gBAC3B,IAAI,GAAG,GAAG,MAAM,CAAC,IAAI,CAAI,CAAA,EAAA,GAAG,GAAG;;iBAC1B;gBACL,IAAI,GAAG,GAAG,MAAM,CAAC,IAAI,CAAI,CAAA,EAAA,GAAG,EAAE;;;aAE3B;YACL,IAAI,GAAG,GAAG;;AAGZ,QAAA,OAAO,IAAI;;IAGL,aAAa,CAAC,GAAQ,EAAE,KAAU,EAAA;AACxC,QAAA,MAAM,OAAO,GAAY;AACvB,YAAA,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE;AACtB,YAAA,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC;AACvB,YAAA,GAAG,EAAE,GAAG;AACR,YAAA,KAAK,EAAE,KAAK;AACZ,YAAA,IAAI,EAAE,SAAS;YACf,WAAW,EAAE,EAAE,GAAG,KAAK;AACvB,YAAA,QAAQ,EAAE,IAAI,CAAC,UAAU,EAAE;SAC5B;AAED,QAAA,QAAQ,OAAO,OAAO,CAAC,KAAK;AAC1B,YAAA,KAAK,QAAQ;AACX,gBAAA,OAAO,CAAC,IAAI,GAAG,QAAQ;gBACvB;AACF,YAAA,KAAK,SAAS;AACZ,gBAAA,OAAO,CAAC,IAAI,GAAG,SAAS;gBACxB;AACF,YAAA,KAAK,UAAU;AACb,gBAAA,OAAO,CAAC,IAAI,GAAG,UAAU;gBACzB;AACF,YAAA,KAAK,QAAQ;AACX,gBAAA,OAAO,CAAC,IAAI,GAAG,QAAQ;gBACvB,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC;gBACnD;AACF,YAAA,KAAK,WAAW;AACd,gBAAA,OAAO,CAAC,IAAI,GAAG,WAAW;AAC1B,gBAAA,OAAO,CAAC,WAAW,GAAG,WAAW;gBACjC;AACF,YAAA,KAAK,QAAQ;AACX,gBAAA,IAAI,OAAO,CAAC,KAAK,KAAK,IAAI,EAAE;AAC1B,oBAAA,OAAO,CAAC,IAAI,GAAG,MAAM;AACrB,oBAAA,OAAO,CAAC,WAAW,GAAG,MAAM;;qBACvB,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;AACvC,oBAAA,OAAO,CAAC,IAAI,GAAG,OAAO;oBACtB,OAAO,CAAC,WAAW,GAAG,aAAa,CAAC,OAAO,CAAC,KAAK,CAAC;;AAC7C,qBAAA,IAAI,OAAO,CAAC,KAAK,YAAY,IAAI,EAAE;AACxC,oBAAA,OAAO,CAAC,IAAI,GAAG,MAAM;oBACrB,OAAO,CAAC,WAAW,GAAG,CAAI,CAAA,EAAA,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,CAAA,CAAA,CAAG;;qBACnD;AACL,oBAAA,OAAO,CAAC,IAAI,GAAG,QAAQ;oBACvB,OAAO,CAAC,WAAW,GAAG,aAAa,CAAC,OAAO,CAAC,KAAK,CAAC;;gBAEpD;AACF,YAAA;AACE,gBAAA,OAAO,CAAC,KAAK,CAAC,sCAAsC,CAAC;;AAGzD,QAAA,OAAO,OAAO;;uGAnTL,wBAAwB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAxB,wBAAwB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,mBAAA,EAAA,MAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,qBAAA,EAAA,EAAA,iBAAA,EAAA,uBAAA,EAAA,UAAA,EAAA,uBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,gBAAA,EAAA,EAAA,iBAAA,EAAA,kBAAA,EAAA,UAAA,EAAA,kBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,kBAAA,EAAA,EAAA,iBAAA,EAAA,oBAAA,EAAA,UAAA,EAAA,oBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,aAAA,EAAA,EAAA,iBAAA,EAAA,eAAA,EAAA,UAAA,EAAA,eAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,YAAA,EAAA,cAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EChBrC,y1HA4GA,EAAA,MAAA,EAAA,CAAA,4mHAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,ED5Fa,wBAAwB,EAAA,QAAA,EAAA,mBAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,UAAA,EAAA,OAAA,EAAA,uBAAA,EAAA,kBAAA,EAAA,oBAAA,EAAA,SAAA,EAAA,eAAA,CAAA,EAAA,OAAA,EAAA,CAAA,cAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;2FAAxB,wBAAwB,EAAA,UAAA,EAAA,CAAA;kBANpC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,mBAAmB,WACpB,EAAE,EAAA,QAAA,EAAA,y1HAAA,EAAA,MAAA,EAAA,CAAA,4mHAAA,CAAA,EAAA;;;AEZb;;AAEG;;ACFH;;AAEG;;;;"}