@dotglitch/ngx-common 1.0.2

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.
Files changed (60) hide show
  1. package/README.md +24 -0
  2. package/components/dynamic-html/dynamic-html.component.d.ts +15 -0
  3. package/components/dynamic-html/dynamic-html.module.d.ts +10 -0
  4. package/components/dynamic-html/dynamic-html.service.d.ts +18 -0
  5. package/components/dynamic-html/types.d.ts +12 -0
  6. package/components/lazy-loader/lazy-loader.component.d.ts +146 -0
  7. package/components/lazy-loader/lazy-loader.module.d.ts +10 -0
  8. package/components/lazy-loader/lazy-loader.service.d.ts +71 -0
  9. package/components/lazy-loader/types.d.ts +142 -0
  10. package/components/menu/menu.component.d.ts +52 -0
  11. package/components/tooltip/tooltip.component.d.ts +35 -0
  12. package/directives/menu.directive.d.ts +27 -0
  13. package/directives/tooltip.directive.d.ts +26 -0
  14. package/directives/utils.d.ts +8 -0
  15. package/esm2020/components/dynamic-html/dynamic-html.component.mjs +43 -0
  16. package/esm2020/components/dynamic-html/dynamic-html.module.mjs +27 -0
  17. package/esm2020/components/dynamic-html/dynamic-html.service.mjs +66 -0
  18. package/esm2020/components/dynamic-html/types.mjs +7 -0
  19. package/esm2020/components/lazy-loader/lazy-loader.component.mjs +360 -0
  20. package/esm2020/components/lazy-loader/lazy-loader.module.mjs +29 -0
  21. package/esm2020/components/lazy-loader/lazy-loader.service.mjs +215 -0
  22. package/esm2020/components/lazy-loader/types.mjs +26 -0
  23. package/esm2020/components/menu/menu.component.mjs +316 -0
  24. package/esm2020/components/tooltip/tooltip.component.mjs +135 -0
  25. package/esm2020/directives/menu.directive.mjs +112 -0
  26. package/esm2020/directives/tooltip.directive.mjs +92 -0
  27. package/esm2020/directives/utils.mjs +120 -0
  28. package/esm2020/dotglitch-ngx-common.mjs +5 -0
  29. package/esm2020/pipes/html-bypass.pipe.mjs +27 -0
  30. package/esm2020/pipes/resource-bypass.pipe.mjs +27 -0
  31. package/esm2020/pipes/script-bypass.pipe.mjs +27 -0
  32. package/esm2020/pipes/style-bypass.pipe.mjs +27 -0
  33. package/esm2020/pipes/url-bypass.pipe.mjs +27 -0
  34. package/esm2020/public-api.mjs +39 -0
  35. package/esm2020/services/dependency.service.mjs +55 -0
  36. package/esm2020/services/dialog.service.mjs +66 -0
  37. package/esm2020/services/fetch.service.mjs +71 -0
  38. package/esm2020/services/keyboard.service.mjs +128 -0
  39. package/esm2020/types/menu.mjs +2 -0
  40. package/esm2020/types/popup.mjs +2 -0
  41. package/esm2020/utils/index.mjs +39 -0
  42. package/fesm2015/dotglitch-ngx-common.mjs +1997 -0
  43. package/fesm2015/dotglitch-ngx-common.mjs.map +1 -0
  44. package/fesm2020/dotglitch-ngx-common.mjs +1977 -0
  45. package/fesm2020/dotglitch-ngx-common.mjs.map +1 -0
  46. package/index.d.ts +5 -0
  47. package/package.json +60 -0
  48. package/pipes/html-bypass.pipe.d.ts +16 -0
  49. package/pipes/resource-bypass.pipe.d.ts +16 -0
  50. package/pipes/script-bypass.pipe.d.ts +16 -0
  51. package/pipes/style-bypass.pipe.d.ts +16 -0
  52. package/pipes/url-bypass.pipe.d.ts +16 -0
  53. package/public-api.d.ts +34 -0
  54. package/services/dependency.service.d.ts +19 -0
  55. package/services/dialog.service.d.ts +41 -0
  56. package/services/fetch.service.d.ts +28 -0
  57. package/services/keyboard.service.d.ts +79 -0
  58. package/types/menu.d.ts +90 -0
  59. package/types/popup.d.ts +27 -0
  60. package/utils/index.d.ts +19 -0
@@ -0,0 +1,1997 @@
1
+ import { __awaiter } from 'tslib';
2
+ import * as i0 from '@angular/core';
3
+ import { TemplateRef, Component, Optional, Inject, Input, HostListener, Directive, EventEmitter, Output, Pipe, Injectable, isDevMode, InjectionToken, ViewContainerRef, ViewChild, NgModule } from '@angular/core';
4
+ import * as i1 from '@angular/material/dialog';
5
+ import { MAT_DIALOG_DATA, MatDialog } from '@angular/material/dialog';
6
+ import * as i2 from '@angular/common';
7
+ import { CommonModule, NgTemplateOutlet, NgIf, NgForOf, DOCUMENT, NgComponentOutlet } from '@angular/common';
8
+ import * as i1$1 from '@angular/platform-browser';
9
+ import { createApplication } from '@angular/platform-browser';
10
+ import { firstValueFrom, of, Subject, debounceTime } from 'rxjs';
11
+ import * as i4 from '@angular/material/icon';
12
+ import { MatIconModule } from '@angular/material/icon';
13
+ import * as i5 from '@angular/material/progress-spinner';
14
+ import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
15
+ import * as i2$1 from '@angular/cdk/portal';
16
+ import { ComponentPortal, PortalModule } from '@angular/cdk/portal';
17
+ import { retry } from 'rxjs/operators';
18
+ import * as i1$2 from '@angular/common/http';
19
+ import * as i2$2 from '@angular/cdk/dialog';
20
+
21
+ /**
22
+ * This utils file exists outside of the strict angular DI zone
23
+ * This enables opening popups without requiring absolute DI bindings.
24
+ */
25
+ const getPosition = (el, config = {}, bounds) => {
26
+ // Bounds of the popup owner
27
+ const src = !!el['nodeName']
28
+ ? el.getBoundingClientRect()
29
+ : {
30
+ // It's a pointer event, so we'll take the X and Y from the pointer.
31
+ x: el['clientX'],
32
+ y: el['clientY'],
33
+ // Set a default tiny size, so we don't divide by zero.
34
+ width: 0.0001,
35
+ height: 0.0001
36
+ };
37
+ // Popup bounds
38
+ const { width, height } = bounds;
39
+ const winh = window.innerHeight;
40
+ const winw = window.innerWidth;
41
+ const cords = {
42
+ top: null,
43
+ left: null
44
+ };
45
+ if ((config === null || config === void 0 ? void 0 : config.position) == "left" || (config === null || config === void 0 ? void 0 : config.position) == "right" || !(config === null || config === void 0 ? void 0 : config.position)) {
46
+ switch (config === null || config === void 0 ? void 0 : config.alignment) {
47
+ case "end": {
48
+ // vertically bind to bottom
49
+ cords.top = src.y + src.height - height;
50
+ break;
51
+ }
52
+ case "afterend": {
53
+ // vertically bind below bottom
54
+ cords.top = src.y + src.height;
55
+ break;
56
+ }
57
+ case "beforestart": {
58
+ // vertically bind above top
59
+ cords.top = src.y - height;
60
+ break;
61
+ }
62
+ case "start": {
63
+ // vertically bind to top
64
+ cords.top = src.y;
65
+ break;
66
+ }
67
+ case "center":
68
+ default: {
69
+ // vertically center
70
+ cords.top = (src.y + (src.height / 2)) - (height / 2);
71
+ break;
72
+ }
73
+ }
74
+ // Apply bounds to prevent the dialog from being cut-off screen
75
+ // Lower bound
76
+ cords.top = Math.max((config === null || config === void 0 ? void 0 : config.edgePadding) || 0, cords.top);
77
+ // Upper bound
78
+ cords.top = Math.min(winh - height, cords.top);
79
+ if ((config === null || config === void 0 ? void 0 : config.position) == "left") {
80
+ cords.left = src.x - (width + ((config === null || config === void 0 ? void 0 : config.arrowSize) || 0) + ((config === null || config === void 0 ? void 0 : config.arrowPadding) || 0));
81
+ }
82
+ if ((config === null || config === void 0 ? void 0 : config.position) == "right" || !(config === null || config === void 0 ? void 0 : config.position)) {
83
+ cords.left = src.x + (src.width + ((config === null || config === void 0 ? void 0 : config.arrowSize) || 0) + ((config === null || config === void 0 ? void 0 : config.arrowPadding) || 0));
84
+ }
85
+ // Lower bound
86
+ cords.left = Math.max((config === null || config === void 0 ? void 0 : config.edgePadding) || 0, cords.left);
87
+ // Upper bound
88
+ cords.left = Math.min(winw - width, cords.left);
89
+ }
90
+ else if ((config === null || config === void 0 ? void 0 : config.position) == "top" || (config === null || config === void 0 ? void 0 : config.position) == "bottom") {
91
+ switch (config === null || config === void 0 ? void 0 : config.alignment) {
92
+ case "end": {
93
+ // vertically bind to right
94
+ cords.left = src.x + src.width - width;
95
+ break;
96
+ }
97
+ case "afterend": {
98
+ // vertically bind past right
99
+ cords.left = src.x + src.width;
100
+ break;
101
+ }
102
+ case "beforestart": {
103
+ // vertically bind before left
104
+ cords.left = src.x - width;
105
+ break;
106
+ }
107
+ case "start": {
108
+ // vertically bind to left
109
+ cords.left = src.x;
110
+ break;
111
+ }
112
+ case "center":
113
+ default: {
114
+ // vertically center
115
+ cords.left = (src.x + (src.width / 2)) - (width / 2);
116
+ break;
117
+ }
118
+ }
119
+ // Apply bounds to prevent the dialog from being cut-off screen
120
+ // Lower bound
121
+ cords.left = Math.max((config === null || config === void 0 ? void 0 : config.edgePadding) || 0, cords.left);
122
+ // Upper bound
123
+ cords.left = Math.min(winw - width, cords.left);
124
+ if ((config === null || config === void 0 ? void 0 : config.position) == "top") {
125
+ cords.top = src.y - (height + ((config === null || config === void 0 ? void 0 : config.arrowSize) || 0) + ((config === null || config === void 0 ? void 0 : config.arrowPadding) || 0));
126
+ }
127
+ if ((config === null || config === void 0 ? void 0 : config.position) == "bottom") {
128
+ cords.top = src.y + (src.height + ((config === null || config === void 0 ? void 0 : config.arrowSize) || 0) + ((config === null || config === void 0 ? void 0 : config.arrowPadding) || 0));
129
+ }
130
+ // Lower bound
131
+ cords.top = Math.max((config === null || config === void 0 ? void 0 : config.edgePadding) || 0, cords.top);
132
+ // Upper bound
133
+ cords.top = Math.min(winh - height, cords.top);
134
+ }
135
+ // Assign unit
136
+ cords.top = cords.top + 'px';
137
+ cords.left = cords.left + 'px';
138
+ return cords;
139
+ };
140
+
141
+ const calcTooltipBounds = (template, data) => __awaiter(void 0, void 0, void 0, function* () {
142
+ var _a, _b;
143
+ const args = {
144
+ data: data || {},
145
+ template,
146
+ config: {},
147
+ selfCords: { left: "0px", top: "0px" },
148
+ ownerCords: { x: 0, y: 0, width: 0, height: 0 },
149
+ id: null
150
+ };
151
+ // Forcibly bootstrap the ctx menu outside of the client application's zone.
152
+ const app = yield createApplication({
153
+ providers: [
154
+ { provide: MAT_DIALOG_DATA, useValue: args }
155
+ ]
156
+ });
157
+ const del = document.createElement("div");
158
+ del.style.position = "absolute";
159
+ del.style.left = '-1000vw';
160
+ document.body.append(del);
161
+ const base = app.bootstrap(TooltipComponent, del);
162
+ const { instance } = base;
163
+ yield firstValueFrom(app.isStable);
164
+ const el = (_b = (_a = instance.viewContainer) === null || _a === void 0 ? void 0 : _a.element) === null || _b === void 0 ? void 0 : _b.nativeElement;
165
+ const rect = el.getBoundingClientRect();
166
+ app.destroy();
167
+ del.remove();
168
+ return rect;
169
+ });
170
+ class TooltipComponent {
171
+ constructor(viewContainer, _data, dialog, // optional only for the purpose of estimating dimensions
172
+ dialogRef) {
173
+ var _a, _b, _c, _d, _e;
174
+ this.viewContainer = viewContainer;
175
+ this._data = _data;
176
+ this.dialog = dialog;
177
+ this.dialogRef = dialogRef;
178
+ this.hasBootstrapped = false;
179
+ this.pointerIsOnVoid = false;
180
+ this.coverRectCords = {
181
+ top: 0,
182
+ left: 0,
183
+ height: 0,
184
+ width: 0
185
+ };
186
+ // Defaults are set before @Input() hooks evaluate
187
+ this.data = this.data || ((_a = this._data) === null || _a === void 0 ? void 0 : _a.data) || {};
188
+ this.config = this.config || ((_b = this._data) === null || _b === void 0 ? void 0 : _b.config);
189
+ this.template = this.template || ((_c = this._data) === null || _c === void 0 ? void 0 : _c.template);
190
+ this.ownerCords = this.ownerCords || ((_d = this._data) === null || _d === void 0 ? void 0 : _d.ownerCords);
191
+ this.selfCords = this.selfCords || ((_e = this._data) === null || _e === void 0 ? void 0 : _e.selfCords);
192
+ }
193
+ ngOnInit() {
194
+ const selfY = parseInt(this.selfCords.top.replace('px', ''));
195
+ const selfX = parseInt(this.selfCords.left.replace('px', ''));
196
+ this.coverRectCords = {
197
+ top: this.ownerCords.y - selfY - 16,
198
+ left: this.ownerCords.x - selfX - 16,
199
+ height: this.ownerCords.height + 32,
200
+ width: this.ownerCords.width + 32
201
+ };
202
+ if (this.template instanceof TemplateRef)
203
+ this.isTemplate = true;
204
+ else if (typeof this.template == "function")
205
+ this.isTemplate = false;
206
+ else
207
+ throw new Error("Unrecognized template object provided.");
208
+ // TODO: resolve the event hook with the .void element
209
+ setTimeout(() => {
210
+ this.hasBootstrapped = true;
211
+ if (this.pointerIsOnVoid)
212
+ this.dialogRef.close();
213
+ }, 10);
214
+ }
215
+ /**
216
+ * Close the tooltip if these actions occur
217
+ */
218
+ onClose() {
219
+ var _a;
220
+ (_a = this.dialogRef) === null || _a === void 0 ? void 0 : _a.close();
221
+ }
222
+ onPointerLeave() {
223
+ var _a;
224
+ (_a = this.dialogRef) === null || _a === void 0 ? void 0 : _a.close();
225
+ }
226
+ }
227
+ TooltipComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: TooltipComponent, deps: [{ token: i0.ViewContainerRef }, { token: MAT_DIALOG_DATA, optional: true }, { token: i1.MatDialog, optional: true }, { token: i1.MatDialogRef, optional: true }], target: i0.ɵɵFactoryTarget.Component });
228
+ TooltipComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.9", type: TooltipComponent, isStandalone: true, selector: "ngx-tooltip", inputs: { data: "data", config: "config", ownerCords: "ownerCords", selfCords: "selfCords", template: "template" }, host: { listeners: { "window:resize": "onClose()", "window:blur": "onClose()", "pointerleave": "onPointerLeave()" } }, ngImport: i0, template: "<!-- Mouse event blocker for pointer leave -->\n<div\n *ngIf=\"coverRectCords\"\n class=\"owner-mask\"\n [style.top]=\"coverRectCords.top + 'px'\"\n [style.left]=\"coverRectCords.left + 'px'\"\n [style.height]=\"coverRectCords.height + 'px'\"\n [style.width]=\"coverRectCords.width + 'px'\"\n style=\"z-index: -1;\"\n></div>\n\n<div class=\"void\"\n (pointerenter)=\"pointerIsOnVoid = true; hasBootstrapped && dialogRef.close()\"\n (pointerleave)=\"pointerIsOnVoid = false\"\n (pointerdown)=\"hasBootstrapped && dialogRef.close()\"\n></div>\n\n<div class=\"container\">\n <ng-container\n *ngIf=\"isTemplate == false\"\n [ngComponentOutlet]=\"$any(template)\"\n >\n </ng-container>\n\n <ng-container\n *ngIf=\"isTemplate == true\"\n >\n <ng-container\n [ngTemplateOutlet]=\"$any(template)\"\n [ngTemplateOutletContext]=\"{ '$implicit': data }\"\n ></ng-container>\n </ng-container>\n</div>\n", styles: ["::ng-deep .cdk-overlay-container .ngx-tooltip{--mdc-dialog-container-color: var(--ngx-tooltip-background-color, #2f2f2f)}::ng-deep .cdk-overlay-container .ngx-tooltip .mdc-dialog__container{transform-origin:top left}::ng-deep .cdk-overlay-container .ngx-tooltip .mdc-dialog--open .mdc-dialog__container{transform:none}::ng-deep .cdk-overlay-container .ngx-tooltip .mdc-dialog__surface{overflow:visible;background-color:#0000}::ng-deep .cdk-overlay-container .context-menu-backdrop.cdk-overlay-backdrop-showing{opacity:0}::ng-deep .cdk-overlay-pane.ngx-tooltip .mat-dialog-container{padding:0}:host{min-width:2px;min-height:2px;display:block}.void,.owner-mask{position:absolute}.void{top:-100vh;right:-100vw;bottom:-100vh;left:-100vw;z-index:-2}.container{width:100%;height:100%;background:var(--ngx-tooltip-background-color, #333);border-radius:6px;overflow:hidden}\n"], dependencies: [{ kind: "ngmodule", type:
229
+ // NgIf,
230
+ // NgTemplateOutlet,
231
+ // NgComponentOutlet,
232
+ CommonModule }, { kind: "directive", type: i2.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
233
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: TooltipComponent, decorators: [{
234
+ type: Component,
235
+ args: [{ selector: 'ngx-tooltip', imports: [
236
+ // NgIf,
237
+ // NgTemplateOutlet,
238
+ // NgComponentOutlet,
239
+ CommonModule,
240
+ ], standalone: true, template: "<!-- Mouse event blocker for pointer leave -->\n<div\n *ngIf=\"coverRectCords\"\n class=\"owner-mask\"\n [style.top]=\"coverRectCords.top + 'px'\"\n [style.left]=\"coverRectCords.left + 'px'\"\n [style.height]=\"coverRectCords.height + 'px'\"\n [style.width]=\"coverRectCords.width + 'px'\"\n style=\"z-index: -1;\"\n></div>\n\n<div class=\"void\"\n (pointerenter)=\"pointerIsOnVoid = true; hasBootstrapped && dialogRef.close()\"\n (pointerleave)=\"pointerIsOnVoid = false\"\n (pointerdown)=\"hasBootstrapped && dialogRef.close()\"\n></div>\n\n<div class=\"container\">\n <ng-container\n *ngIf=\"isTemplate == false\"\n [ngComponentOutlet]=\"$any(template)\"\n >\n </ng-container>\n\n <ng-container\n *ngIf=\"isTemplate == true\"\n >\n <ng-container\n [ngTemplateOutlet]=\"$any(template)\"\n [ngTemplateOutletContext]=\"{ '$implicit': data }\"\n ></ng-container>\n </ng-container>\n</div>\n", styles: ["::ng-deep .cdk-overlay-container .ngx-tooltip{--mdc-dialog-container-color: var(--ngx-tooltip-background-color, #2f2f2f)}::ng-deep .cdk-overlay-container .ngx-tooltip .mdc-dialog__container{transform-origin:top left}::ng-deep .cdk-overlay-container .ngx-tooltip .mdc-dialog--open .mdc-dialog__container{transform:none}::ng-deep .cdk-overlay-container .ngx-tooltip .mdc-dialog__surface{overflow:visible;background-color:#0000}::ng-deep .cdk-overlay-container .context-menu-backdrop.cdk-overlay-backdrop-showing{opacity:0}::ng-deep .cdk-overlay-pane.ngx-tooltip .mat-dialog-container{padding:0}:host{min-width:2px;min-height:2px;display:block}.void,.owner-mask{position:absolute}.void{top:-100vh;right:-100vw;bottom:-100vh;left:-100vw;z-index:-2}.container{width:100%;height:100%;background:var(--ngx-tooltip-background-color, #333);border-radius:6px;overflow:hidden}\n"] }]
241
+ }], ctorParameters: function () {
242
+ return [{ type: i0.ViewContainerRef }, { type: undefined, decorators: [{
243
+ type: Optional
244
+ }, {
245
+ type: Inject,
246
+ args: [MAT_DIALOG_DATA]
247
+ }] }, { type: i1.MatDialog, decorators: [{
248
+ type: Optional
249
+ }] }, { type: i1.MatDialogRef, decorators: [{
250
+ type: Optional
251
+ }] }];
252
+ }, propDecorators: { data: [{
253
+ type: Input
254
+ }], config: [{
255
+ type: Input
256
+ }], ownerCords: [{
257
+ type: Input
258
+ }], selfCords: [{
259
+ type: Input
260
+ }], template: [{
261
+ type: Input
262
+ }], onClose: [{
263
+ type: HostListener,
264
+ args: ["window:resize"]
265
+ }, {
266
+ type: HostListener,
267
+ args: ["window:blur"]
268
+ }], onPointerLeave: [{
269
+ type: HostListener,
270
+ args: ["pointerleave"]
271
+ }] } });
272
+
273
+ class TooltipDirective {
274
+ constructor(dialog, viewContainer) {
275
+ this.dialog = dialog;
276
+ this.viewContainer = viewContainer;
277
+ /**
278
+ * Configuration for opening the app menu
279
+ */
280
+ this.config = {};
281
+ /**
282
+ * Arbitrary data to pass into the template
283
+ */
284
+ this.data = {};
285
+ }
286
+ ngOnInit() {
287
+ }
288
+ // Needs to be public so we can manually open the dialog
289
+ onPointerEnter(evt) {
290
+ return __awaiter(this, void 0, void 0, function* () {
291
+ // If the template is not a template ref, do nothing.
292
+ if (!(this.template instanceof TemplateRef))
293
+ return;
294
+ const el = this.viewContainer.element.nativeElement;
295
+ this.dialogInstance = yield openTooltip(this.dialog, this.template, this.data, el, this.config);
296
+ });
297
+ }
298
+ }
299
+ TooltipDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: TooltipDirective, deps: [{ token: i1.MatDialog }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Directive });
300
+ TooltipDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.9", type: TooltipDirective, isStandalone: true, selector: "[ngxTooltip],[ngx-tooltip]", inputs: { template: ["ngx-tooltip", "template"], config: ["ngx-tooltip-config", "config"], data: ["ngx-tooltip-context", "data"] }, host: { listeners: { "pointerenter": "onPointerEnter($event)" } }, providers: [
301
+ MatDialog
302
+ ], ngImport: i0 });
303
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: TooltipDirective, decorators: [{
304
+ type: Directive,
305
+ args: [{
306
+ selector: '[ngxTooltip],[ngx-tooltip]',
307
+ providers: [
308
+ MatDialog
309
+ ],
310
+ standalone: true
311
+ }]
312
+ }], ctorParameters: function () { return [{ type: i1.MatDialog }, { type: i0.ViewContainerRef }]; }, propDecorators: { template: [{
313
+ type: Input,
314
+ args: ["ngxTooltip"]
315
+ }, {
316
+ type: Input,
317
+ args: ["ngx-tooltip"]
318
+ }], config: [{
319
+ type: Input,
320
+ args: ["ngxTooltipConfig"]
321
+ }, {
322
+ type: Input,
323
+ args: ["ngx-tooltip-config"]
324
+ }], data: [{
325
+ type: Input,
326
+ args: ["ngxTooltipContext"]
327
+ }, {
328
+ type: Input,
329
+ args: ["ngx-tooltip-context"]
330
+ }], onPointerEnter: [{
331
+ type: HostListener,
332
+ args: ['pointerenter', ['$event']]
333
+ }] } });
334
+ // Helper to open the context menu without using the directive.
335
+ const openTooltip = (dialog, template, data, el, config) => __awaiter(void 0, void 0, void 0, function* () {
336
+ const rect = yield calcTooltipBounds(template, data);
337
+ const ownerCords = el.getBoundingClientRect();
338
+ const cords = getPosition(el, config, rect);
339
+ const specificId = crypto.randomUUID();
340
+ return new Promise(res => {
341
+ dialog.open(TooltipComponent, {
342
+ data: {
343
+ data: data,
344
+ template: template,
345
+ config: config,
346
+ ownerCords: ownerCords,
347
+ selfCords: cords,
348
+ id: specificId
349
+ },
350
+ panelClass: ["ngx-tooltip", 'ngx-' + specificId].concat((config === null || config === void 0 ? void 0 : config.customClass) || []),
351
+ position: cords,
352
+ hasBackdrop: false
353
+ })
354
+ .afterClosed()
355
+ .subscribe(s => {
356
+ res(s);
357
+ });
358
+ });
359
+ });
360
+
361
+ const calcMenuItemBounds = (menuItems, dataObj) => __awaiter(void 0, void 0, void 0, function* () {
362
+ const data = {
363
+ data: dataObj,
364
+ items: menuItems,
365
+ config: {},
366
+ id: null
367
+ };
368
+ return calcComponentBounds(MenuComponent, data);
369
+ });
370
+ const calcComponentBounds = (component, data) => __awaiter(void 0, void 0, void 0, function* () {
371
+ var _a, _b;
372
+ // Forcibly bootstrap the ctx menu outside of the client application's zone.
373
+ const app = yield createApplication({
374
+ providers: [
375
+ { provide: MAT_DIALOG_DATA, useValue: data }
376
+ ]
377
+ });
378
+ const del = document.createElement("div");
379
+ del.style.position = "absolute";
380
+ del.style.left = '-1000vw';
381
+ document.body.append(del);
382
+ const base = app.bootstrap(component, del);
383
+ const { instance } = base;
384
+ yield firstValueFrom(app.isStable);
385
+ const el = (_b = (_a = instance.viewContainer) === null || _a === void 0 ? void 0 : _a.element) === null || _b === void 0 ? void 0 : _b.nativeElement;
386
+ const rect = el.getBoundingClientRect();
387
+ app.destroy();
388
+ del.remove();
389
+ return rect;
390
+ });
391
+ class TemplateWrapper {
392
+ constructor(dialogRef, _data, viewContainer) {
393
+ this.dialogRef = dialogRef;
394
+ this._data = _data;
395
+ this.viewContainer = viewContainer;
396
+ this.data = _data.data;
397
+ this.template = _data.template;
398
+ // TODO: This is probably invalid
399
+ this.templateType = this.template instanceof TemplateRef ? "template" : "component";
400
+ if (this.templateType == "component") {
401
+ this.componentPortal = new ComponentPortal(this.template);
402
+ }
403
+ }
404
+ }
405
+ TemplateWrapper.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: TemplateWrapper, deps: [{ token: i1.MatDialogRef, optional: true }, { token: MAT_DIALOG_DATA }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Component });
406
+ TemplateWrapper.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.9", type: TemplateWrapper, isStandalone: true, selector: "ngx-menu-template-wrapper", ngImport: i0, template: `
407
+ <ng-container *ngIf="templateType == 'template'; else portalOutlet">
408
+ <ng-container
409
+ [ngTemplateOutlet]="template"
410
+ [ngTemplateOutletContext]="{ '$implicit': data, dialog: dialogRef }"
411
+ />
412
+ </ng-container>
413
+ <ng-template #portalOutlet [cdkPortalOutlet]="componentPortal" ></ng-template>
414
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: PortalModule }, { kind: "directive", type: i2$1.CdkPortalOutlet, selector: "[cdkPortalOutlet]", inputs: ["cdkPortalOutlet"], outputs: ["attached"], exportAs: ["cdkPortalOutlet"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
415
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: TemplateWrapper, decorators: [{
416
+ type: Component,
417
+ args: [{
418
+ selector: 'ngx-menu-template-wrapper',
419
+ template: `
420
+ <ng-container *ngIf="templateType == 'template'; else portalOutlet">
421
+ <ng-container
422
+ [ngTemplateOutlet]="template"
423
+ [ngTemplateOutletContext]="{ '$implicit': data, dialog: dialogRef }"
424
+ />
425
+ </ng-container>
426
+ <ng-template #portalOutlet [cdkPortalOutlet]="componentPortal" ></ng-template>
427
+ `,
428
+ imports: [NgTemplateOutlet, PortalModule, NgIf],
429
+ standalone: true
430
+ }]
431
+ }], ctorParameters: function () {
432
+ return [{ type: i1.MatDialogRef, decorators: [{
433
+ type: Optional
434
+ }] }, { type: undefined, decorators: [{
435
+ type: Inject,
436
+ args: [MAT_DIALOG_DATA]
437
+ }] }, { type: i0.ViewContainerRef }];
438
+ } });
439
+ class MenuComponent {
440
+ constructor(viewContainer, sanitizer, _data, dialog, // optional only for the purpose of estimating dimensions
441
+ dialogRef, changeDetector) {
442
+ var _a, _b, _c, _d, _e;
443
+ this.viewContainer = viewContainer;
444
+ this.sanitizer = sanitizer;
445
+ this._data = _data;
446
+ this.dialog = dialog;
447
+ this.dialogRef = dialogRef;
448
+ this.changeDetector = changeDetector;
449
+ this.closeSignal = new EventEmitter();
450
+ // Check if there are any slashes or dots -- that will clearly exclude it from being a mat icon
451
+ this.matIconRx = /[\/\.]/i;
452
+ this.showIconColumn = true;
453
+ this.showShortcutColumn = true;
454
+ // Defaults are set before @Input() hooks evaluate
455
+ this.data = (_a = this._data) === null || _a === void 0 ? void 0 : _a.data;
456
+ this.parentCords = (_b = this._data) === null || _b === void 0 ? void 0 : _b.parentCords;
457
+ this.items = (_c = this._data) === null || _c === void 0 ? void 0 : _c.items;
458
+ this.config = (_d = this._data) === null || _d === void 0 ? void 0 : _d.config;
459
+ this.id = (_e = this._data) === null || _e === void 0 ? void 0 : _e.id;
460
+ }
461
+ ngOnInit() {
462
+ var _a;
463
+ (_a = this.items) === null || _a === void 0 ? void 0 : _a.forEach(i => {
464
+ if (typeof i == "string")
465
+ return;
466
+ // Set defaults
467
+ i['_disabled'] = false;
468
+ i['_visible'] = true;
469
+ if (i.label)
470
+ try {
471
+ i['_formattedLabel'] = this.formatLabel(i.label);
472
+ }
473
+ catch (e) {
474
+ console.warn(e);
475
+ }
476
+ if (typeof i.isDisabled == "function")
477
+ try {
478
+ i['_disabled'] = i.isDisabled(this.data || {});
479
+ }
480
+ catch (e) {
481
+ console.warn(e);
482
+ }
483
+ if (typeof i.isVisible == "function")
484
+ try {
485
+ i['_visible'] = i.isVisible(this.data || {});
486
+ }
487
+ catch (e) {
488
+ console.warn(e);
489
+ }
490
+ if (typeof i.linkTemplate == "function")
491
+ try {
492
+ i['_link'] = i.linkTemplate(this.data || {});
493
+ }
494
+ catch (e) {
495
+ console.warn(e);
496
+ }
497
+ });
498
+ // Show the icon column if there are any items with an icon
499
+ this.showIconColumn = !!this.items.find(i => typeof i == "object" &&
500
+ typeof i['icon'] == "string" &&
501
+ i['icon'].length > 2);
502
+ this.showShortcutColumn = !!this.items.find(i => typeof i == "object" &&
503
+ typeof i['shortcut'] == "string" &&
504
+ i['shortcut'].length > 2);
505
+ // setTimeout(() => {
506
+ // this.closeOnLeave = true
507
+ // }, 300);
508
+ }
509
+ ngAfterViewInit() {
510
+ var _a, _b, _c;
511
+ if (this.parentCords) {
512
+ this.selfCords = (_c = (_b = (_a = this.viewContainer) === null || _a === void 0 ? void 0 : _a.element) === null || _b === void 0 ? void 0 : _b.nativeElement) === null || _c === void 0 ? void 0 : _c.getBoundingClientRect();
513
+ this.changeDetector.detectChanges();
514
+ }
515
+ }
516
+ /**
517
+ *
518
+ * @param item
519
+ * @param evt
520
+ * @returns
521
+ */
522
+ onMenuItemClick(item, row, hideBackdrop = false) {
523
+ var _a, _b, _c, _d;
524
+ return __awaiter(this, void 0, void 0, function* () {
525
+ if (typeof item == 'string')
526
+ return null;
527
+ if (item.separator)
528
+ return null;
529
+ // If cache is enabled, only load if we don't have any children.
530
+ const forceLoad = (item.cacheResolvedChildren ? !item.children : true);
531
+ if (item.childrenResolver && forceLoad) {
532
+ item['_isResolving'] = true;
533
+ item.children = yield item.childrenResolver(this.data);
534
+ item['_isResolving'] = false;
535
+ }
536
+ if (!item.childTemplate && !item.children) {
537
+ if (item.action) {
538
+ item.action(this.data);
539
+ this.close();
540
+ }
541
+ // If no action, this is simply a text item.
542
+ return null;
543
+ }
544
+ // Need X pos, Y pos, width and height
545
+ const bounds = row.getBoundingClientRect();
546
+ const cords = {
547
+ top: null,
548
+ left: null,
549
+ bottom: null,
550
+ right: null
551
+ };
552
+ // Set position coordinates
553
+ const { width, height } = yield (item.childTemplate
554
+ ? calcComponentBounds(TemplateWrapper, { template: item.childTemplate })
555
+ : calcMenuItemBounds(item.children, this.data));
556
+ if (bounds.y + height > window.innerHeight)
557
+ cords.bottom = "0px";
558
+ if (bounds.x + bounds.width + width > window.innerWidth)
559
+ cords.left = ((bounds.x - width)) + "px";
560
+ if (!cords.bottom)
561
+ cords.top = bounds.y + "px";
562
+ if (!cords.left)
563
+ cords.left = bounds.x + bounds.width + "px";
564
+ const component = item.children ? MenuComponent : TemplateWrapper;
565
+ const dialogRef = this.dialog.open(component, {
566
+ position: cords,
567
+ panelClass: ["ngx-ctx-menu", "ngx-app-menu"].concat(((_a = this.config) === null || _a === void 0 ? void 0 : _a.customClass) || []),
568
+ backdropClass: "ngx-ctx-menu-backdrop",
569
+ hasBackdrop: !hideBackdrop,
570
+ data: {
571
+ data: this.data,
572
+ parentCords: (_d = (_c = (_b = this.viewContainer) === null || _b === void 0 ? void 0 : _b.element) === null || _c === void 0 ? void 0 : _c.nativeElement) === null || _d === void 0 ? void 0 : _d.getBoundingClientRect(),
573
+ items: item.children,
574
+ template: item.childTemplate,
575
+ config: this.config
576
+ }
577
+ });
578
+ let _s = dialogRef
579
+ .afterClosed()
580
+ .subscribe((result) => {
581
+ if (result != -1) {
582
+ if (result && typeof item.action == 'function')
583
+ item.action(result);
584
+ this.close();
585
+ }
586
+ else {
587
+ item['_selfclose'] = Date.now();
588
+ }
589
+ _s.unsubscribe();
590
+ });
591
+ return dialogRef;
592
+ });
593
+ }
594
+ /**
595
+ *
596
+ * @param label
597
+ * @returns
598
+ */
599
+ formatLabel(label) {
600
+ return label.replace(/_([a-z0-9])_/i, (match, group) => `<u>${group}</u>`);
601
+ }
602
+ /**
603
+ * Close the context menu under these circumstances
604
+ */
605
+ // @HostListener("window:resize", ['event'])
606
+ // @HostListener("window:blur", ['event'])
607
+ close() {
608
+ var _a;
609
+ this.closeSignal.emit();
610
+ (_a = this.dialogRef) === null || _a === void 0 ? void 0 : _a.close();
611
+ }
612
+ /**
613
+ * Check if the dialog is clipping offscreen
614
+ * if so, move it back into view.
615
+ */
616
+ onResize() {
617
+ var _a, _b;
618
+ const el = (_b = (_a = this.viewContainer) === null || _a === void 0 ? void 0 : _a.element) === null || _b === void 0 ? void 0 : _b.nativeElement;
619
+ if (!el)
620
+ return;
621
+ const { width, height, x, y } = el.getBoundingClientRect();
622
+ const target = document.querySelector(".ngx-ctx-menu,.ngx-app-menu");
623
+ if (!target)
624
+ return;
625
+ // Move back into view if we're clipping outside of the bottom
626
+ if (y + height > window.innerHeight) {
627
+ const newTop = (window.innerHeight - (height + (this.config.edgePadding || 12))) + "px";
628
+ target.style['margin-top'] = newTop;
629
+ }
630
+ // Move back into view if we're clipping off the right
631
+ if (x + width > window.innerWidth) {
632
+ const newLeft = (window.innerWidth - (width + (this.config.edgePadding || 12))) + "px";
633
+ target.style['margin-left'] = newLeft;
634
+ }
635
+ }
636
+ }
637
+ MenuComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: MenuComponent, deps: [{ token: i0.ViewContainerRef }, { token: i1$1.DomSanitizer }, { token: MAT_DIALOG_DATA, optional: true }, { token: i1.MatDialog, optional: true }, { token: i1.MatDialogRef, optional: true }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
638
+ MenuComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.9", type: MenuComponent, isStandalone: true, selector: "ngx-menu", inputs: { data: "data", parentCords: "parentCords", items: "items", config: "config", id: "id" }, outputs: { closeSignal: "closeSignal" }, host: { listeners: { "window:resize": "onResize()" } }, ngImport: i0, template: "<table>\n <tbody>\n <ng-container *ngFor=\"let item of items\">\n <ng-container>\n\n <!-- A row with a click action -->\n <tr #row\n *ngIf=\"item != 'separator' && item.separator != true && item['_visible']\"\n [class.disabled]=\"item['_disabled']\"\n (click)=\"!item['_disabled'] && onMenuItemClick(item, row)\"\n [class.hover]=\"item['children'] && row['hover']\"\n (pointerenter)=\"row['hover'] = true;\"\n (pointerleave)=\"row['hover'] = false\"\n >\n <!-- (item['children']?.length > 0 || item['childTemplate']) && onHover(item, row); closeOnLeave=true -->\n <td class=\"icon\" *ngIf=\"showIconColumn\">\n <img *ngIf=\"matIconRx.test(item.icon); else matIcon\" [src]=\"item.icon\" />\n <ng-template #matIcon>\n <mat-icon [fontIcon]=\"item.icon\"></mat-icon>\n </ng-template>\n </td>\n\n <!-- 'Normal' action based item -->\n <ng-container>\n <td class=\"label\"\n [style.padding-left]=\"showIconColumn ? 0 : '16px'\"\n >\n <a\n [attr.target]=\"item.linkTarget\"\n [attr.href]=\"(item['_link'] || item.link) ? sanitizer.bypassSecurityTrustUrl(item['_link'] || item.link) : undefined\"\n >\n <ng-container\n *ngIf=\"$any(item.labelTemplate)?.prototype; else labelTemplate\"\n [ngTemplateOutlet]=\"$any(item).labelTemplate\"\n [ngTemplateOutletContext]=\"{ '$implicit': data, 'dialog': dialogRef }\"\n />\n\n <ng-template #labelTemplate>\n <ng-container *ngIf=\"!$any(item)?.labelTemplate\">\n <div [innerHTML]=\"item['_formattedLabel']\"></div>\n </ng-container>\n <ng-container *ngIf=\"$any(item)?.labelTemplate\">\n {{$any(item)?.labelTemplate(data || {})}}\n </ng-container>\n </ng-template>\n </a>\n </td>\n </ng-container>\n\n <td class=\"shortcut\" *ngIf=\"showShortcutColumn\">\n {{item.shortcutLabel}}\n </td>\n <td style=\"min-width: 16px\">\n <mat-icon *ngIf=\"\n (item.children && item.children.length > 0) ||\n item.childTemplate ||\n (item.childrenResolver && !item['_isResolving'])\n \"\n sytle=\"transform: translateY(2px)\"\n >\n chevron_right\n </mat-icon>\n\n <mat-progress-spinner *ngIf=\"item['_isResolving']\" mode=\"indeterminate\" [diameter]=\"20\" style=\"margin-right: 4px\"/>\n </td>\n </tr>\n\n <tr *ngIf=\"item != 'separator' && item.separator == true\" class=\"disabled separator\">\n <td class=\"center\" [attr.colspan]=\"2 + (showIconColumn ? 1 : 0) + (showShortcutColumn ? 1 : 0)\">\n <span class=\"hr\">\n {{item['label'] || ''}}\n </span>\n </td>\n </tr>\n <tr *ngIf=\"item == 'separator'\" class=\"disabled separator\">\n <td [attr.colspan]=\"2 + (showIconColumn ? 1 : 0) + (showShortcutColumn ? 1 : 0)\">\n <hr/>\n </td>\n </tr>\n </ng-container>\n </ng-container>\n </tbody>\n</table>\n\n<!-- <div *ngIf=\"true\" class=\"backdrop\"></div> -->\n<!-- <div\n *ngIf=\"parentCords && this.selfCords\"\n class=\"backdrop parent\"\n [style.top]=\"(parentCords.y - selfCords.y + 6) + 'px'\"\n [style.left]=\"(parentCords.x - selfCords.x + 12) + 'px'\"\n [style.width]=\"(parentCords.width) + 'px'\"\n [style.height]=\"(parentCords.height) + 'px'\"\n>\n</div> -->\n<!-- <ng-container *ngIf=\"parentCords && selfCords\">\n <div #top\n class=\"backdrop-outer\"\n [style.bottom]=\"(parentCords.y - selfCords.y)*-1 + parentCords.height + 'px'\"\n style=\"background: #f003;\"\n (pointerenter)=\"onLeave()\"\n ></div>\n <div #right\n class=\"backdrop-outer\"\n [style.left]=\"((parentCords.x - selfCords.x) + parentCords.width) + 'px'\"\n style=\"background: #0f03;\"\n (pointerenter)=\"onLeave()\"\n >\n <div>px: {{parentCords.x}}</div>\n <div>py: {{parentCords.y}}</div>\n <div>pw: {{parentCords.width}}</div>\n <div>ph: {{parentCords.height}}</div>\n <div>sx: {{selfCords.x}}</div>\n <div>sy: {{selfCords.y}}</div>\n <div>sw: {{selfCords.width}}</div>\n <div>sh: {{selfCords.height}}</div>\n </div>\n <div #bottom\n class=\"backdrop-outer\"\n [style.top]=\"((parentCords.y + parentCords.height - selfCords.y)) + 'px'\"\n style=\"background: #00f3;\"\n (pointerenter)=\"onLeave()\"\n ></div>\n <div #left\n class=\"backdrop-outer\"\n [style.right]=\"((parentCords.x - selfCords.x)*-1 + parentCords.width + 32) + 'px'\"\n style=\"background: #fff3;\"\n (pointerenter)=\"onLeave()\"\n ></div>\n</ng-container> -->\n", styles: ["::ng-deep .cdk-overlay-container .ngx-ctx-menu{--mdc-dialog-container-color: var(--ngx-ctx-menu-background-color, #2f2f2f)}::ng-deep .cdk-overlay-container .ngx-ctx-menu .mdc-dialog__container{transform-origin:top left}::ng-deep .cdk-overlay-container .ngx-ctx-menu .mdc-dialog--open .mdc-dialog__container{transform:none}::ng-deep .cdk-overlay-pane.ngx-ctx-menu .mat-mdc-dialog-surface{overflow:visible}:host{-webkit-user-select:none;user-select:none;z-index:1;position:relative;display:block;overflow:hidden auto}table{border-spacing:0;border-radius:5px;padding:4px 0}tr{color:var(--ngx-ctx-menu-text-color, #ccc);font-size:14px;cursor:pointer;transition:background-color 75ms ease,color 75ms ease}tr:not(.disabled):hover{background-color:var(--ngx-ctx-menu-hover-background-color, #94ebeb);color:var(--ngx-ctx-menu-hover-text-color, #000)}tr:not(.disabled):hover a{color:var(--ngx-ctx-menu-hover-text-color, #000)}tr:not(.separator){height:36px}tr.disabled .label{color:var(--ngx-ctx-menu-disabled-text-color, #919191)}tr .center{text-align:center}tr a{outline:0;display:flex;align-items:center;gap:10px;justify-content:space-between;height:100%;width:100%}tr .label{min-width:100px}.hr{height:1px;text-align:center;position:relative}.hr:before,.hr:after{content:\"\";background:var(--ngx-ctx-menu-separator-color, #2a2a2a);display:block;position:absolute;top:0;bottom:0;height:1px;margin:auto;width:300px}.hr:before{right:calc(100% + 4px)}.hr:after{left:calc(100% + 4px)}hr{background:var(--ngx-ctx-menu-separator-color, #2a2a2a);border:0;height:1px;margin:0}.icon{width:24px;height:24px;padding-left:10px}.icon mat-icon{transform:translateY(2px)}.shortcut{color:var(--ngx-ctx-menu-shortcut-text-color, #848484);text-align:end;padding-right:10px;padding-left:12px}.label{height:var(--ngx-ctx-menu-item-height, 30px)}td{vertical-align:middle}\n"], dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i5.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }] });
639
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: MenuComponent, decorators: [{
640
+ type: Component,
641
+ args: [{ selector: 'ngx-menu', imports: [
642
+ NgIf,
643
+ NgForOf,
644
+ NgTemplateOutlet,
645
+ MatIconModule,
646
+ MatProgressSpinnerModule
647
+ ], standalone: true, template: "<table>\n <tbody>\n <ng-container *ngFor=\"let item of items\">\n <ng-container>\n\n <!-- A row with a click action -->\n <tr #row\n *ngIf=\"item != 'separator' && item.separator != true && item['_visible']\"\n [class.disabled]=\"item['_disabled']\"\n (click)=\"!item['_disabled'] && onMenuItemClick(item, row)\"\n [class.hover]=\"item['children'] && row['hover']\"\n (pointerenter)=\"row['hover'] = true;\"\n (pointerleave)=\"row['hover'] = false\"\n >\n <!-- (item['children']?.length > 0 || item['childTemplate']) && onHover(item, row); closeOnLeave=true -->\n <td class=\"icon\" *ngIf=\"showIconColumn\">\n <img *ngIf=\"matIconRx.test(item.icon); else matIcon\" [src]=\"item.icon\" />\n <ng-template #matIcon>\n <mat-icon [fontIcon]=\"item.icon\"></mat-icon>\n </ng-template>\n </td>\n\n <!-- 'Normal' action based item -->\n <ng-container>\n <td class=\"label\"\n [style.padding-left]=\"showIconColumn ? 0 : '16px'\"\n >\n <a\n [attr.target]=\"item.linkTarget\"\n [attr.href]=\"(item['_link'] || item.link) ? sanitizer.bypassSecurityTrustUrl(item['_link'] || item.link) : undefined\"\n >\n <ng-container\n *ngIf=\"$any(item.labelTemplate)?.prototype; else labelTemplate\"\n [ngTemplateOutlet]=\"$any(item).labelTemplate\"\n [ngTemplateOutletContext]=\"{ '$implicit': data, 'dialog': dialogRef }\"\n />\n\n <ng-template #labelTemplate>\n <ng-container *ngIf=\"!$any(item)?.labelTemplate\">\n <div [innerHTML]=\"item['_formattedLabel']\"></div>\n </ng-container>\n <ng-container *ngIf=\"$any(item)?.labelTemplate\">\n {{$any(item)?.labelTemplate(data || {})}}\n </ng-container>\n </ng-template>\n </a>\n </td>\n </ng-container>\n\n <td class=\"shortcut\" *ngIf=\"showShortcutColumn\">\n {{item.shortcutLabel}}\n </td>\n <td style=\"min-width: 16px\">\n <mat-icon *ngIf=\"\n (item.children && item.children.length > 0) ||\n item.childTemplate ||\n (item.childrenResolver && !item['_isResolving'])\n \"\n sytle=\"transform: translateY(2px)\"\n >\n chevron_right\n </mat-icon>\n\n <mat-progress-spinner *ngIf=\"item['_isResolving']\" mode=\"indeterminate\" [diameter]=\"20\" style=\"margin-right: 4px\"/>\n </td>\n </tr>\n\n <tr *ngIf=\"item != 'separator' && item.separator == true\" class=\"disabled separator\">\n <td class=\"center\" [attr.colspan]=\"2 + (showIconColumn ? 1 : 0) + (showShortcutColumn ? 1 : 0)\">\n <span class=\"hr\">\n {{item['label'] || ''}}\n </span>\n </td>\n </tr>\n <tr *ngIf=\"item == 'separator'\" class=\"disabled separator\">\n <td [attr.colspan]=\"2 + (showIconColumn ? 1 : 0) + (showShortcutColumn ? 1 : 0)\">\n <hr/>\n </td>\n </tr>\n </ng-container>\n </ng-container>\n </tbody>\n</table>\n\n<!-- <div *ngIf=\"true\" class=\"backdrop\"></div> -->\n<!-- <div\n *ngIf=\"parentCords && this.selfCords\"\n class=\"backdrop parent\"\n [style.top]=\"(parentCords.y - selfCords.y + 6) + 'px'\"\n [style.left]=\"(parentCords.x - selfCords.x + 12) + 'px'\"\n [style.width]=\"(parentCords.width) + 'px'\"\n [style.height]=\"(parentCords.height) + 'px'\"\n>\n</div> -->\n<!-- <ng-container *ngIf=\"parentCords && selfCords\">\n <div #top\n class=\"backdrop-outer\"\n [style.bottom]=\"(parentCords.y - selfCords.y)*-1 + parentCords.height + 'px'\"\n style=\"background: #f003;\"\n (pointerenter)=\"onLeave()\"\n ></div>\n <div #right\n class=\"backdrop-outer\"\n [style.left]=\"((parentCords.x - selfCords.x) + parentCords.width) + 'px'\"\n style=\"background: #0f03;\"\n (pointerenter)=\"onLeave()\"\n >\n <div>px: {{parentCords.x}}</div>\n <div>py: {{parentCords.y}}</div>\n <div>pw: {{parentCords.width}}</div>\n <div>ph: {{parentCords.height}}</div>\n <div>sx: {{selfCords.x}}</div>\n <div>sy: {{selfCords.y}}</div>\n <div>sw: {{selfCords.width}}</div>\n <div>sh: {{selfCords.height}}</div>\n </div>\n <div #bottom\n class=\"backdrop-outer\"\n [style.top]=\"((parentCords.y + parentCords.height - selfCords.y)) + 'px'\"\n style=\"background: #00f3;\"\n (pointerenter)=\"onLeave()\"\n ></div>\n <div #left\n class=\"backdrop-outer\"\n [style.right]=\"((parentCords.x - selfCords.x)*-1 + parentCords.width + 32) + 'px'\"\n style=\"background: #fff3;\"\n (pointerenter)=\"onLeave()\"\n ></div>\n</ng-container> -->\n", styles: ["::ng-deep .cdk-overlay-container .ngx-ctx-menu{--mdc-dialog-container-color: var(--ngx-ctx-menu-background-color, #2f2f2f)}::ng-deep .cdk-overlay-container .ngx-ctx-menu .mdc-dialog__container{transform-origin:top left}::ng-deep .cdk-overlay-container .ngx-ctx-menu .mdc-dialog--open .mdc-dialog__container{transform:none}::ng-deep .cdk-overlay-pane.ngx-ctx-menu .mat-mdc-dialog-surface{overflow:visible}:host{-webkit-user-select:none;user-select:none;z-index:1;position:relative;display:block;overflow:hidden auto}table{border-spacing:0;border-radius:5px;padding:4px 0}tr{color:var(--ngx-ctx-menu-text-color, #ccc);font-size:14px;cursor:pointer;transition:background-color 75ms ease,color 75ms ease}tr:not(.disabled):hover{background-color:var(--ngx-ctx-menu-hover-background-color, #94ebeb);color:var(--ngx-ctx-menu-hover-text-color, #000)}tr:not(.disabled):hover a{color:var(--ngx-ctx-menu-hover-text-color, #000)}tr:not(.separator){height:36px}tr.disabled .label{color:var(--ngx-ctx-menu-disabled-text-color, #919191)}tr .center{text-align:center}tr a{outline:0;display:flex;align-items:center;gap:10px;justify-content:space-between;height:100%;width:100%}tr .label{min-width:100px}.hr{height:1px;text-align:center;position:relative}.hr:before,.hr:after{content:\"\";background:var(--ngx-ctx-menu-separator-color, #2a2a2a);display:block;position:absolute;top:0;bottom:0;height:1px;margin:auto;width:300px}.hr:before{right:calc(100% + 4px)}.hr:after{left:calc(100% + 4px)}hr{background:var(--ngx-ctx-menu-separator-color, #2a2a2a);border:0;height:1px;margin:0}.icon{width:24px;height:24px;padding-left:10px}.icon mat-icon{transform:translateY(2px)}.shortcut{color:var(--ngx-ctx-menu-shortcut-text-color, #848484);text-align:end;padding-right:10px;padding-left:12px}.label{height:var(--ngx-ctx-menu-item-height, 30px)}td{vertical-align:middle}\n"] }]
648
+ }], ctorParameters: function () {
649
+ return [{ type: i0.ViewContainerRef }, { type: i1$1.DomSanitizer }, { type: undefined, decorators: [{
650
+ type: Optional
651
+ }, {
652
+ type: Inject,
653
+ args: [MAT_DIALOG_DATA]
654
+ }] }, { type: i1.MatDialog, decorators: [{
655
+ type: Optional
656
+ }] }, { type: i1.MatDialogRef, decorators: [{
657
+ type: Optional
658
+ }] }, { type: i0.ChangeDetectorRef }];
659
+ }, propDecorators: { data: [{
660
+ type: Input
661
+ }], parentCords: [{
662
+ type: Input
663
+ }], items: [{
664
+ type: Input
665
+ }], config: [{
666
+ type: Input
667
+ }], id: [{
668
+ type: Input
669
+ }], closeSignal: [{
670
+ type: Output
671
+ }], onResize: [{
672
+ type: HostListener,
673
+ args: ["window:resize"]
674
+ }] } });
675
+
676
+ class MenuDirective {
677
+ constructor(dialog, viewContainer) {
678
+ this.dialog = dialog;
679
+ this.viewContainer = viewContainer;
680
+ /**
681
+ * Configuration for opening the app menu
682
+ */
683
+ this.config = {};
684
+ }
685
+ ngAfterViewInit() {
686
+ var _a;
687
+ const el = this.viewContainer.element.nativeElement;
688
+ // Automatically attach context menu items to
689
+ // the contextmenu event
690
+ if (this.ctxMenuItems) {
691
+ el.onclick = this.openMenu.bind(this);
692
+ el.addEventListener('contextmenu', (e) => {
693
+ e.preventDefault();
694
+ this.openMenu(e);
695
+ });
696
+ }
697
+ if (!((_a = this.config) === null || _a === void 0 ? void 0 : _a.trigger)) {
698
+ el.onclick = this.openMenu.bind(this);
699
+ el.addEventListener('click', this.openMenu.bind(this));
700
+ }
701
+ else {
702
+ const triggers = Array.isArray(this.config.trigger) ? this.config.trigger : [this.config.trigger];
703
+ triggers.forEach(t => {
704
+ if (t == "contextmenu") {
705
+ el.addEventListener(t, (e) => {
706
+ e.preventDefault();
707
+ this.openMenu(e);
708
+ });
709
+ }
710
+ else {
711
+ el.addEventListener(t, this.openMenu.bind(this));
712
+ }
713
+ });
714
+ }
715
+ }
716
+ openMenu(evt) {
717
+ return __awaiter(this, void 0, void 0, function* () {
718
+ const el = this.viewContainer.element.nativeElement;
719
+ el.classList.add("ngx-menu-open");
720
+ return openMenu(this.dialog, this.menuItems, this.data, evt, this.config)
721
+ .then((...res) => {
722
+ el.classList.remove("ngx-menu-open");
723
+ return res;
724
+ })
725
+ .catch((ex) => {
726
+ el.classList.remove("ngx-menu-open");
727
+ throw ex;
728
+ });
729
+ });
730
+ }
731
+ }
732
+ MenuDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: MenuDirective, deps: [{ token: i1.MatDialog }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Directive });
733
+ MenuDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.9", type: MenuDirective, isStandalone: true, selector: "[ngx-ctxmenu],[ngx-menu]", inputs: { data: ["ngx-menu-context", "data"], ctxMenuItems: ["ngx-ctxmenu", "ctxMenuItems"], menuItems: ["ngx-menu", "menuItems"], config: ["ngx-menu-config", "config"] }, providers: [
734
+ MatDialog
735
+ ], ngImport: i0 });
736
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: MenuDirective, decorators: [{
737
+ type: Directive,
738
+ args: [{
739
+ selector: '[ngx-ctxmenu],[ngx-menu]',
740
+ providers: [
741
+ MatDialog
742
+ ],
743
+ standalone: true
744
+ }]
745
+ }], ctorParameters: function () { return [{ type: i1.MatDialog }, { type: i0.ViewContainerRef }]; }, propDecorators: { data: [{
746
+ type: Input,
747
+ args: ["ngx-menu-context"]
748
+ }], ctxMenuItems: [{
749
+ type: Input,
750
+ args: ["ngx-ctxmenu"]
751
+ }], menuItems: [{
752
+ type: Input,
753
+ args: ["ngx-menu"]
754
+ }], config: [{
755
+ type: Input,
756
+ args: ["ngx-menu-config"]
757
+ }] } });
758
+ // Helper to open the context menu without using the directive.
759
+ const openMenu = (dialog, menuItems, data, evt, config = {}) => __awaiter(void 0, void 0, void 0, function* () {
760
+ evt.preventDefault();
761
+ evt.stopPropagation();
762
+ const cords = getPosition(evt, config, yield calcMenuItemBounds(menuItems, data));
763
+ const specificId = crypto.randomUUID();
764
+ if (!config.alignment)
765
+ config.alignment = "start";
766
+ return new Promise(res => {
767
+ dialog.open(MenuComponent, {
768
+ data: {
769
+ data: data,
770
+ items: menuItems,
771
+ config: config,
772
+ id: specificId
773
+ },
774
+ panelClass: ["ngx-menu", 'ngx-' + specificId].concat((config === null || config === void 0 ? void 0 : config.customClass) || []),
775
+ position: cords,
776
+ backdropClass: "ngx-menu-backdrop"
777
+ })
778
+ .afterClosed()
779
+ .subscribe(s => {
780
+ res(s);
781
+ });
782
+ });
783
+ });
784
+
785
+ /**
786
+ * Url Sanitizer pipe.
787
+ *
788
+ * This trusts URLs that exist in a safe list defined in our environments.ts file.
789
+ * Any other URLs will NOT be trusted, thus will not be loaded.
790
+ */
791
+ class HtmlBypass {
792
+ constructor(sanitizer) {
793
+ this.sanitizer = sanitizer;
794
+ }
795
+ transform(url) {
796
+ return this.sanitizer.bypassSecurityTrustHtml(url);
797
+ }
798
+ }
799
+ HtmlBypass.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: HtmlBypass, deps: [{ token: i1$1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Pipe });
800
+ HtmlBypass.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "15.2.9", ngImport: i0, type: HtmlBypass, isStandalone: true, name: "htmlbypass" });
801
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: HtmlBypass, decorators: [{
802
+ type: Pipe,
803
+ args: [{
804
+ name: 'htmlbypass',
805
+ standalone: true
806
+ }]
807
+ }], ctorParameters: function () { return [{ type: i1$1.DomSanitizer }]; } });
808
+
809
+ /**
810
+ * Url Sanitizer pipe.
811
+ *
812
+ * This trusts URLs that exist in a safe list defined in our environments.ts file.
813
+ * Any other URLs will NOT be trusted, thus will not be loaded.
814
+ */
815
+ class ResourceBypass {
816
+ constructor(sanitizer) {
817
+ this.sanitizer = sanitizer;
818
+ }
819
+ transform(url) {
820
+ return this.sanitizer.bypassSecurityTrustResourceUrl(url);
821
+ }
822
+ }
823
+ ResourceBypass.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ResourceBypass, deps: [{ token: i1$1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Pipe });
824
+ ResourceBypass.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "15.2.9", ngImport: i0, type: ResourceBypass, isStandalone: true, name: "resourcebypass" });
825
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ResourceBypass, decorators: [{
826
+ type: Pipe,
827
+ args: [{
828
+ name: 'resourcebypass',
829
+ standalone: true
830
+ }]
831
+ }], ctorParameters: function () { return [{ type: i1$1.DomSanitizer }]; } });
832
+
833
+ /**
834
+ * Url Sanitizer pipe.
835
+ *
836
+ * This trusts URLs that exist in a safe list defined in our environments.ts file.
837
+ * Any other URLs will NOT be trusted, thus will not be loaded.
838
+ */
839
+ class ScriptBypass {
840
+ constructor(sanitizer) {
841
+ this.sanitizer = sanitizer;
842
+ }
843
+ transform(url) {
844
+ return this.sanitizer.bypassSecurityTrustScript(url);
845
+ }
846
+ }
847
+ ScriptBypass.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ScriptBypass, deps: [{ token: i1$1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Pipe });
848
+ ScriptBypass.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "15.2.9", ngImport: i0, type: ScriptBypass, isStandalone: true, name: "scriptbypass" });
849
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ScriptBypass, decorators: [{
850
+ type: Pipe,
851
+ args: [{
852
+ name: 'scriptbypass',
853
+ standalone: true
854
+ }]
855
+ }], ctorParameters: function () { return [{ type: i1$1.DomSanitizer }]; } });
856
+
857
+ /**
858
+ * Url Sanitizer pipe.
859
+ *
860
+ * This trusts URLs that exist in a safe list defined in our environments.ts file.
861
+ * Any other URLs will NOT be trusted, thus will not be loaded.
862
+ */
863
+ class StyleBypass {
864
+ constructor(sanitizer) {
865
+ this.sanitizer = sanitizer;
866
+ }
867
+ transform(url) {
868
+ return this.sanitizer.bypassSecurityTrustStyle(url);
869
+ }
870
+ }
871
+ StyleBypass.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: StyleBypass, deps: [{ token: i1$1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Pipe });
872
+ StyleBypass.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "15.2.9", ngImport: i0, type: StyleBypass, isStandalone: true, name: "stylebypass" });
873
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: StyleBypass, decorators: [{
874
+ type: Pipe,
875
+ args: [{
876
+ name: 'stylebypass',
877
+ standalone: true
878
+ }]
879
+ }], ctorParameters: function () { return [{ type: i1$1.DomSanitizer }]; } });
880
+
881
+ /**
882
+ * Url Sanitizer pipe.
883
+ *
884
+ * This trusts URLs that exist in a safe list defined in our environments.ts file.
885
+ * Any other URLs will NOT be trusted, thus will not be loaded.
886
+ */
887
+ class UrlBypass {
888
+ constructor(sanitizer) {
889
+ this.sanitizer = sanitizer;
890
+ }
891
+ transform(url) {
892
+ return this.sanitizer.bypassSecurityTrustUrl(url);
893
+ }
894
+ }
895
+ UrlBypass.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: UrlBypass, deps: [{ token: i1$1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Pipe });
896
+ UrlBypass.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "15.2.9", ngImport: i0, type: UrlBypass, isStandalone: true, name: "urlbypass" });
897
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: UrlBypass, decorators: [{
898
+ type: Pipe,
899
+ args: [{
900
+ name: 'urlbypass',
901
+ standalone: true
902
+ }]
903
+ }], ctorParameters: function () { return [{ type: i1$1.DomSanitizer }]; } });
904
+
905
+ const sleep = ms => new Promise(r => setTimeout(r, ms));
906
+ /**
907
+ * Prompt the user to save a json file of the given object.
908
+ */
909
+ const saveObjectAsFile = (name, data) => {
910
+ const a = document.createElement("a");
911
+ const file = new Blob([JSON.stringify(data)], { type: "application/json" });
912
+ a.href = URL.createObjectURL(file);
913
+ a.download = name;
914
+ a.click();
915
+ a.remove();
916
+ };
917
+ /**
918
+ * Formatted logger that will print a bit of context before the message.
919
+ * @returns
920
+ */
921
+ const Logger = (context, contextColor, textColor = "#03a9f4") => ({
922
+ log: (message, ...args) => {
923
+ console.log(`%c[${context}] %c${message}`, 'color: ' + contextColor, 'color: ' + textColor, ...args);
924
+ },
925
+ warn: (message, ...args) => {
926
+ console.warn(`%c[${context}] %c${message}`, 'color: ' + contextColor, 'color: ' + textColor, ...args);
927
+ },
928
+ err: (message, ...args) => {
929
+ console.error(`%c[${context}] %c${message}`, 'color: ' + contextColor, 'color: ' + textColor, ...args);
930
+ },
931
+ error: (message, ...args) => {
932
+ console.error(`%c[${context}] %c${message}`, 'color: ' + contextColor, 'color: ' + textColor, ...args);
933
+ }
934
+ });
935
+ /**
936
+ * Convert a string `fooBAR baz_160054''"1]"` into a slug: `foobar-baz-1600541`
937
+ */
938
+ const stringToSlug = (text) => (text || '')
939
+ .trim()
940
+ .toLowerCase()
941
+ .replace(/[\-_+ ]/g, '-')
942
+ .replace(/[^a-z0-9\-]/g, '');
943
+
944
+ const SCRIPT_INIT_TIMEOUT = 500; // ms
945
+ /**
946
+ * Service that installs CSS/JS dynamically
947
+ */
948
+ class DependencyService {
949
+ constructor(document) {
950
+ this.document = document;
951
+ }
952
+ /**
953
+ * Install a Javascript file into the webpage on-demand
954
+ * @param id Unique identifier for the JS script
955
+ * @param src URL of the script
956
+ * @param globalkey A global object the script will provide.
957
+ * Providing this will ensure a promise only resolves after the
958
+ * specified global object is provided, with a timeout of 500ms
959
+ */
960
+ loadScript(id, src, globalkey = null) {
961
+ return new Promise((res, rej) => {
962
+ if (this.document.getElementById(id))
963
+ return res();
964
+ const script = this.document.createElement('script');
965
+ script.id = id;
966
+ script.setAttribute("async", '');
967
+ script.setAttribute("src", src);
968
+ script.onload = () => __awaiter(this, void 0, void 0, function* () {
969
+ if (typeof globalkey == "string") {
970
+ let i = 0;
971
+ for (; !window[globalkey] && i < SCRIPT_INIT_TIMEOUT; i += 10)
972
+ yield sleep(10);
973
+ if (i >= SCRIPT_INIT_TIMEOUT) {
974
+ return rej(new Error("Timed out waiting for script to self-initialize."));
975
+ }
976
+ }
977
+ res();
978
+ });
979
+ this.document.body.appendChild(script);
980
+ });
981
+ }
982
+ }
983
+ DependencyService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: DependencyService, deps: [{ token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Injectable });
984
+ DependencyService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: DependencyService, providedIn: 'root' });
985
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: DependencyService, decorators: [{
986
+ type: Injectable,
987
+ args: [{
988
+ providedIn: 'root'
989
+ }]
990
+ }], ctorParameters: function () {
991
+ return [{ type: Document, decorators: [{
992
+ type: Inject,
993
+ args: [DOCUMENT]
994
+ }] }];
995
+ } });
996
+
997
+ const { log, warn, err } = Logger("DialogService", "#607d8b");
998
+ class DialogService {
999
+ constructor(dialog, lazyLoader) {
1000
+ this.dialog = dialog;
1001
+ this.lazyLoader = lazyLoader;
1002
+ this.dialogs = [];
1003
+ }
1004
+ open(name, opts = {}) {
1005
+ return new Promise((resolve, reject) => {
1006
+ const registration = this.lazyLoader.resolveRegistrationEntry(name, opts.group || "default");
1007
+ if (!registration)
1008
+ return reject(new Error("Cannot open dialog for " + name + ". Could not find in registry."));
1009
+ const args = Object.assign(Object.assign({ closeOnNavigation: true, restoreFocus: true, width: registration['width'], height: registration['height'] }, opts), { data: {
1010
+ id: name,
1011
+ inputs: opts.inputs || {},
1012
+ outputs: opts.outputs || {},
1013
+ group: opts.group
1014
+ }, panelClass: [
1015
+ "dialog-" + name,
1016
+ ...(Array.isArray(opts.panelClass) ? opts.panelClass : [opts.panelClass] || [])
1017
+ ] });
1018
+ // TODO:
1019
+ let dialog = this.dialog.open(undefined, args);
1020
+ dialog['idx'] = name;
1021
+ this.dialogs.push(dialog);
1022
+ dialog.afterClosed().subscribe(result => {
1023
+ log("Dialog closed " + name, result);
1024
+ resolve(result);
1025
+ });
1026
+ });
1027
+ }
1028
+ // Close all dialogs matching the given name
1029
+ close(name) {
1030
+ const dialogs = this.dialogs.filter(d => d['idx'] == name);
1031
+ dialogs.forEach(dialog => dialog.close());
1032
+ }
1033
+ /**
1034
+ * Method to close _all_ dialogs.
1035
+ * Should be used sparingly.
1036
+ */
1037
+ clearDialog() {
1038
+ this.dialogs.forEach(dialog => dialog.close());
1039
+ }
1040
+ }
1041
+ DialogService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: DialogService, deps: [{ token: i1.MatDialog }, { token: LazyLoaderService }], target: i0.ɵɵFactoryTarget.Injectable });
1042
+ DialogService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: DialogService, providedIn: 'root' });
1043
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: DialogService, decorators: [{
1044
+ type: Injectable,
1045
+ args: [{
1046
+ providedIn: 'root'
1047
+ }]
1048
+ }], ctorParameters: function () { return [{ type: i1.MatDialog }, { type: LazyLoaderService }]; } });
1049
+
1050
+ // Total number of _retries_ if there is a 429 response code.
1051
+ const retryCount = 2;
1052
+ class Fetch {
1053
+ constructor(http) {
1054
+ this.http = http;
1055
+ }
1056
+ // Public interface for making AJAX transactions
1057
+ get(url, options = {}, returnError = false) {
1058
+ return this.request("get", url, options, returnError);
1059
+ }
1060
+ put(url, body, options = {}, returnError = false) {
1061
+ options.body = (options.body && Object.keys(options.body).length > 0 ? options.body : body) || {};
1062
+ return this.request("put", url, options, returnError);
1063
+ }
1064
+ post(url, body, options = {}, returnError = false) {
1065
+ options.body = (options.body && Object.keys(options.body).length > 0 ? options.body : body) || {};
1066
+ return this.request("post", url, options, returnError);
1067
+ }
1068
+ patch(url, body, options = {}, returnError = false) {
1069
+ options.body = (options.body && Object.keys(options.body).length > 0 ? options.body : body) || {};
1070
+ return this.request("patch", url, options, returnError);
1071
+ }
1072
+ delete(url, options = {}, returnError = false) {
1073
+ return this.request("delete", url, options, returnError);
1074
+ }
1075
+ // Internally, handle the observable as a promise.
1076
+ request(method, url, options = {}, returnError = false) {
1077
+ options.reportProgress = true;
1078
+ // Allow support for different response types.
1079
+ // Generally we shouldn't need this to be anything other than JSON.
1080
+ options.responseType = options.responseType || "json";
1081
+ options.withCredentials = true;
1082
+ const p = new Promise((resolve, reject) => {
1083
+ const o = this.http.request(method, url, options)
1084
+ .pipe(retry({
1085
+ delay(error, retryCount) {
1086
+ // 429 and 502 are most common for overloaded
1087
+ // backends -- so we'll retry if we get these errors
1088
+ if (error.status == 429 || error.status == 502)
1089
+ return of({});
1090
+ if (error.status == 504 && isDevMode())
1091
+ alert("It looks like you can't reach your development backend anymore");
1092
+ throw error;
1093
+ },
1094
+ count: retryCount
1095
+ }))
1096
+ .subscribe(data => {
1097
+ resolve(data);
1098
+ // provide 3ms slacktime before releasing observable.
1099
+ setTimeout(() => {
1100
+ o.unsubscribe();
1101
+ }, 3);
1102
+ });
1103
+ });
1104
+ return p;
1105
+ }
1106
+ }
1107
+ Fetch.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: Fetch, deps: [{ token: i1$2.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable });
1108
+ Fetch.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: Fetch, providedIn: "root" });
1109
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: Fetch, decorators: [{
1110
+ type: Injectable,
1111
+ args: [{
1112
+ providedIn: "root"
1113
+ }]
1114
+ }], ctorParameters: function () { return [{ type: i1$2.HttpClient }]; } });
1115
+
1116
+ /**
1117
+ * Service that listens for global keyboard events
1118
+ */
1119
+ class KeyboardService {
1120
+ constructor() {
1121
+ this.heldKeys = {};
1122
+ this.keyCommands = [];
1123
+ window.addEventListener("keydown", (evt) => this.onKeyDown(evt));
1124
+ window.addEventListener("keyup", (evt) => this.onKeyUp(evt));
1125
+ }
1126
+ onKeyDown(evt) {
1127
+ // console.log("keydown", evt.key)
1128
+ this.heldKeys[evt.key.toLowerCase()] = true;
1129
+ // Do a general filter where all of the modifiers must be matched if specified
1130
+ // Then check that the actual keys match what was specified
1131
+ let commands = this.keyCommands
1132
+ .filter(kc => {
1133
+ var _a;
1134
+ return (kc.ctrl == undefined || kc.ctrl === evt.ctrlKey) &&
1135
+ (kc.alt == undefined || kc.alt === evt.altKey) &&
1136
+ (kc.shift == undefined || kc.shift === evt.shiftKey) &&
1137
+ (kc.super == undefined || kc.super === evt.metaKey) &&
1138
+ kc.keys.length == ((_a = kc.keys.filter(k => this.heldKeys[k])) === null || _a === void 0 ? void 0 : _a.length);
1139
+ });
1140
+ if (evt.ctrlKey && commands.length > 0 || commands.find(c => c.interrupt)) {
1141
+ evt.stopPropagation();
1142
+ evt.preventDefault();
1143
+ }
1144
+ if (evt.key == "Pause")
1145
+ debugger;
1146
+ commands.forEach(kc => kc.sub.next(evt));
1147
+ /**
1148
+ * Prevent CTRL+P and other standard key events from being handled by the browser.
1149
+ * Allow specific combonations:
1150
+ * CTRL+W
1151
+ * CTRL+T
1152
+ * CTRL+F5
1153
+ */
1154
+ // if (evt.ctrlKey && !['w', 't', 'F5'].includes(evt.key)) {
1155
+ // evt.preventDefault();
1156
+ // }
1157
+ }
1158
+ onKeyUp(evt) {
1159
+ this.heldKeys[evt.key.toLowerCase()] = false;
1160
+ }
1161
+ onKeyPress(evt) {
1162
+ // this.heldKeys[evt.key] = false;
1163
+ }
1164
+ /**
1165
+ * Use this to subscribe to keyboard events throughout
1166
+ * the application. This is a passive listener and will
1167
+ * **NOT** interrupt the event chain.
1168
+ */
1169
+ onKeyCommand(key) {
1170
+ const sub = new Subject();
1171
+ let item = Object.assign(Object.assign({}, key), { keys: (Array.isArray(key.key) ? key.key : [key.key]), sub: sub });
1172
+ this.keyCommands.push(item);
1173
+ return Object.assign(Object.assign({}, sub), { subscribe: ((...args) => {
1174
+ const s = sub.subscribe(...args);
1175
+ return Object.assign(Object.assign({}, s), { unsubscribe: () => {
1176
+ s.unsubscribe();
1177
+ // Remove the keycommand from the list of listeners.
1178
+ const i = this.keyCommands.findIndex(c => c == item);
1179
+ this.keyCommands.splice(i, 1);
1180
+ } });
1181
+ }) });
1182
+ }
1183
+ /**
1184
+ * Return `true` if shift is currently pressed.
1185
+ */
1186
+ get isShiftPressed() {
1187
+ return !!this.heldKeys["shift"];
1188
+ }
1189
+ /**
1190
+ * Return `true` if ctrl is currently pressed.
1191
+ */
1192
+ get isCtrlPressed() {
1193
+ return !!this.heldKeys["control"];
1194
+ }
1195
+ /**
1196
+ * Return `true` if alt is currently pressed.
1197
+ */
1198
+ get isAltPressed() {
1199
+ return !!this.heldKeys["alt"];
1200
+ }
1201
+ /**
1202
+ * Return `true` if super (mac/linux) or the windows key is currently pressed.
1203
+ */
1204
+ get isSuperPressed() {
1205
+ return !!this.heldKeys["super"];
1206
+ }
1207
+ /**
1208
+ * Return `true` if tab is currently pressed.
1209
+ */
1210
+ get isTabPressed() {
1211
+ return !!this.heldKeys["tab"];
1212
+ }
1213
+ clearKeys() {
1214
+ Object.keys(this.heldKeys).forEach(k => {
1215
+ this.heldKeys[k] = false;
1216
+ });
1217
+ }
1218
+ }
1219
+ KeyboardService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: KeyboardService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1220
+ KeyboardService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: KeyboardService, providedIn: 'root' });
1221
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: KeyboardService, decorators: [{
1222
+ type: Injectable,
1223
+ args: [{
1224
+ providedIn: 'root'
1225
+ }]
1226
+ }], ctorParameters: function () { return []; }, propDecorators: { clearKeys: [{
1227
+ type: HostListener,
1228
+ args: ["window:blur"]
1229
+ }, {
1230
+ type: HostListener,
1231
+ args: ["window:resize"]
1232
+ }] } });
1233
+
1234
+ var ComponentResolveStrategy;
1235
+ (function (ComponentResolveStrategy) {
1236
+ /**
1237
+ * Match the fist component we find
1238
+ * (best used for standalone components)
1239
+ * @default
1240
+ */
1241
+ ComponentResolveStrategy[ComponentResolveStrategy["PickFirst"] = 0] = "PickFirst";
1242
+ /**
1243
+ * Perform an Exact ID to Classname of the Component
1244
+ * case sensitive, zero tolerance.
1245
+ */
1246
+ ComponentResolveStrategy[ComponentResolveStrategy["MatchIdToClassName"] = 1] = "MatchIdToClassName";
1247
+ /**
1248
+ * Perform a fuzzy ID to classname match
1249
+ * case insensitive, mutes symbols
1250
+ * ignores "Component" and "Module" postfixes on class
1251
+ * names
1252
+ */
1253
+ ComponentResolveStrategy[ComponentResolveStrategy["FuzzyIdClassName"] = 2] = "FuzzyIdClassName";
1254
+ /**
1255
+ * Use a user-provided component match function
1256
+ */
1257
+ ComponentResolveStrategy[ComponentResolveStrategy["Custom"] = 3] = "Custom";
1258
+ })(ComponentResolveStrategy || (ComponentResolveStrategy = {}));
1259
+
1260
+ // Monkey-patch the type of these symbols.
1261
+ const $id = Symbol("id");
1262
+ const $group = Symbol("group");
1263
+ const NGX_LAZY_LOADER_CONFIG = new InjectionToken('config');
1264
+ class LazyLoaderService {
1265
+ get err() { return LazyLoaderService.config.logger.err; }
1266
+ get log() { return LazyLoaderService.config.logger.log; }
1267
+ get warn() { return LazyLoaderService.config.logger.warn; }
1268
+ constructor(config = {}) {
1269
+ // Ensure this is singleton and works regardless of special instancing requirements.
1270
+ LazyLoaderService.configure(config);
1271
+ }
1272
+ static configure(config) {
1273
+ var _a;
1274
+ const { log, warn, err } = Logger("ngx-lazy-loader", "#009688");
1275
+ this.config = Object.assign({ componentResolveStrategy: ComponentResolveStrategy.PickFirst, logger: {
1276
+ log,
1277
+ warn,
1278
+ err
1279
+ } }, config);
1280
+ (_a = config.entries) === null || _a === void 0 ? void 0 : _a.forEach(e => this.addComponentToRegistry(e));
1281
+ // If a custom resolution strategy is provided but no resolution function is passed,
1282
+ // we throw an error
1283
+ if (this.config.componentResolveStrategy == ComponentResolveStrategy.Custom &&
1284
+ !this.config.customResolver) {
1285
+ throw new Error("Cannot initialize. Configuration specifies a custom resolve matcher but none was provided");
1286
+ }
1287
+ if (this.config.loaderDistractorComponent && this.config.loaderDistractorTemplate)
1288
+ throw new Error("Cannot have both a Component and Template for Distractor view.");
1289
+ if (this.config.errorComponent && this.config.errorTemplate)
1290
+ throw new Error("Cannot have both a Component and Template for Error view.");
1291
+ if (this.config.notFoundComponent && this.config.notFoundTemplate)
1292
+ throw new Error("Cannot have both a Component and Template for NotFound view.");
1293
+ }
1294
+ static addComponentToRegistry(registration) {
1295
+ var _a;
1296
+ if (!registration)
1297
+ throw new Error("Cannot add <undefined> component into registry.");
1298
+ // Clone the object into our repository and transfer the id into a standardized slug format
1299
+ const id = stringToSlug((_a = registration.id) !== null && _a !== void 0 ? _a : Date.now().toString()); // purge non-basic ASCII chars
1300
+ const group = registration.group || "default";
1301
+ registration[$id] = id;
1302
+ registration[$group] = id;
1303
+ if (!this.registry[group])
1304
+ this.registry[group] = [];
1305
+ // Check if we already have a registration for the component
1306
+ // if (this.registry[group] && typeof this.registry[group]['load'] == "function") {
1307
+ // // Warn the developer that the state is problematic
1308
+ // this.config.logger.warn(
1309
+ // `A previous entry already exists for ${id}! The old registration will be overridden.` +
1310
+ // `Please ensure you use groups if you intend to have duplicate component ids. ` +
1311
+ // `If this was intentional, first remove the old component from the registry before adding a new instance`
1312
+ // );
1313
+ // // If we're in dev mode, break the loader surface
1314
+ // if (isDevMode())
1315
+ // return;
1316
+ // }
1317
+ this.registry[group].push(registration);
1318
+ }
1319
+ /**
1320
+ * Register an Angular component
1321
+ * @param id identifier that is used to resolve the component
1322
+ * @param group
1323
+ * @param component Angular Component Class constructor
1324
+ */
1325
+ registerComponent(args) {
1326
+ if (this.isComponentRegistered(args.id, args.group)) {
1327
+ this.log(`Will not re-register component '${args.id}' in group '${args.group || 'default'}' `);
1328
+ return;
1329
+ }
1330
+ LazyLoaderService.addComponentToRegistry({
1331
+ id: stringToSlug(args.id),
1332
+ matcher: args.matcher,
1333
+ group: stringToSlug(args.group || "default"),
1334
+ load: args.load || (() => args.component)
1335
+ });
1336
+ }
1337
+ /**
1338
+ *
1339
+ * @param id
1340
+ * @param group
1341
+ */
1342
+ unregisterComponent(id, group = "default") {
1343
+ const _id = stringToSlug(id);
1344
+ const _group = stringToSlug(group);
1345
+ if (!this.resolveRegistrationEntry(id, group))
1346
+ throw new Error("Cannot unregister component ${}! Component is not present in registry");
1347
+ // TODO: handle clearing running instances
1348
+ delete LazyLoaderService.registry[_group][_id];
1349
+ }
1350
+ /**
1351
+ * Get the registration entry for a component.
1352
+ * Returns null if component is not in the registry.
1353
+ */
1354
+ resolveRegistrationEntry(value, group = "default") {
1355
+ const _id = stringToSlug(value);
1356
+ const _group = stringToSlug(group);
1357
+ const targetGroup = (LazyLoaderService.registry[_group] || []);
1358
+ let items = targetGroup.filter(t => {
1359
+ if (!t)
1360
+ return false;
1361
+ // No matcher, check id
1362
+ if (!t.matcher)
1363
+ return t[$id] == _id;
1364
+ // Matcher is regex
1365
+ if (t.matcher instanceof RegExp)
1366
+ return t.matcher.test(_id) || t.matcher.test(value);
1367
+ // Matcher is string => regex
1368
+ if (typeof t.matcher == 'string') {
1369
+ const rx = new RegExp(t.matcher, 'ui');
1370
+ return rx.test(_id) || rx.test(value);
1371
+ }
1372
+ // Matcher is array
1373
+ if (Array.isArray(t.matcher)) {
1374
+ return !!t.matcher.find(e => stringToSlug(e) == _id);
1375
+ }
1376
+ // Custom matcher function
1377
+ if (typeof t.matcher == "function")
1378
+ return t.matcher(_id);
1379
+ return false;
1380
+ });
1381
+ if (items.length > 1) {
1382
+ this.warn("Resolved multiple components for the provided `[component]` binding. This may cause UI conflicts.");
1383
+ }
1384
+ if (items.length == 0) {
1385
+ return null;
1386
+ }
1387
+ const out = items[0];
1388
+ if (out.matcher instanceof RegExp) {
1389
+ const result = _id.match(out.matcher) || value.match(out.matcher);
1390
+ return {
1391
+ entry: out,
1392
+ matchGroups: result === null || result === void 0 ? void 0 : result.groups
1393
+ };
1394
+ }
1395
+ return { entry: out };
1396
+ }
1397
+ /**
1398
+ * Check if a component is currently registered
1399
+ * Can be used to validate regex matchers and aliases.
1400
+ */
1401
+ isComponentRegistered(value, group = "default") {
1402
+ return !!this.resolveRegistrationEntry(value, group);
1403
+ }
1404
+ /**
1405
+ *
1406
+ * @param bundle
1407
+ * @returns The component `Object` if a component was resolved, `null` if no component was found
1408
+ * `false` if the specified strategy was an invalid selection
1409
+ */
1410
+ resolveComponent(id, group, modules) {
1411
+ switch (LazyLoaderService.config.componentResolveStrategy) {
1412
+ case ComponentResolveStrategy.PickFirst: {
1413
+ return modules[0];
1414
+ }
1415
+ // Exact id -> classname match
1416
+ case ComponentResolveStrategy.MatchIdToClassName: {
1417
+ const matches = modules
1418
+ .filter(k => k.name == id);
1419
+ if (matches.length == 0)
1420
+ return null;
1421
+ return matches[0];
1422
+ }
1423
+ // Fuzzy id -> classname match
1424
+ case ComponentResolveStrategy.FuzzyIdClassName: {
1425
+ const _id = id.replace(/[^a-z0-9_\-]/ig, '');
1426
+ if (_id.length == 0) {
1427
+ LazyLoaderService.config.logger.err("Fuzzy classname matching stripped all symbols from the ID specified!");
1428
+ return false;
1429
+ }
1430
+ const rx = new RegExp(`^${id}(component|module)?$`, "i");
1431
+ const matches = modules
1432
+ .filter(mod => {
1433
+ let kid = mod.name.replace(/[^a-z0-9_\-]/ig, '');
1434
+ return rx.test(kid);
1435
+ });
1436
+ if (matches.length > 1) {
1437
+ LazyLoaderService.config.logger.err("Fuzzy classname matching resolved multiple targets!");
1438
+ return false;
1439
+ }
1440
+ if (matches.length == 0) {
1441
+ LazyLoaderService.config.logger.err("Fuzzy classname matching resolved no targets!");
1442
+ return null;
1443
+ }
1444
+ return matches[0];
1445
+ }
1446
+ case ComponentResolveStrategy.Custom: {
1447
+ return LazyLoaderService.config.customResolver(modules);
1448
+ }
1449
+ default: {
1450
+ return false;
1451
+ }
1452
+ }
1453
+ }
1454
+ }
1455
+ // A proxied registry that mutates reference keys
1456
+ LazyLoaderService.registry = {};
1457
+ LazyLoaderService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: LazyLoaderService, deps: [{ token: NGX_LAZY_LOADER_CONFIG }], target: i0.ɵɵFactoryTarget.Injectable });
1458
+ LazyLoaderService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: LazyLoaderService, providedIn: 'root' });
1459
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: LazyLoaderService, decorators: [{
1460
+ type: Injectable,
1461
+ args: [{
1462
+ providedIn: 'root'
1463
+ }]
1464
+ }], ctorParameters: function () {
1465
+ return [{ type: undefined, decorators: [{
1466
+ type: Inject,
1467
+ args: [NGX_LAZY_LOADER_CONFIG]
1468
+ }] }];
1469
+ } });
1470
+
1471
+ class LazyLoaderComponent {
1472
+ /**
1473
+ * The id of the component that will be lazy loaded
1474
+ */
1475
+ set id(data) {
1476
+ const id = stringToSlug(data);
1477
+ // Check if there is a change to the loaded component's id
1478
+ // if it's updated, we destroy and rehydrate the entire container
1479
+ if (this.initialized && this._id != id) {
1480
+ this._id = id;
1481
+ this.ngAfterViewInit();
1482
+ }
1483
+ else {
1484
+ this._id = id;
1485
+ }
1486
+ }
1487
+ ;
1488
+ set group(data) {
1489
+ const group = stringToSlug(data);
1490
+ if (typeof group != "string" || !group)
1491
+ return;
1492
+ // If the group was updated, retry to bootstrap something into the container.
1493
+ if (this.initialized && this._group != group) {
1494
+ this._group = group;
1495
+ this.ngAfterViewInit();
1496
+ return;
1497
+ }
1498
+ this._group = group;
1499
+ }
1500
+ get group() { return this._group; }
1501
+ /**
1502
+ * A map of inputs to bind to the child.
1503
+ * Supports change detection. (May fail on deep JSON changes)
1504
+ *
1505
+ * ```html
1506
+ * <lazy-loader component="MyLazyComponent"
1507
+ * [inputs]="{
1508
+ * prop1: true,
1509
+ * prop2: false,
1510
+ * complex: {
1511
+ * a: true,
1512
+ * b: 0
1513
+ * }
1514
+ * }"
1515
+ * >
1516
+ * </lazy-loader>
1517
+ * ```
1518
+ */
1519
+ set inputs(data) {
1520
+ if (data == undefined)
1521
+ return;
1522
+ let previous = this._inputs;
1523
+ this._inputs = data;
1524
+ if (data == undefined)
1525
+ console.trace(data);
1526
+ if (this.targetComponentFactory) {
1527
+ const { inputs } = this.targetComponentFactory.ɵcmp;
1528
+ const currentKeys = Object.keys(inputs);
1529
+ const oldKeys = Object.keys(previous).filter(key => currentKeys.includes(key));
1530
+ const newKeys = Object.keys(data).filter(key => currentKeys.includes(key));
1531
+ const removed = oldKeys.filter(key => !newKeys.includes(key));
1532
+ // ? perhaps set to null or undefined instead
1533
+ removed.forEach(k => this.targetComponentInstance[k] = null);
1534
+ this.bindInputs();
1535
+ }
1536
+ }
1537
+ /**
1538
+ * A map of outputs to bind from the child.
1539
+ * Should support change detection.
1540
+ * ```html
1541
+ * <lazy-loader component="MyLazyComponent"
1542
+ * [outputs]="{
1543
+ * prop3: onOutputFire
1544
+ * }"
1545
+ * >
1546
+ * </lazy-loader>
1547
+ * ```
1548
+ */
1549
+ set outputs(data) {
1550
+ let previous = this._outputs;
1551
+ this._outputs = data;
1552
+ if (this.targetComponentFactory) {
1553
+ const { inputs } = this.targetComponentFactory.ɵcmp;
1554
+ const currentKeys = Object.keys(inputs);
1555
+ const removed = Object.keys(previous).filter(key => !currentKeys.includes(key));
1556
+ removed.forEach(k => {
1557
+ var _a;
1558
+ // Unsubscribe from observable
1559
+ (_a = this.outputSubscriptions[k]) === null || _a === void 0 ? void 0 : _a.unsubscribe();
1560
+ delete this.targetComponentInstance[k];
1561
+ });
1562
+ this.bindOutputs();
1563
+ }
1564
+ }
1565
+ constructor(service, viewContainerRef, dialog, dialogArguments) {
1566
+ this.service = service;
1567
+ this.viewContainerRef = viewContainerRef;
1568
+ this.dialog = dialog;
1569
+ this.dialogArguments = dialogArguments;
1570
+ this._group = "default";
1571
+ this.outputSubscriptions = {};
1572
+ /**
1573
+ * Emits errors encountered when loading components
1574
+ */
1575
+ this.componentLoadError = new EventEmitter();
1576
+ /**
1577
+ * Emits when the component is fully constructed
1578
+ * and had it's inputs and outputs bound
1579
+ * > before `OnInit`
1580
+ *
1581
+ * Returns the active class instance of the lazy-loaded component
1582
+ */
1583
+ this.componentLoaded = new EventEmitter();
1584
+ // Force 500ms delay before revealing the spinner
1585
+ this.loaderEmitter = new EventEmitter();
1586
+ this.clearLoader$ = this.loaderEmitter.pipe(debounceTime(300));
1587
+ this.showLoader = true; // whether we render the DOM for the spinner
1588
+ this.isClearingLoader = false; // should the spinner start fading out
1589
+ this.initialized = false;
1590
+ this.config = LazyLoaderService.config;
1591
+ this.err = LazyLoaderService.config.logger.err;
1592
+ this.warn = LazyLoaderService.config.logger.warn;
1593
+ this.log = LazyLoaderService.config.logger.log;
1594
+ // First, check for dialog arguments
1595
+ if (this.dialogArguments) {
1596
+ this.inputs = this.dialogArguments.inputs || this.dialogArguments.data;
1597
+ this.outputs = this.dialogArguments.outputs;
1598
+ this.id = this.dialogArguments.id;
1599
+ this.group = this.dialogArguments.group;
1600
+ }
1601
+ this.loaderSub = this.clearLoader$.subscribe(() => {
1602
+ this.showLoader = false;
1603
+ });
1604
+ }
1605
+ ngAfterViewInit() {
1606
+ return __awaiter(this, void 0, void 0, function* () {
1607
+ this.ngOnDestroy(false);
1608
+ this.isClearingLoader = false;
1609
+ this.showLoader = true;
1610
+ this.initialized = true;
1611
+ if (!this._id) {
1612
+ this.warn("No component was specified!");
1613
+ return this.loadDefault();
1614
+ }
1615
+ try {
1616
+ const _entry = this.service.resolveRegistrationEntry(this._id, this._group);
1617
+ if (!_entry || !_entry.entry) {
1618
+ this.err(`Failed to find Component '${this._id}' in group '${this._group}' in registry!`);
1619
+ return this.loadDefault();
1620
+ }
1621
+ const { entry, matchGroups } = _entry;
1622
+ this._matchGroups = matchGroups;
1623
+ // Download the "module" (the standalone component)
1624
+ const bundle = this.targetModule = yield entry.load();
1625
+ // Check if there is some corruption on the bundle.
1626
+ if (!bundle || typeof bundle != 'object' || bundle['__esModule'] !== true || bundle.toString() != "[object Module]") {
1627
+ this.err(`Failed to load component/module for '${this._id}'! Parsed resource is invalid.`);
1628
+ return this.loadError();
1629
+ }
1630
+ const modules = Object.keys(bundle)
1631
+ .map(k => {
1632
+ const entry = bundle[k];
1633
+ // Strictly check for exported modules or standalone components
1634
+ if (typeof entry == "function" && typeof entry["ɵfac"] == "function")
1635
+ return entry;
1636
+ return null;
1637
+ })
1638
+ .filter(e => e != null)
1639
+ .filter(entry => {
1640
+ entry['_isModule'] = !!entry['ɵmod']; // module
1641
+ entry['_isComponent'] = !!entry['ɵcmp']; // component
1642
+ return (entry['_isModule'] || entry['_isComponent']);
1643
+ });
1644
+ if (modules.length == 0) {
1645
+ this.err(`Component/Module loaded for '${this._id}' has no exported components or modules!`);
1646
+ return this.loadError();
1647
+ }
1648
+ const component = this.targetComponentFactory = this.service.resolveComponent(this._id, "default", modules);
1649
+ if (!component) {
1650
+ this.err(`Component '${this._id}' is invalid or corrupted!`);
1651
+ return this.loadError();
1652
+ }
1653
+ // Bootstrap the component into the container
1654
+ const componentRef = this.targetComponentContainerRef = this.targetContainer.createComponent(component);
1655
+ this.targetRef = this.targetContainer.insert(this.targetComponentContainerRef.hostView);
1656
+ const instance = this.targetComponentInstance = componentRef['instance'];
1657
+ this.bindInputs();
1658
+ this.bindOutputs();
1659
+ this.componentLoaded.next(instance);
1660
+ this.instance = instance;
1661
+ // Look for an observable called isLoading$ that will make us show/hide
1662
+ // the same distractor that is used on basic loading
1663
+ const isLoading$ = instance['ngxShowDistractor$'];
1664
+ if (isLoading$ && typeof isLoading$.subscribe == "function") {
1665
+ this.distractorSubscription = isLoading$.subscribe(loading => {
1666
+ if (!loading) {
1667
+ this.isClearingLoader = true;
1668
+ this.loaderEmitter.emit();
1669
+ }
1670
+ else {
1671
+ this.showLoader = true;
1672
+ this.isClearingLoader = false;
1673
+ }
1674
+ });
1675
+ }
1676
+ else {
1677
+ this.isClearingLoader = true;
1678
+ }
1679
+ const name = Object.keys(bundle)[0];
1680
+ this.log(`Loaded '${name}'`);
1681
+ this.loaderEmitter.emit();
1682
+ return componentRef;
1683
+ }
1684
+ catch (ex) {
1685
+ if (isDevMode()) {
1686
+ console.warn("Component " + this._id + " threw an error on mount!");
1687
+ console.warn("This will cause you to see a 404 panel.");
1688
+ console.error(ex);
1689
+ }
1690
+ // Network errors throw a toast and return an error component
1691
+ if (ex && !isDevMode()) {
1692
+ console.error("Uncaught error when loading component");
1693
+ throw ex;
1694
+ }
1695
+ return this.loadDefault();
1696
+ }
1697
+ });
1698
+ }
1699
+ ngOnDestroy(clearAll = true) {
1700
+ var _a, _b, _c, _d, _e;
1701
+ // unsubscribe from all subscriptions
1702
+ Object.entries(this.outputSubscriptions).forEach(([key, sub]) => {
1703
+ sub.unsubscribe();
1704
+ });
1705
+ this.outputSubscriptions = {};
1706
+ // Clear all things
1707
+ if (clearAll) {
1708
+ (_a = this.loaderSub) === null || _a === void 0 ? void 0 : _a.unsubscribe();
1709
+ }
1710
+ (_b = this.distractorSubscription) === null || _b === void 0 ? void 0 : _b.unsubscribe();
1711
+ // Clear target container
1712
+ (_c = this.targetRef) === null || _c === void 0 ? void 0 : _c.destroy();
1713
+ (_d = this.targetComponentContainerRef) === null || _d === void 0 ? void 0 : _d.destroy();
1714
+ (_e = this.targetContainer) === null || _e === void 0 ? void 0 : _e.clear();
1715
+ // Wipe the rest of the state clean
1716
+ this.targetRef = null;
1717
+ this.targetComponentContainerRef = null;
1718
+ }
1719
+ /**
1720
+ * Bind the input values to the child component.
1721
+ */
1722
+ bindInputs() {
1723
+ if (!this._inputs || !this.targetComponentInstance)
1724
+ return;
1725
+ // Merge match groups
1726
+ if (typeof this._matchGroups == "object") {
1727
+ Object.entries(this._matchGroups).forEach(([key, val]) => {
1728
+ if (typeof this._inputs[key] == 'undefined')
1729
+ this._inputs[key] = val;
1730
+ });
1731
+ }
1732
+ // forward-bind inputs
1733
+ const { inputs } = this.targetComponentFactory.ɵcmp;
1734
+ // Returns a list of entries that need to be set
1735
+ // This makes it so that unnecessary setters are not invoked.
1736
+ const updated = Object.entries(inputs).filter(([parentKey, childKey]) => {
1737
+ return this.targetComponentInstance[childKey] != this._inputs[parentKey];
1738
+ });
1739
+ updated.forEach(([parentKey, childKey]) => {
1740
+ if (this._inputs.hasOwnProperty(parentKey))
1741
+ this.targetComponentInstance[childKey] = this._inputs[parentKey];
1742
+ });
1743
+ }
1744
+ /**
1745
+ * Bind the output handlers to the loaded child component
1746
+ */
1747
+ bindOutputs() {
1748
+ if (!this._outputs || !this.targetComponentInstance)
1749
+ return;
1750
+ const { outputs } = this.targetComponentFactory.ɵcmp;
1751
+ // Get a list of unregistered outputs
1752
+ const newOutputs = Object.entries(outputs).filter(([parentKey, childKey]) => {
1753
+ return !this.outputSubscriptions[parentKey];
1754
+ });
1755
+ // Reverse bind via subscription
1756
+ newOutputs.forEach(([parentKey, childKey]) => {
1757
+ if (this._outputs.hasOwnProperty(parentKey)) {
1758
+ const target = this.targetComponentInstance[childKey];
1759
+ const outputs = this._outputs;
1760
+ // Angular folks, stop making this so difficult.
1761
+ const ctx = this.viewContainerRef['_hostLView'][8];
1762
+ const sub = target.subscribe(outputs[parentKey].bind(ctx)); // Subscription
1763
+ this.outputSubscriptions[parentKey] = sub;
1764
+ }
1765
+ });
1766
+ }
1767
+ /**
1768
+ * Load the "Default" component (404) screen normally.
1769
+ * This is shown when the component id isn't in the
1770
+ * registry or otherwise doesn't match
1771
+ *
1772
+ * This
1773
+ */
1774
+ loadDefault() {
1775
+ if (this.config.notFoundComponent)
1776
+ this.targetContainer.createComponent(this.config.notFoundComponent);
1777
+ this.showLoader = false;
1778
+ }
1779
+ /**
1780
+ * Load the "Error" component.
1781
+ * This is shown when we are able to resolve the component
1782
+ * in the registry, but have some issue boostrapping the
1783
+ * component into the viewContainer
1784
+ */
1785
+ loadError() {
1786
+ if (this.config.errorComponent)
1787
+ this.targetContainer.createComponent(this.config.errorComponent);
1788
+ this.showLoader = false;
1789
+ }
1790
+ }
1791
+ LazyLoaderComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: LazyLoaderComponent, deps: [{ token: LazyLoaderService }, { token: i0.ViewContainerRef, optional: true }, { token: i2$2.DialogRef, optional: true }, { token: MAT_DIALOG_DATA, optional: true }], target: i0.ɵɵFactoryTarget.Component });
1792
+ LazyLoaderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.9", type: LazyLoaderComponent, isStandalone: true, selector: "ngx-lazy-loader", inputs: { id: ["component", "id"], group: "group", inputs: "inputs", outputs: "outputs" }, outputs: { componentLoadError: "componentLoadError", componentLoaded: "componentLoaded" }, viewQueries: [{ propertyName: "targetContainer", first: true, predicate: ["content"], descendants: true, read: ViewContainerRef }], ngImport: i0, template: "<ng-container #content></ng-container>\n\n<div class=\"ngx-lazy-loader-distractor\" [class.destroying]=\"isClearingLoader\">\n <ng-container *ngIf=\"config.loaderDistractorComponent\" [ngComponentOutlet]=\"config.loaderDistractorComponent\"></ng-container>\n <ng-container *ngIf=\"config.loaderDistractorTemplate\" [ngTemplateOutlet]=\"config.loaderDistractorTemplate\" [ngTemplateOutletContext]=\"{ '$implicit': inputs }\"></ng-container>\n</div>\n", styles: [":host{display:contents;contain:content;z-index:1;position:relative}.ngx-lazy-loader-distractor{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;flex-direction:column;background-color:var(--background-color, #212121);opacity:1;transition:opacity .3s ease;z-index:999999}.ngx-lazy-loader-distractor.destroying{opacity:0;pointer-events:none}\n"], dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
1793
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: LazyLoaderComponent, decorators: [{
1794
+ type: Component,
1795
+ args: [{ selector: 'ngx-lazy-loader', imports: [NgIf, NgComponentOutlet, NgTemplateOutlet], standalone: true, template: "<ng-container #content></ng-container>\n\n<div class=\"ngx-lazy-loader-distractor\" [class.destroying]=\"isClearingLoader\">\n <ng-container *ngIf=\"config.loaderDistractorComponent\" [ngComponentOutlet]=\"config.loaderDistractorComponent\"></ng-container>\n <ng-container *ngIf=\"config.loaderDistractorTemplate\" [ngTemplateOutlet]=\"config.loaderDistractorTemplate\" [ngTemplateOutletContext]=\"{ '$implicit': inputs }\"></ng-container>\n</div>\n", styles: [":host{display:contents;contain:content;z-index:1;position:relative}.ngx-lazy-loader-distractor{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;flex-direction:column;background-color:var(--background-color, #212121);opacity:1;transition:opacity .3s ease;z-index:999999}.ngx-lazy-loader-distractor.destroying{opacity:0;pointer-events:none}\n"] }]
1796
+ }], ctorParameters: function () {
1797
+ return [{ type: LazyLoaderService }, { type: i0.ViewContainerRef, decorators: [{
1798
+ type: Optional
1799
+ }] }, { type: i2$2.DialogRef, decorators: [{
1800
+ type: Optional
1801
+ }] }, { type: undefined, decorators: [{
1802
+ type: Optional
1803
+ }, {
1804
+ type: Inject,
1805
+ args: [MAT_DIALOG_DATA]
1806
+ }] }];
1807
+ }, propDecorators: { targetContainer: [{
1808
+ type: ViewChild,
1809
+ args: ["content", { read: ViewContainerRef }]
1810
+ }], id: [{
1811
+ type: Input,
1812
+ args: ["component"]
1813
+ }], group: [{
1814
+ type: Input,
1815
+ args: ["group"]
1816
+ }], inputs: [{
1817
+ type: Input,
1818
+ args: ["inputs"]
1819
+ }], outputs: [{
1820
+ type: Input,
1821
+ args: ["outputs"]
1822
+ }], componentLoadError: [{
1823
+ type: Output
1824
+ }], componentLoaded: [{
1825
+ type: Output
1826
+ }] } });
1827
+
1828
+ class LazyLoaderModule {
1829
+ static forRoot(config) {
1830
+ return ({
1831
+ ngModule: LazyLoaderModule,
1832
+ providers: [
1833
+ LazyLoaderService,
1834
+ {
1835
+ provide: NGX_LAZY_LOADER_CONFIG,
1836
+ useValue: config
1837
+ }
1838
+ ]
1839
+ });
1840
+ }
1841
+ }
1842
+ LazyLoaderModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: LazyLoaderModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1843
+ LazyLoaderModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.9", ngImport: i0, type: LazyLoaderModule, imports: [LazyLoaderComponent], exports: [LazyLoaderComponent] });
1844
+ LazyLoaderModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: LazyLoaderModule, imports: [LazyLoaderComponent] });
1845
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: LazyLoaderModule, decorators: [{
1846
+ type: NgModule,
1847
+ args: [{
1848
+ imports: [LazyLoaderComponent],
1849
+ exports: [LazyLoaderComponent]
1850
+ }]
1851
+ }] });
1852
+
1853
+ class OnMount {
1854
+ }
1855
+ class DynamicHTMLOptions {
1856
+ }
1857
+ const NGX_DYNAMIC_CONFIG = new InjectionToken('config');
1858
+
1859
+ function isBrowserPlatform() {
1860
+ return window != null && window.document != null;
1861
+ }
1862
+ class DynamicHTMLRenderer {
1863
+ constructor(config, cfr, injector) {
1864
+ this.config = config;
1865
+ this.cfr = cfr;
1866
+ this.injector = injector;
1867
+ this.componentFactories = new Map();
1868
+ this.componentRefs = new Map();
1869
+ this.config.components.forEach(({ selector, component }) => {
1870
+ let cf;
1871
+ cf = this.cfr.resolveComponentFactory(component);
1872
+ this.componentFactories.set(selector, cf);
1873
+ });
1874
+ }
1875
+ renderInnerHTML(elementRef, html) {
1876
+ if (!isBrowserPlatform()) {
1877
+ return {
1878
+ check: () => { },
1879
+ destroy: () => { },
1880
+ };
1881
+ }
1882
+ elementRef.nativeElement.innerHTML = html;
1883
+ const componentRefs = [];
1884
+ this.config.components.forEach(({ selector }) => {
1885
+ const elements = elementRef.nativeElement.querySelectorAll(selector);
1886
+ Array.prototype.forEach.call(elements, (el) => {
1887
+ const content = el.innerHTML;
1888
+ const cmpRef = this.componentFactories.get(selector).create(this.injector, [], el);
1889
+ el.removeAttribute('ng-version');
1890
+ if (cmpRef.instance.dynamicOnMount) {
1891
+ const attrsMap = new Map();
1892
+ if (el.hasAttributes()) {
1893
+ Array.prototype.forEach.call(el.attributes, (attr) => {
1894
+ attrsMap.set(attr.name, attr.value);
1895
+ });
1896
+ }
1897
+ cmpRef.instance.dynamicOnMount(attrsMap, content, el);
1898
+ }
1899
+ componentRefs.push(cmpRef);
1900
+ });
1901
+ });
1902
+ this.componentRefs.set(elementRef, componentRefs);
1903
+ return {
1904
+ check: () => componentRefs.forEach(ref => ref.changeDetectorRef.detectChanges()),
1905
+ destroy: () => {
1906
+ componentRefs.forEach(ref => ref.destroy());
1907
+ this.componentRefs.delete(elementRef);
1908
+ },
1909
+ };
1910
+ }
1911
+ }
1912
+ DynamicHTMLRenderer.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: DynamicHTMLRenderer, deps: [{ token: NGX_DYNAMIC_CONFIG }, { token: i0.ComponentFactoryResolver }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable });
1913
+ DynamicHTMLRenderer.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: DynamicHTMLRenderer });
1914
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: DynamicHTMLRenderer, decorators: [{
1915
+ type: Injectable
1916
+ }], ctorParameters: function () {
1917
+ return [{ type: DynamicHTMLOptions, decorators: [{
1918
+ type: Inject,
1919
+ args: [NGX_DYNAMIC_CONFIG]
1920
+ }] }, { type: i0.ComponentFactoryResolver }, { type: i0.Injector }];
1921
+ } });
1922
+
1923
+ class DynamicHTMLComponent {
1924
+ constructor(renderer, elementRef) {
1925
+ this.renderer = renderer;
1926
+ this.elementRef = elementRef;
1927
+ this.ref = null;
1928
+ }
1929
+ ngOnChanges(_) {
1930
+ if (this.ref) {
1931
+ this.ref.destroy();
1932
+ this.ref = null;
1933
+ }
1934
+ if (this.content && this.elementRef) {
1935
+ this.ref = this.renderer.renderInnerHTML(this.elementRef, this.content);
1936
+ }
1937
+ }
1938
+ ngDoCheck() {
1939
+ if (this.ref) {
1940
+ this.ref.check();
1941
+ }
1942
+ }
1943
+ ngOnDestroy() {
1944
+ if (this.ref) {
1945
+ this.ref.destroy();
1946
+ this.ref = null;
1947
+ }
1948
+ }
1949
+ }
1950
+ DynamicHTMLComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: DynamicHTMLComponent, deps: [{ token: DynamicHTMLRenderer }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
1951
+ DynamicHTMLComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.9", type: DynamicHTMLComponent, isStandalone: true, selector: "dynamic-html", inputs: { content: "content" }, usesOnChanges: true, ngImport: i0, template: '', isInline: true });
1952
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: DynamicHTMLComponent, decorators: [{
1953
+ type: Component,
1954
+ args: [{
1955
+ selector: 'dynamic-html',
1956
+ template: '',
1957
+ standalone: true
1958
+ }]
1959
+ }], ctorParameters: function () { return [{ type: DynamicHTMLRenderer }, { type: i0.ElementRef }]; }, propDecorators: { content: [{
1960
+ type: Input
1961
+ }] } });
1962
+
1963
+ class NgxDynamicHTMLModule {
1964
+ static forRoot(config) {
1965
+ return {
1966
+ ngModule: NgxDynamicHTMLModule,
1967
+ providers: [
1968
+ DynamicHTMLRenderer,
1969
+ { provide: NGX_DYNAMIC_CONFIG, useValue: config }
1970
+ ],
1971
+ };
1972
+ }
1973
+ }
1974
+ NgxDynamicHTMLModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: NgxDynamicHTMLModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1975
+ NgxDynamicHTMLModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.9", ngImport: i0, type: NgxDynamicHTMLModule, imports: [DynamicHTMLComponent], exports: [DynamicHTMLComponent] });
1976
+ NgxDynamicHTMLModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: NgxDynamicHTMLModule, imports: [DynamicHTMLComponent] });
1977
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: NgxDynamicHTMLModule, decorators: [{
1978
+ type: NgModule,
1979
+ args: [{
1980
+ imports: [DynamicHTMLComponent],
1981
+ exports: [DynamicHTMLComponent],
1982
+ }]
1983
+ }] });
1984
+
1985
+ /*
1986
+ * Public API Surface of package
1987
+ */
1988
+ /**
1989
+ ** Directives
1990
+ */
1991
+
1992
+ /**
1993
+ * Generated bundle index. Do not edit.
1994
+ */
1995
+
1996
+ export { ComponentResolveStrategy, DependencyService, DialogService, DynamicHTMLComponent, DynamicHTMLOptions, DynamicHTMLRenderer, Fetch, HtmlBypass, KeyboardService, LazyLoaderComponent, LazyLoaderModule, LazyLoaderService, MenuDirective, NGX_DYNAMIC_CONFIG, NGX_LAZY_LOADER_CONFIG, NgxDynamicHTMLModule, OnMount, ResourceBypass, ScriptBypass, StyleBypass, TooltipDirective, UrlBypass, openMenu, openTooltip };
1997
+ //# sourceMappingURL=dotglitch-ngx-common.mjs.map