@memberjunction/ng-base-forms 5.37.0 → 5.39.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +53 -0
- package/dist/lib/base-form-component.d.ts +46 -0
- package/dist/lib/base-form-component.d.ts.map +1 -1
- package/dist/lib/base-form-component.js +68 -2
- package/dist/lib/base-form-component.js.map +1 -1
- package/dist/lib/container/record-form-container.component.d.ts +77 -1
- package/dist/lib/container/record-form-container.component.d.ts.map +1 -1
- package/dist/lib/container/record-form-container.component.js +157 -39
- package/dist/lib/container/record-form-container.component.js.map +1 -1
- package/dist/lib/field/fk-search-utils.d.ts +31 -0
- package/dist/lib/field/fk-search-utils.d.ts.map +1 -0
- package/dist/lib/field/fk-search-utils.js +47 -0
- package/dist/lib/field/fk-search-utils.js.map +1 -0
- package/dist/lib/field/form-field.component.d.ts +401 -6
- package/dist/lib/field/form-field.component.d.ts.map +1 -1
- package/dist/lib/field/form-field.component.js +1646 -214
- package/dist/lib/field/form-field.component.js.map +1 -1
- package/dist/lib/field/linked-field-options.d.ts +76 -0
- package/dist/lib/field/linked-field-options.d.ts.map +1 -0
- package/dist/lib/field/linked-field-options.js +80 -0
- package/dist/lib/field/linked-field-options.js.map +1 -0
- package/dist/lib/host/entity-form-host.component.d.ts +159 -0
- package/dist/lib/host/entity-form-host.component.d.ts.map +1 -0
- package/dist/lib/host/entity-form-host.component.js +539 -0
- package/dist/lib/host/entity-form-host.component.js.map +1 -0
- package/dist/lib/interactive-form/interactive-form.component.d.ts +181 -0
- package/dist/lib/interactive-form/interactive-form.component.d.ts.map +1 -0
- package/dist/lib/interactive-form/interactive-form.component.js +560 -0
- package/dist/lib/interactive-form/interactive-form.component.js.map +1 -0
- package/dist/lib/isa-related-panel/isa-related-card.component.js +2 -2
- package/dist/lib/overlays/base-form-overlay.d.ts +114 -0
- package/dist/lib/overlays/base-form-overlay.d.ts.map +1 -0
- package/dist/lib/overlays/base-form-overlay.js +227 -0
- package/dist/lib/overlays/base-form-overlay.js.map +1 -0
- package/dist/lib/overlays/form-dialog.component.d.ts +35 -0
- package/dist/lib/overlays/form-dialog.component.d.ts.map +1 -0
- package/dist/lib/overlays/form-dialog.component.js +92 -0
- package/dist/lib/overlays/form-dialog.component.js.map +1 -0
- package/dist/lib/overlays/form-presenter.service.d.ts +37 -0
- package/dist/lib/overlays/form-presenter.service.d.ts.map +1 -0
- package/dist/lib/overlays/form-presenter.service.js +130 -0
- package/dist/lib/overlays/form-presenter.service.js.map +1 -0
- package/dist/lib/overlays/form-presenter.types.d.ts +65 -0
- package/dist/lib/overlays/form-presenter.types.d.ts.map +1 -0
- package/dist/lib/overlays/form-presenter.types.js +25 -0
- package/dist/lib/overlays/form-presenter.types.js.map +1 -0
- package/dist/lib/overlays/form-slide-in.component.d.ts +38 -0
- package/dist/lib/overlays/form-slide-in.component.d.ts.map +1 -0
- package/dist/lib/overlays/form-slide-in.component.js +106 -0
- package/dist/lib/overlays/form-slide-in.component.js.map +1 -0
- package/dist/lib/overlays/form-window.component.d.ts +32 -0
- package/dist/lib/overlays/form-window.component.d.ts.map +1 -0
- package/dist/lib/overlays/form-window.component.js +93 -0
- package/dist/lib/overlays/form-window.component.js.map +1 -0
- package/dist/lib/panel/collapsible-panel.component.d.ts +19 -2
- package/dist/lib/panel/collapsible-panel.component.d.ts.map +1 -1
- package/dist/lib/panel/collapsible-panel.component.js +70 -13
- package/dist/lib/panel/collapsible-panel.component.js.map +1 -1
- package/dist/lib/panel-slot/base-form-panel.d.ts +97 -0
- package/dist/lib/panel-slot/base-form-panel.d.ts.map +1 -0
- package/dist/lib/panel-slot/base-form-panel.js +64 -0
- package/dist/lib/panel-slot/base-form-panel.js.map +1 -0
- package/dist/lib/panel-slot/form-panel-slot.component.d.ts +78 -0
- package/dist/lib/panel-slot/form-panel-slot.component.d.ts.map +1 -0
- package/dist/lib/panel-slot/form-panel-slot.component.js +227 -0
- package/dist/lib/panel-slot/form-panel-slot.component.js.map +1 -0
- package/dist/lib/panel-slot/form-slot-coordinator.service.d.ts +57 -0
- package/dist/lib/panel-slot/form-slot-coordinator.service.d.ts.map +1 -0
- package/dist/lib/panel-slot/form-slot-coordinator.service.js +104 -0
- package/dist/lib/panel-slot/form-slot-coordinator.service.js.map +1 -0
- package/dist/lib/resolver/form-resolver.service.d.ts +139 -0
- package/dist/lib/resolver/form-resolver.service.d.ts.map +1 -0
- package/dist/lib/resolver/form-resolver.service.js +235 -0
- package/dist/lib/resolver/form-resolver.service.js.map +1 -0
- package/dist/lib/section-manager/section-manager.component.js +2 -2
- package/dist/lib/toolbar/form-toolbar.component.d.ts +56 -1
- package/dist/lib/toolbar/form-toolbar.component.d.ts.map +1 -1
- package/dist/lib/toolbar/form-toolbar.component.js +294 -136
- package/dist/lib/toolbar/form-toolbar.component.js.map +1 -1
- package/dist/lib/types/entity-form-config.d.ts +125 -0
- package/dist/lib/types/entity-form-config.d.ts.map +1 -0
- package/dist/lib/types/entity-form-config.js +75 -0
- package/dist/lib/types/entity-form-config.js.map +1 -0
- package/dist/lib/types/form-types.d.ts +24 -0
- package/dist/lib/types/form-types.d.ts.map +1 -1
- package/dist/lib/types/form-types.js.map +1 -1
- package/dist/lib/types/navigation-events.d.ts +64 -2
- package/dist/lib/types/navigation-events.d.ts.map +1 -1
- package/dist/lib/types/navigation-events.js.map +1 -1
- package/dist/lib/types/toolbar-config.d.ts +11 -0
- package/dist/lib/types/toolbar-config.d.ts.map +1 -1
- package/dist/lib/types/toolbar-config.js +3 -0
- package/dist/lib/types/toolbar-config.js.map +1 -1
- package/dist/module.d.ts +14 -7
- package/dist/module.d.ts.map +1 -1
- package/dist/module.js +40 -7
- package/dist/module.js.map +1 -1
- package/dist/public-api.d.ts +15 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +21 -0
- package/dist/public-api.js.map +1 -1
- package/package.json +17 -11
- package/dist/__tests__/sanity.test.d.ts +0 -2
- package/dist/__tests__/sanity.test.d.ts.map +0 -1
- package/dist/__tests__/sanity.test.js +0 -12
- package/dist/__tests__/sanity.test.js.map +0 -1
- package/dist/__tests__/tag-count-badge.test.d.ts +0 -2
- package/dist/__tests__/tag-count-badge.test.d.ts.map +0 -1
- package/dist/__tests__/tag-count-badge.test.js +0 -70
- package/dist/__tests__/tag-count-badge.test.js.map +0 -1
- package/dist/lib/__tests__/base-forms.test.d.ts +0 -2
- package/dist/lib/__tests__/base-forms.test.d.ts.map +0 -1
- package/dist/lib/__tests__/base-forms.test.js +0 -256
- package/dist/lib/__tests__/base-forms.test.js.map +0 -1
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { EventEmitter, OnDestroy, OnInit } from '@angular/core';
|
|
2
|
+
import { BaseEntity } from '@memberjunction/core';
|
|
3
|
+
import { ComponentSpec } from '@memberjunction/interactive-component-types';
|
|
4
|
+
import { FormHostProps } from '@memberjunction/interactive-component-types/forms';
|
|
5
|
+
import { MJReactComponent, ReactComponentEvent } from '@memberjunction/ng-react';
|
|
6
|
+
import { BaseFormComponent } from '../base-form-component';
|
|
7
|
+
import * as i0 from "@angular/core";
|
|
8
|
+
/**
|
|
9
|
+
* Wraps a Component (the IC kind — declared `componentRole: 'form'`) so it can
|
|
10
|
+
* stand in for an Angular form on any entity.
|
|
11
|
+
*
|
|
12
|
+
* **Layering invariant:** the React component never touches BaseEntity. This
|
|
13
|
+
* wrapper owns the entity lifecycle (`record.Save`, `record.Delete`, mode
|
|
14
|
+
* transitions). The React component sees only the snapshot in
|
|
15
|
+
* {@link FormHostProps} and communicates back via `BeforeSave` /
|
|
16
|
+
* `BeforeDelete` / `EditModeChangeRequested` events plus its dirty-field diff.
|
|
17
|
+
*
|
|
18
|
+
* Instantiated by `SingleRecordComponent.LoadForm` when the resolver finds an
|
|
19
|
+
* `EntityFormOverride` matching the user's scope. Behaves exactly like the
|
|
20
|
+
* generated Angular form from the host's perspective: same `record` setter,
|
|
21
|
+
* same `EditMode` toggle, same outputs.
|
|
22
|
+
*/
|
|
23
|
+
export declare class InteractiveFormComponent extends BaseFormComponent implements OnInit, OnDestroy {
|
|
24
|
+
/**
|
|
25
|
+
* The bound record. Backed by a setter so swapping records *after*
|
|
26
|
+
* the component has mounted (e.g. Form Builder cockpit preview record
|
|
27
|
+
* picker) triggers a fresh `originalSnapshot` capture + a
|
|
28
|
+
* `formHostProps` rebuild — without this, the React form keeps
|
|
29
|
+
* rendering the original record's values even after the input
|
|
30
|
+
* changes. Guarded on `_recordInitialized` so the post-mount path
|
|
31
|
+
* doesn't fire during the first input assignment (handled by
|
|
32
|
+
* `ngOnInit`, which sets both `originalSnapshot` and `formHostProps`).
|
|
33
|
+
*/
|
|
34
|
+
private _record;
|
|
35
|
+
private _recordInitialized;
|
|
36
|
+
set record(value: BaseEntity);
|
|
37
|
+
get record(): BaseEntity;
|
|
38
|
+
/**
|
|
39
|
+
* The Component row ID resolved for this (entity, user, roles) tuple. Set
|
|
40
|
+
* by `SingleRecordComponent.LoadForm` after the resolver returns an
|
|
41
|
+
* override.
|
|
42
|
+
*/
|
|
43
|
+
ComponentID: string | null;
|
|
44
|
+
/**
|
|
45
|
+
* Loaded ComponentSpec, parsed from the Component row's `Specification` JSON.
|
|
46
|
+
*
|
|
47
|
+
* Two ways to populate this:
|
|
48
|
+
* 1. **Via `ComponentID`** (the standard path): set the input, ngOnInit
|
|
49
|
+
* fetches the row from `MJ: Components` and assigns the parsed spec.
|
|
50
|
+
* 2. **Direct assignment** (the artifact-viewer path): the caller already
|
|
51
|
+
* has the spec in hand (parsed from an artifact JSON blob) and sets
|
|
52
|
+
* `componentSpec` directly. In that case `ComponentID` should be left
|
|
53
|
+
* null and the DB fetch is skipped.
|
|
54
|
+
*/
|
|
55
|
+
componentSpec: ComponentSpec | null;
|
|
56
|
+
/**
|
|
57
|
+
* When true, render the React component **without** the
|
|
58
|
+
* `<mj-record-form-container>` wrapper — i.e. no toolbar (no Save /
|
|
59
|
+
* Cancel / Edit / Delete / History / Tags / Lists).
|
|
60
|
+
*
|
|
61
|
+
* Used by the Form Builder cockpit's Preview tab where the toolbar's
|
|
62
|
+
* actions don't apply (Save would save the *record*, but the cockpit's
|
|
63
|
+
* own Save button saves the *spec*; History/Tags assume a real
|
|
64
|
+
* persistent record, but the preview record can be a synthetic
|
|
65
|
+
* NewRecord). Keeping just the form body produces a clean "this is
|
|
66
|
+
* what the form looks like" view.
|
|
67
|
+
*/
|
|
68
|
+
previewMode: boolean;
|
|
69
|
+
/** FormHostProps passed to the React component. Recomputed when record or mode changes. */
|
|
70
|
+
formHostProps: FormHostProps | null;
|
|
71
|
+
/** Loaded-spec error (component row missing, JSON parse failure, etc.). */
|
|
72
|
+
private _loadError;
|
|
73
|
+
/**
|
|
74
|
+
* Loaded-spec error (component row missing, JSON parse failure,
|
|
75
|
+
* React-runtime bootstrap failure, etc.). Setter auto-emits
|
|
76
|
+
* `LoadErrorChanged` so host surfaces (e.g. Form Builder cockpit
|
|
77
|
+
* Preview tab) can show their own error state — retrospective fix #10.
|
|
78
|
+
*/
|
|
79
|
+
get loadError(): string | null;
|
|
80
|
+
set loadError(v: string | null);
|
|
81
|
+
LoadErrorChanged: EventEmitter<string | null>;
|
|
82
|
+
/** Tracks last-known field snapshot for computing the dirty-field diff on save. */
|
|
83
|
+
private originalSnapshot;
|
|
84
|
+
/**
|
|
85
|
+
* Reference to the mounted React component. Used by the SaveRecord /
|
|
86
|
+
* CancelEdit overrides below to invoke the component's registered
|
|
87
|
+
* `RequestSave` / `RequestCancel` methods when the host toolbar fires
|
|
88
|
+
* Save/Cancel — so the single user-visible Save lives on the toolbar
|
|
89
|
+
* (consistent with every other entity form in MJ) and not duplicated
|
|
90
|
+
* inside the form body.
|
|
91
|
+
*/
|
|
92
|
+
reactComponent?: MJReactComponent;
|
|
93
|
+
/**
|
|
94
|
+
* Promise resolver populated when `SaveRecord` invokes `RequestSave`
|
|
95
|
+
* on the React component. `handleBeforeSave` resolves it after the
|
|
96
|
+
* BeforeSave-driven entity save completes, so SaveRecord can return
|
|
97
|
+
* a meaningful success boolean and honor `StopEditModeAfterSave`.
|
|
98
|
+
*/
|
|
99
|
+
private pendingSaveResolver;
|
|
100
|
+
private readonly changeDetector;
|
|
101
|
+
private readonly reactBridge;
|
|
102
|
+
ngOnInit(): Promise<void>;
|
|
103
|
+
/**
|
|
104
|
+
* Called by the React component via `mj-react-component`'s `componentEvent`
|
|
105
|
+
* @Output. Maps the form-role event names to BaseEntity operations.
|
|
106
|
+
*/
|
|
107
|
+
OnReactComponentEvent(event: ReactComponentEvent): Promise<void>;
|
|
108
|
+
/**
|
|
109
|
+
* Apply the React component's dirty-field diff to the BaseEntity, save,
|
|
110
|
+
* and refresh the snapshot. Errors surface via `LatestResult.CompleteMessage`
|
|
111
|
+
* per the BaseEntity Save contract.
|
|
112
|
+
*
|
|
113
|
+
* Resolves `pendingSaveResolver` if {@link SaveRecord} initiated this
|
|
114
|
+
* flow via the toolbar — so the toolbar can return a meaningful boolean
|
|
115
|
+
* and honor `StopEditModeAfterSave`.
|
|
116
|
+
*/
|
|
117
|
+
private handleBeforeSave;
|
|
118
|
+
private resolvePendingSave;
|
|
119
|
+
private handleBeforeDelete;
|
|
120
|
+
private handleEditModeChangeRequested;
|
|
121
|
+
/**
|
|
122
|
+
* Propagate Angular-toolbar-driven mode changes into the React component's
|
|
123
|
+
* `FormHostProps.mode`. Without these overrides, clicking Edit on the
|
|
124
|
+
* `<mj-record-form-container>` toolbar flips `this.EditMode` but the React
|
|
125
|
+
* side still sees `mode: 'view'`.
|
|
126
|
+
*/
|
|
127
|
+
StartEditMode(): void;
|
|
128
|
+
EndEditMode(): void;
|
|
129
|
+
/**
|
|
130
|
+
* Toolbar **Save** override. Routes the click through the React
|
|
131
|
+
* component's registered `RequestSave` method so the React layer can
|
|
132
|
+
* (a) run its own validation, (b) flush its draft state, (c) emit
|
|
133
|
+
* `BeforeSave` with the dirty-field diff — exactly the flow the
|
|
134
|
+
* in-form Save button would trigger. The wrapper then awaits the
|
|
135
|
+
* BeforeSave handler via `pendingSaveResolver`, gets a real
|
|
136
|
+
* success/failure boolean, and honors `StopEditModeAfterSave`.
|
|
137
|
+
*
|
|
138
|
+
* Falls back to the base implementation for components that haven't
|
|
139
|
+
* registered `RequestSave` — preserves correctness for forms that
|
|
140
|
+
* keep their own in-form Save button (older sample, hand-authored
|
|
141
|
+
* forms that pre-date this contract).
|
|
142
|
+
*/
|
|
143
|
+
SaveRecord(StopEditModeAfterSave: boolean): Promise<boolean>;
|
|
144
|
+
/**
|
|
145
|
+
* Toolbar **Cancel** override. Asks the React component to discard
|
|
146
|
+
* its draft via `RequestCancel`, then flips out of edit mode the
|
|
147
|
+
* same way the base implementation would. The React component is
|
|
148
|
+
* expected to (a) clear its local draft state and (b) emit
|
|
149
|
+
* `EditModeChangeRequested({ requestedMode: 'view' })` — though we
|
|
150
|
+
* call `EndEditMode` here directly anyway, so even a no-op handler
|
|
151
|
+
* leaves the form in a coherent state.
|
|
152
|
+
*/
|
|
153
|
+
CancelEdit(): void;
|
|
154
|
+
/**
|
|
155
|
+
* Resolve the Component row, parse its `Specification`, and surface either
|
|
156
|
+
* the spec or an error. Backed by `InteractiveFormsEngine` (in-memory
|
|
157
|
+
* cache, BaseEntity event-driven invalidation) so this is a sub-ms JS
|
|
158
|
+
* lookup once the engine has loaded — the engine handles freshness
|
|
159
|
+
* via remote-invalidate events, replacing the prior RunView's
|
|
160
|
+
* `BypassCache: true` escape hatch. Falls through to a one-shot
|
|
161
|
+
* RunView only on engine-cache miss (defensive — the engine should
|
|
162
|
+
* always have a Type='Form' Component, but if a brand-new Component
|
|
163
|
+
* was just created on the server and the invalidation event hasn't
|
|
164
|
+
* propagated yet, we still want to render rather than blank-screen).
|
|
165
|
+
*/
|
|
166
|
+
private loadComponentSpec;
|
|
167
|
+
/**
|
|
168
|
+
* Build `FormHostProps` from the current record + permissions + edit mode.
|
|
169
|
+
* Called whenever the record loads, mode changes, or save completes.
|
|
170
|
+
*/
|
|
171
|
+
private rebuildFormHostProps;
|
|
172
|
+
private primaryKeyToPlain;
|
|
173
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<InteractiveFormComponent, never>;
|
|
174
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<InteractiveFormComponent, "mj-interactive-form", never, { "record": { "alias": "record"; "required": false; }; "ComponentID": { "alias": "ComponentID"; "required": false; }; "componentSpec": { "alias": "componentSpec"; "required": false; }; "previewMode": { "alias": "previewMode"; "required": false; }; }, { "LoadErrorChanged": "LoadErrorChanged"; }, never, never, false, never>;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Tree-shaking guard. Imported and called from public-api.ts so bundlers don't
|
|
178
|
+
* drop the component when no consumer references it by name.
|
|
179
|
+
*/
|
|
180
|
+
export declare function LoadInteractiveFormComponent(): void;
|
|
181
|
+
//# sourceMappingURL=interactive-form.component.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interactive-form.component.d.ts","sourceRoot":"","sources":["../../../src/lib/interactive-form/interactive-form.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgC,YAAY,EAAS,SAAS,EAAE,MAAM,EAA6B,MAAM,eAAe,CAAC;AAChI,OAAO,EAAE,UAAU,EAAmC,MAAM,sBAAsB,CAAC;AAEnF,OAAO,EAAE,aAAa,EAAE,MAAM,6CAA6C,CAAC;AAC5E,OAAO,EACH,aAAa,EAOhB,MAAM,mDAAmD,CAAC;AAE3D,OAAO,EAAE,gBAAgB,EAAsB,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AACrG,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;;AAE3D;;;;;;;;;;;;;;GAcG;AACH,qBAKa,wBAAyB,SAAQ,iBAAkB,YAAW,MAAM,EAAE,SAAS;IAExF;;;;;;;;;OASG;IACH,OAAO,CAAC,OAAO,CAAc;IAC7B,OAAO,CAAC,kBAAkB,CAAS;IAEnC,IACoB,MAAM,CAAC,KAAK,EAAE,UAAU,EAQ3C;IACD,IAAoB,MAAM,IAAI,UAAU,CAAyB;IAEjE;;;;OAIG;IACa,WAAW,EAAE,MAAM,GAAG,IAAI,CAAQ;IAElD;;;;;;;;;;OAUG;IACa,aAAa,EAAE,aAAa,GAAG,IAAI,CAAQ;IAE3D;;;;;;;;;;;OAWG;IACa,WAAW,UAAS;IAEpC,2FAA2F;IACpF,aAAa,EAAE,aAAa,GAAG,IAAI,CAAQ;IAElD,2EAA2E;IAC3E,OAAO,CAAC,UAAU,CAAuB;IAEzC;;;;;OAKG;IACH,IAAW,SAAS,IAAI,MAAM,GAAG,IAAI,CAA4B;IACjE,IAAW,SAAS,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,EAIpC;IAEgB,gBAAgB,8BAAqC;IAEtE,mFAAmF;IACnF,OAAO,CAAC,gBAAgB,CAA+B;IAEvD;;;;;;;OAOG;IACiC,cAAc,CAAC,EAAE,gBAAgB,CAAC;IAEtE;;;;;OAKG;IACH,OAAO,CAAC,mBAAmB,CAA6C;IAExE,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA6B;IAC5D,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA8B;IAEpC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IA+B/C;;;OAGG;IACU,qBAAqB,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAgB7E;;;;;;;;OAQG;YACW,gBAAgB;IAgD9B,OAAO,CAAC,kBAAkB;YAOZ,kBAAkB;IAahC,OAAO,CAAC,6BAA6B;IAWrC;;;;;OAKG;IACa,aAAa,IAAI,IAAI;IAKrB,WAAW,IAAI,IAAI;IAKnC;;;;;;;;;;;;;OAaG;IACmB,UAAU,CAAC,qBAAqB,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAqBlF;;;;;;;;OAQG;IACa,UAAU,IAAI,IAAI;IAiBlC;;;;;;;;;;;OAWG;YACW,iBAAiB;IAoE/B;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IA6B5B,OAAO,CAAC,iBAAiB;yCAnbhB,wBAAwB;2CAAxB,wBAAwB;CA0bpC;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,IAAI,IAAI,CAMnD"}
|