@c8y/ngx-components
Version:
Angular modules for Cumulocity IoT applications
1 lines • 21.4 kB
Source Map (JSON)
{"version":3,"file":"c8y-ngx-components-operation-picker.mjs","sources":["../../operation-picker/operation-template.hook.ts","../../operation-picker/operation-template.service.ts","../../operation-picker/modal/operation-modal.component.ts","../../operation-picker/modal/operation-modal.component.html","../../operation-picker/operation-picker.service.ts","../../operation-picker/c8y-ngx-components-operation-picker.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\nimport { GenericHookOptions, GenericHookType, hookGeneric } from '@c8y/ngx-components';\n\n/**\n * Represents a predefined operation template that can be registered\n * and selected in the operation render type modal.\n */\nexport interface OperationTemplate {\n /** Display name shown in the dropdown. */\n name: string;\n /** The operation command object that will be serialized as JSON into the command field.\n * The command object must contain a `description` property, which will be used as the description of the operation in the UI.\n * The rest of the properties can be defined based on the requirements of the specific operation.\n * For example, a restart operation might look like this:\n * ```\n * {\n * description: 'Restart device',\n * c8y_Restart: {}\n * }\n * ```\n * Or a more complex command with parameters:\n * ```\n * {\n * description: 'Set relay status to OPEN',\n * c8y_Relay: {\n * relayState: 'OPEN'\n * }\n * }\n * ```\n */\n command: Record<string, unknown>;\n}\n\n/**\n * Injection token for registering additional operation templates.\n *\n * Use the `hookOperationTemplate` helper to register templates from a plugin:\n *\n * ```typescript\n * // Provide a single template\n * hookOperationTemplate({ name: 'Restart device', command: { c8y_Restart: {} } })\n *\n * // Provide multiple templates\n * hookOperationTemplate([\n * { name: 'Restart device', command: { c8y_Restart: {} } },\n * { name: 'Set relay OPEN', command: { c8y_Relay: { relayState: 'OPEN' } } }\n * ])\n * ```\n */\nexport const HOOK_OPERATION_TEMPLATE = new InjectionToken<OperationTemplate[]>(\n 'HOOK_OPERATION_TEMPLATE'\n);\n\n/**\n * Registers one or more operation templates to be shown in the operation modal selector.\n *\n * @example\n * ```typescript\n * \\@NgModule({\n * providers: [\n * hookOperationTemplate({ name: 'Restart device', command: { c8y_Restart: {} } })\n * ]\n * })\n * export class MyPlugin {}\n * ```\n */\nexport function hookOperationTemplate(\n template: GenericHookType<OperationTemplate>,\n options?: Partial<GenericHookOptions>\n) {\n return hookGeneric<OperationTemplate>(template, HOOK_OPERATION_TEMPLATE, options);\n}\n","import { Injectable, Injector } from '@angular/core';\nimport {\n ExtensionPointForPlugins,\n fromTriggerOnce,\n getInjectedHooks,\n PluginsResolveService\n} from '@c8y/ngx-components';\nimport { distinctUntilChanged, Observable, shareReplay } from 'rxjs';\nimport { HOOK_OPERATION_TEMPLATE, OperationTemplate } from './operation-template.hook';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class OperationTemplateService extends ExtensionPointForPlugins<OperationTemplate> {\n items$: Observable<OperationTemplate[]>;\n\n constructor(rootInjector: Injector, pluginService: PluginsResolveService) {\n super(rootInjector, pluginService);\n this.items$ = this.setupItemsObservable();\n }\n\n get state() {\n return this.state$.value;\n }\n\n protected setupItemsObservable(): Observable<OperationTemplate[]> {\n return fromTriggerOnce<OperationTemplate>(undefined, this.refresh$, [\n getInjectedHooks<OperationTemplate>(HOOK_OPERATION_TEMPLATE, this.injectors),\n () => this.factories\n ]).pipe(distinctUntilChanged(), shareReplay(1));\n }\n}\n","import { Component, DestroyRef, inject, OnInit } from '@angular/core';\nimport {\n FormBuilder,\n FormControl,\n FormGroup,\n FormsModule,\n ReactiveFormsModule,\n Validators\n} from '@angular/forms';\nimport {\n CommonModule,\n CoreModule,\n ModalModule,\n ModalLabels,\n C8yTranslateModule\n} from '@c8y/ngx-components';\nimport { gettext } from '@c8y/ngx-components/gettext';\nimport { TranslateService } from '@ngx-translate/core';\nimport { DeviceShellService, DeviceShellTemplate } from '@c8y/ngx-components/device-shell';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { Observable, startWith, withLatestFrom } from 'rxjs';\nimport { OperationTemplate } from '../operation-template.hook';\nimport { OperationTemplateService } from '../operation-template.service';\nimport { OperationModalInitialConfig } from '../operation-picker.model';\n\ninterface OperationRenderForm {\n buttonLabel: FormControl<string>;\n operation: FormControl<string | null>;\n command: FormControl<string>;\n}\n\ninterface OperationRenderFormValue {\n buttonLabel: string;\n operation: string | null;\n command: string;\n}\n\ninterface PredefinedOperation {\n name: string;\n command: Record<string, unknown>;\n}\n\n@Component({\n selector: 'c8y-operation-render-type-modal',\n templateUrl: './operation-modal.component.html',\n standalone: true,\n imports: [\n ModalModule,\n FormsModule,\n ReactiveFormsModule,\n C8yTranslateModule,\n CommonModule,\n CoreModule\n ],\n providers: [DeviceShellService]\n})\nexport class OperationModalComponent implements OnInit {\n showButtonLabelOnly = false;\n initialConfig: OperationModalInitialConfig = {};\n deviceTypes: string[] = [];\n templates: DeviceShellTemplate[] = [];\n pluginTemplates$!: Observable<OperationTemplate[]>;\n predefinedOperations: PredefinedOperation[] = [\n {\n name: gettext('Restart device'),\n command: { description: gettext('Restart device'), c8y_Restart: {} }\n },\n {\n name: gettext('Change relay status to OPEN'),\n command: {\n description: gettext('Change relay status to OPEN.'),\n c8y_Relay: { relayState: 'OPEN' }\n }\n },\n {\n name: gettext('Change relay status to CLOSED'),\n command: {\n description: gettext('Change relay status to CLOSED.'),\n c8y_Relay: { relayState: 'CLOSED' }\n }\n }\n ];\n\n labels: ModalLabels = { ok: gettext('Save'), cancel: gettext('Cancel') };\n form!: FormGroup<OperationRenderForm>;\n\n result: Promise<OperationRenderFormValue> = new Promise((resolve, reject) => {\n this._save = resolve;\n this._cancel = reject;\n });\n\n get modalTitle(): string {\n if (this.showButtonLabelOnly) {\n return this.translate.instant(gettext('Maintenance mode'));\n }\n const buttonLabel = this.form?.get('buttonLabel')?.value;\n return buttonLabel\n ? this.translate.instant(gettext('Edit operation'))\n : this.translate.instant(gettext('Create operation'));\n }\n\n private _save!: (value: OperationRenderFormValue) => void;\n private _cancel!: () => void;\n\n private readonly fb = inject(FormBuilder);\n private readonly translate = inject(TranslateService);\n private readonly deviceShellService = inject(DeviceShellService);\n private readonly operationTemplateService = inject(OperationTemplateService);\n private readonly destroyRef = inject(DestroyRef);\n\n async ngOnInit(): Promise<void> {\n const defaultCommand = JSON.stringify(\n { description: 'Command description', c8y_Command: { text: '<command>' } },\n null,\n 2\n );\n\n this.form = this.fb.group<OperationRenderForm>({\n buttonLabel: new FormControl(this.initialConfig?.buttonLabel ?? '', {\n validators: [Validators.required]\n }),\n operation: new FormControl<string | null>(this.initialConfig?.operationType ?? null),\n command: new FormControl(this.initialConfig?.command ?? defaultCommand, {\n validators: [Validators.required]\n })\n });\n\n if (this.deviceTypes?.length) {\n const loadedTemplates = await this.deviceShellService.getCommandTemplatesForDeviceType(\n this.deviceTypes\n );\n this.templates = loadedTemplates.map(t => ({\n name: t.name,\n text: t.text,\n category: t.category\n }));\n }\n\n this.pluginTemplates$ = this.operationTemplateService.items$;\n\n this.form\n .get('operation')\n ?.valueChanges.pipe(\n withLatestFrom(this.pluginTemplates$.pipe(startWith([] as OperationTemplate[]))),\n takeUntilDestroyed(this.destroyRef)\n )\n .subscribe(([selectedName, pluginTemplates]) => {\n const predefined = [...this.predefinedOperations, ...pluginTemplates].find(\n p => p.name === selectedName\n );\n if (predefined) {\n this.form.get('command')?.setValue(JSON.stringify(predefined.command, null, 2));\n return;\n }\n\n const template = this.templates.find(t => t.name === selectedName);\n if (template) {\n const cmd = JSON.stringify(\n { description: template.name, c8y_Command: { text: template.text } },\n null,\n 2\n );\n this.form.get('command')?.setValue(cmd);\n }\n });\n }\n\n onClose(_: unknown) {\n if (this.form.valid) {\n this._save(this.form.getRawValue());\n }\n }\n\n onDismiss(_: unknown) {\n this._cancel();\n }\n}\n","<c8y-modal\n [title]=\"modalTitle\"\n (onClose)=\"onClose($event)\"\n (onDismiss)=\"onDismiss($event)\"\n [labels]=\"labels\"\n [disabled]=\"form?.invalid\"\n [headerClasses]=\"'dialog-header'\"\n>\n <ng-container c8y-modal-title>\n <span [c8yIcon]=\"'cog'\"></span>\n </ng-container>\n <form\n class=\"p-24\"\n [formGroup]=\"form\"\n >\n <c8y-form-group>\n <label\n for=\"buttonLabel\"\n translate\n >\n Button label\n </label>\n <input\n class=\"form-control\"\n id=\"buttonLabel\"\n placeholder=\"{{ 'e.g. Execute operation' | translate }}\"\n type=\"text\"\n formControlName=\"buttonLabel\"\n />\n <c8y-messages></c8y-messages>\n </c8y-form-group>\n\n @if (!showButtonLabelOnly) {\n <div class=\"form-group\">\n <label\n for=\"operation\"\n translate\n >\n Operation\n </label>\n <div class=\"c8y-select-wrapper\">\n <select\n class=\"form-control\"\n id=\"operation\"\n formControlName=\"operation\"\n >\n <optgroup label=\"{{ 'Predefined' | translate }}\">\n @for (op of predefinedOperations; track op.name) {\n <option [ngValue]=\"op.name\">{{ op.name | translate }}</option>\n }\n </optgroup>\n @let pluginTemplates = pluginTemplates$ | async;\n @if (pluginTemplates?.length) {\n <optgroup label=\"{{ 'Plugin templates' | translate }}\">\n @for (op of pluginTemplates; track op.name) {\n <option [ngValue]=\"op.name\">{{ op.name | translate }}</option>\n }\n </optgroup>\n }\n @if (templates.length) {\n <optgroup label=\"{{ 'Device templates' | translate }}\">\n @for (op of templates; track op.name) {\n <option [ngValue]=\"op.name\">{{ op.name | translate }}</option>\n }\n </optgroup>\n }\n </select>\n </div>\n </div>\n <div class=\"form-group\">\n <label\n for=\"command\"\n translate\n >\n Command\n </label>\n <textarea\n class=\"form-control no-resize inner-scroll\"\n style=\"max-height: 300px\"\n id=\"command\"\n c8y-textarea-autoresize\n formControlName=\"command\"\n maxlength=\"900\"\n ></textarea>\n </div>\n }\n </form>\n</c8y-modal>\n","import { inject, Injectable } from '@angular/core';\nimport { BsModalService } from 'ngx-bootstrap/modal';\nimport { OperationModalInitialConfig, OperationModalResult } from './operation-picker.model';\nimport { OperationModalComponent } from './modal/operation-modal.component';\n\n@Injectable({ providedIn: 'root' })\nexport class OperationPickerService {\n private readonly modalService = inject(BsModalService);\n\n /**\n *\n * @param options Modal configuration options\n * `showButtonLabelOnly` - if `true`, only button label will be shown in the modal, otherwise user will be able to select both operation and command. This is useful when you want to allow users to select only predefined operations (e.g. restart, shutdown) without showing them the underlying operation types and commands.\n * `deviceTypes` - list of device types to filter available operations. Only operations applicable to the provided device types will be shown in the modal.\n * `initialConfig` - initial configuration for the modal form. This is useful when you want to edit existing configuration, so you can prefill the form with existing values.\n * @returns\n */\n async openModal(options: {\n showButtonLabelOnly: boolean;\n deviceTypes: string[];\n initialConfig?: Partial<OperationModalInitialConfig>;\n }): Promise<OperationModalResult> {\n const modal = this.modalService.show(OperationModalComponent, {\n class: 'modal-sm',\n ariaDescribedby: 'modal-body',\n ariaLabelledBy: 'modal-title',\n ignoreBackdropClick: true,\n initialState: {\n initialConfig: options.initialConfig ?? {},\n showButtonLabelOnly: options.showButtonLabelOnly,\n deviceTypes: options.deviceTypes\n }\n }).content;\n\n return modal.result;\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;;;;;;;;;AAiCA;;;;;;;;;;;;;;;AAeG;AACI,MAAM,uBAAuB,GAAG,IAAI,cAAc,CACvD,yBAAyB,CAC1B;AAED;;;;;;;;;;;;AAYG;AACG,SAAU,qBAAqB,CACnC,QAA4C,EAC5C,OAAqC,EAAA;IAErC,OAAO,WAAW,CAAoB,QAAQ,EAAE,uBAAuB,EAAE,OAAO,CAAC;AACnF;;AC1DM,MAAO,wBAAyB,SAAQ,wBAA2C,CAAA;IAGvF,WAAA,CAAY,YAAsB,EAAE,aAAoC,EAAA;AACtE,QAAA,KAAK,CAAC,YAAY,EAAE,aAAa,CAAC;AAClC,QAAA,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,oBAAoB,EAAE;IAC3C;AAEA,IAAA,IAAI,KAAK,GAAA;AACP,QAAA,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK;IAC1B;IAEU,oBAAoB,GAAA;AAC5B,QAAA,OAAO,eAAe,CAAoB,SAAS,EAAE,IAAI,CAAC,QAAQ,EAAE;AAClE,YAAA,gBAAgB,CAAoB,uBAAuB,EAAE,IAAI,CAAC,SAAS,CAAC;AAC5E,YAAA,MAAM,IAAI,CAAC;SACZ,CAAC,CAAC,IAAI,CAAC,oBAAoB,EAAE,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;IACjD;+GAjBW,wBAAwB,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAA,EAAA,CAAA,QAAA,EAAA,EAAA,EAAA,KAAA,EAAA,EAAA,CAAA,qBAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAAxB,IAAA,SAAA,IAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,wBAAwB,cAFvB,MAAM,EAAA,CAAA,CAAA;;4FAEP,wBAAwB,EAAA,UAAA,EAAA,CAAA;kBAHpC,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;AACV,oBAAA,UAAU,EAAE;AACb,iBAAA;;;MC4CY,uBAAuB,CAAA;AAdpC,IAAA,WAAA,GAAA;QAeE,IAAA,CAAA,mBAAmB,GAAG,KAAK;QAC3B,IAAA,CAAA,aAAa,GAAgC,EAAE;QAC/C,IAAA,CAAA,WAAW,GAAa,EAAE;QAC1B,IAAA,CAAA,SAAS,GAA0B,EAAE;AAErC,QAAA,IAAA,CAAA,oBAAoB,GAA0B;AAC5C,YAAA;AACE,gBAAA,IAAI,EAAE,OAAO,CAAC,gBAAgB,CAAC;AAC/B,gBAAA,OAAO,EAAE,EAAE,WAAW,EAAE,OAAO,CAAC,gBAAgB,CAAC,EAAE,WAAW,EAAE,EAAE;AACnE,aAAA;AACD,YAAA;AACE,gBAAA,IAAI,EAAE,OAAO,CAAC,6BAA6B,CAAC;AAC5C,gBAAA,OAAO,EAAE;AACP,oBAAA,WAAW,EAAE,OAAO,CAAC,8BAA8B,CAAC;AACpD,oBAAA,SAAS,EAAE,EAAE,UAAU,EAAE,MAAM;AAChC;AACF,aAAA;AACD,YAAA;AACE,gBAAA,IAAI,EAAE,OAAO,CAAC,+BAA+B,CAAC;AAC9C,gBAAA,OAAO,EAAE;AACP,oBAAA,WAAW,EAAE,OAAO,CAAC,gCAAgC,CAAC;AACtD,oBAAA,SAAS,EAAE,EAAE,UAAU,EAAE,QAAQ;AAClC;AACF;SACF;AAED,QAAA,IAAA,CAAA,MAAM,GAAgB,EAAE,EAAE,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,EAAE;QAGxE,IAAA,CAAA,MAAM,GAAsC,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,KAAI;AAC1E,YAAA,IAAI,CAAC,KAAK,GAAG,OAAO;AACpB,YAAA,IAAI,CAAC,OAAO,GAAG,MAAM;AACvB,QAAA,CAAC,CAAC;AAee,QAAA,IAAA,CAAA,EAAE,GAAG,MAAM,CAAC,WAAW,CAAC;AACxB,QAAA,IAAA,CAAA,SAAS,GAAG,MAAM,CAAC,gBAAgB,CAAC;AACpC,QAAA,IAAA,CAAA,kBAAkB,GAAG,MAAM,CAAC,kBAAkB,CAAC;AAC/C,QAAA,IAAA,CAAA,wBAAwB,GAAG,MAAM,CAAC,wBAAwB,CAAC;AAC3D,QAAA,IAAA,CAAA,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;AAoEjD,IAAA;AArFC,IAAA,IAAI,UAAU,GAAA;AACZ,QAAA,IAAI,IAAI,CAAC,mBAAmB,EAAE;YAC5B,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;QAC5D;AACA,QAAA,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,aAAa,CAAC,EAAE,KAAK;AACxD,QAAA,OAAO;cACH,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAC;AAClD,cAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACzD;AAWA,IAAA,MAAM,QAAQ,GAAA;QACZ,MAAM,cAAc,GAAG,IAAI,CAAC,SAAS,CACnC,EAAE,WAAW,EAAE,qBAAqB,EAAE,WAAW,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAC1E,IAAI,EACJ,CAAC,CACF;QAED,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,KAAK,CAAsB;YAC7C,WAAW,EAAE,IAAI,WAAW,CAAC,IAAI,CAAC,aAAa,EAAE,WAAW,IAAI,EAAE,EAAE;AAClE,gBAAA,UAAU,EAAE,CAAC,UAAU,CAAC,QAAQ;aACjC,CAAC;YACF,SAAS,EAAE,IAAI,WAAW,CAAgB,IAAI,CAAC,aAAa,EAAE,aAAa,IAAI,IAAI,CAAC;YACpF,OAAO,EAAE,IAAI,WAAW,CAAC,IAAI,CAAC,aAAa,EAAE,OAAO,IAAI,cAAc,EAAE;AACtE,gBAAA,UAAU,EAAE,CAAC,UAAU,CAAC,QAAQ;aACjC;AACF,SAAA,CAAC;AAEF,QAAA,IAAI,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE;AAC5B,YAAA,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,gCAAgC,CACpF,IAAI,CAAC,WAAW,CACjB;YACD,IAAI,CAAC,SAAS,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,KAAK;gBACzC,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,QAAQ,EAAE,CAAC,CAAC;AACb,aAAA,CAAC,CAAC;QACL;QAEA,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,wBAAwB,CAAC,MAAM;AAE5D,QAAA,IAAI,CAAC;aACF,GAAG,CAAC,WAAW;cACd,YAAY,CAAC,IAAI,CACjB,cAAc,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,SAAS,CAAC,EAAyB,CAAC,CAAC,CAAC,EAChF,kBAAkB,CAAC,IAAI,CAAC,UAAU,CAAC;aAEpC,SAAS,CAAC,CAAC,CAAC,YAAY,EAAE,eAAe,CAAC,KAAI;YAC7C,MAAM,UAAU,GAAG,CAAC,GAAG,IAAI,CAAC,oBAAoB,EAAE,GAAG,eAAe,CAAC,CAAC,IAAI,CACxE,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,YAAY,CAC7B;YACD,IAAI,UAAU,EAAE;gBACd,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;gBAC/E;YACF;AAEA,YAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,YAAY,CAAC;YAClE,IAAI,QAAQ,EAAE;AACZ,gBAAA,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CACxB,EAAE,WAAW,EAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,EAAE,EACpE,IAAI,EACJ,CAAC,CACF;AACD,gBAAA,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,QAAQ,CAAC,GAAG,CAAC;YACzC;AACF,QAAA,CAAC,CAAC;IACN;AAEA,IAAA,OAAO,CAAC,CAAU,EAAA;AAChB,QAAA,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE;YACnB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;QACrC;IACF;AAEA,IAAA,SAAS,CAAC,CAAU,EAAA;QAClB,IAAI,CAAC,OAAO,EAAE;IAChB;+GAvHW,uBAAuB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAAvB,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,uBAAuB,8EAFvB,CAAC,kBAAkB,CAAC,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECtDjC,0iFAwFA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EDzCI,WAAW,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,cAAA,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,UAAA,EAAA,OAAA,EAAA,SAAA,EAAA,OAAA,EAAA,MAAA,EAAA,cAAA,EAAA,eAAA,EAAA,QAAA,CAAA,EAAA,OAAA,EAAA,CAAA,WAAA,EAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EACX,WAAW,ytCACX,mBAAmB,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,kBAAA,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,CAAA,WAAA,CAAA,EAAA,OAAA,EAAA,CAAA,UAAA,CAAA,EAAA,QAAA,EAAA,CAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,mBAAA,EAAA,MAAA,EAAA,CAAA,iBAAA,EAAA,UAAA,EAAA,SAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EACnB,kBAAkB,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,qBAAA,EAAA,QAAA,EAAA,6BAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAClB,YAAY,6NACZ,UAAU,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,kBAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,CAAA,UAAA,EAAA,YAAA,EAAA,YAAA,EAAA,cAAA,EAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,iBAAA,EAAA,QAAA,EAAA,cAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,UAAA,EAAA,aAAA,EAAA,oBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,iCAAA,EAAA,QAAA,EAAA,yCAAA,EAAA,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAA,EAAA,CAAA,gBAAA,EAAA,IAAA,EAAA,WAAA,EAAA,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAA,EAAA,CAAA,SAAA,EAAA,IAAA,EAAA,OAAA,EAAA,CAAA,EAAA,CAAA,CAAA;;4FAID,uBAAuB,EAAA,UAAA,EAAA,CAAA;kBAdnC,SAAS;+BACE,iCAAiC,EAAA,UAAA,EAE/B,IAAI,EAAA,OAAA,EACP;wBACP,WAAW;wBACX,WAAW;wBACX,mBAAmB;wBACnB,kBAAkB;wBAClB,YAAY;wBACZ;qBACD,EAAA,SAAA,EACU,CAAC,kBAAkB,CAAC,EAAA,QAAA,EAAA,0iFAAA,EAAA;;;MEhDpB,sBAAsB,CAAA;AADnC,IAAA,WAAA,GAAA;AAEmB,QAAA,IAAA,CAAA,YAAY,GAAG,MAAM,CAAC,cAAc,CAAC;AA6BvD,IAAA;AA3BC;;;;;;;AAOG;IACH,MAAM,SAAS,CAAC,OAIf,EAAA;QACC,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,uBAAuB,EAAE;AAC5D,YAAA,KAAK,EAAE,UAAU;AACjB,YAAA,eAAe,EAAE,YAAY;AAC7B,YAAA,cAAc,EAAE,aAAa;AAC7B,YAAA,mBAAmB,EAAE,IAAI;AACzB,YAAA,YAAY,EAAE;AACZ,gBAAA,aAAa,EAAE,OAAO,CAAC,aAAa,IAAI,EAAE;gBAC1C,mBAAmB,EAAE,OAAO,CAAC,mBAAmB;gBAChD,WAAW,EAAE,OAAO,CAAC;AACtB;SACF,CAAC,CAAC,OAAO;QAEV,OAAO,KAAK,CAAC,MAAM;IACrB;+GA7BW,sBAAsB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAAtB,IAAA,SAAA,IAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,sBAAsB,cADT,MAAM,EAAA,CAAA,CAAA;;4FACnB,sBAAsB,EAAA,UAAA,EAAA,CAAA;kBADlC,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;ACLlC;;AAEG;;;;"}