@memberjunction/ng-ui-components 6.1.0-edge.4 → 6.1.0-edge.6

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 (52) hide show
  1. package/README.md +9 -1
  2. package/dist/lib/alert/alert.component.d.ts.map +1 -1
  3. package/dist/lib/alert/alert.component.js +1 -1
  4. package/dist/lib/applied-filters/applied-filters.component.js +1 -1
  5. package/dist/lib/bottom-sheet/bottom-sheet.component.js +1 -1
  6. package/dist/lib/combobox/combobox.component.d.ts +32 -1
  7. package/dist/lib/combobox/combobox.component.d.ts.map +1 -1
  8. package/dist/lib/combobox/combobox.component.js +73 -28
  9. package/dist/lib/combobox/combobox.component.js.map +1 -1
  10. package/dist/lib/confirm-dialog/confirm-dialog.component.d.ts.map +1 -1
  11. package/dist/lib/datepicker/datepicker.component.d.ts +25 -1
  12. package/dist/lib/datepicker/datepicker.component.d.ts.map +1 -1
  13. package/dist/lib/datepicker/datepicker.component.js +59 -28
  14. package/dist/lib/datepicker/datepicker.component.js.map +1 -1
  15. package/dist/lib/dialog/dialog.component.js +1 -1
  16. package/dist/lib/dialog/dialog.component.js.map +1 -1
  17. package/dist/lib/dialog/dialog.service.js +15 -16
  18. package/dist/lib/dialog/dialog.service.js.map +1 -1
  19. package/dist/lib/dropdown/dropdown.component.d.ts +103 -3
  20. package/dist/lib/dropdown/dropdown.component.d.ts.map +1 -1
  21. package/dist/lib/dropdown/dropdown.component.js +208 -52
  22. package/dist/lib/dropdown/dropdown.component.js.map +1 -1
  23. package/dist/lib/dropdown/dropdown.scss +16 -0
  24. package/dist/lib/empty-state/empty-state.component.js +1 -1
  25. package/dist/lib/filter-popover/filter-popover.component.js +27 -28
  26. package/dist/lib/filter-popover/filter-popover.component.js.map +1 -1
  27. package/dist/lib/left-nav/left-nav-content.component.js +1 -1
  28. package/dist/lib/left-nav/left-nav.component.js +72 -73
  29. package/dist/lib/left-nav/left-nav.component.js.map +1 -1
  30. package/dist/lib/numeric-input/numeric-input.component.d.ts +22 -1
  31. package/dist/lib/numeric-input/numeric-input.component.d.ts.map +1 -1
  32. package/dist/lib/numeric-input/numeric-input.component.js +30 -3
  33. package/dist/lib/numeric-input/numeric-input.component.js.map +1 -1
  34. package/dist/lib/page-body/page-body.component.js +1 -1
  35. package/dist/lib/page-body-interior/page-body-interior.component.js +1 -1
  36. package/dist/lib/page-header/page-header.component.js +1 -1
  37. package/dist/lib/page-header-interior/page-header-interior.component.js +1 -1
  38. package/dist/lib/page-search/page-search.component.js +1 -1
  39. package/dist/lib/refresh-button/refresh-button.component.js +1 -1
  40. package/dist/lib/slide-panel/slide-panel.component.js +1 -1
  41. package/dist/lib/stat-badge/stat-badge.component.js +1 -1
  42. package/dist/lib/switch/switch.component.d.ts +22 -1
  43. package/dist/lib/switch/switch.component.d.ts.map +1 -1
  44. package/dist/lib/switch/switch.component.js +30 -3
  45. package/dist/lib/switch/switch.component.js.map +1 -1
  46. package/dist/lib/tab-nav/tab-nav.component.js +1 -1
  47. package/dist/lib/view-toggle/view-toggle.component.js +1 -1
  48. package/dist/lib/window/window.component.js +1 -1
  49. package/dist/lib/window/window.component.js.map +1 -1
  50. package/dist/lib/workspace-tabs/workspace-card.component.js +1 -1
  51. package/dist/lib/workspace-tabs/workspace-tab-strip.component.js +1 -1
  52. package/package.json +8 -8
@@ -9,10 +9,31 @@ export declare class MJNumericInputComponent implements ControlValueAccessor {
9
9
  Step: number;
10
10
  Format: string;
11
11
  Decimals: number | null;
12
- Disabled: boolean;
12
+ /**
13
+ * Host-driven disable. Composed with Angular Forms' `setDisabledState()` into `IsDisabled`
14
+ * (the actual gate) — see `syncDisabled`. A setter, not a bare field, because this input is
15
+ * routinely bound to an expression that changes over the control's lifetime, and the gate has
16
+ * to follow it every time.
17
+ */
18
+ set Disabled(value: boolean);
19
+ get Disabled(): boolean;
13
20
  Placeholder: string;
14
21
  readonly hostClass = true;
22
+ /** The rendered `[disabled]` state — true when EITHER source says so. Assign via `syncDisabled()`. */
15
23
  IsDisabled: boolean;
24
+ private disabledInput;
25
+ private formDisabled;
26
+ private cdr;
27
+ /**
28
+ * Recompute the gate from both of its sources. Called whenever either one changes.
29
+ *
30
+ * `IsDisabled` is derived state, and the only thing that assigned it was `setDisabledState()`.
31
+ * The forms-driven half was in fact fine — `setUpControl` also wires `registerOnDisabledChange`,
32
+ * so that hook fires on every `control.disable()`/`enable()`, not just at registration. What had
33
+ * no recompute path at all was the `Disabled` @Input: a plain field, so the gate froze at
34
+ * whatever the first compose produced and every later change to the input was dropped.
35
+ */
36
+ private syncDisabled;
16
37
  DisplayValue: string | number;
17
38
  private internalValue;
18
39
  private onChange;
@@ -1 +1 @@
1
- {"version":3,"file":"numeric-input.component.d.ts","sourceRoot":"","sources":["../../../src/lib/numeric-input/numeric-input.component.ts"],"names":[],"mappings":"AACA,OAAO,EAAqB,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;;AAEzE;;GAEG;AACH,qBAYa,uBAAwB,YAAW,oBAAoB;IACzD,GAAG,EAAE,MAAM,GAAG,IAAI,CAAQ;IAC1B,GAAG,EAAE,MAAM,GAAG,IAAI,CAAQ;IAC1B,IAAI,EAAE,MAAM,CAAK;IACjB,MAAM,EAAE,MAAM,CAAM;IACpB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IAC/B,QAAQ,UAAS;IACjB,WAAW,SAAM;IACkB,QAAQ,CAAC,SAAS,QAAQ;IAEtE,UAAU,UAAS;IACnB,YAAY,EAAE,MAAM,GAAG,MAAM,CAAM;IACnC,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,QAAQ,CAA4C;IAC5D,OAAO,CAAC,SAAS,CAAwB;IAEzC,OAAO,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAU3B,MAAM,IAAI,IAAI;IAEd,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IACtC,gBAAgB,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,GAAG,IAAI;IAC1D,iBAAiB,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,IAAI;IACvC,gBAAgB,CAAC,UAAU,EAAE,OAAO,GAAG,IAAI;IAE3C,OAAO,CAAC,KAAK;IAOb,OAAO,CAAC,aAAa;yCAxCV,uBAAuB;2CAAvB,uBAAuB;CA4CnC"}
1
+ {"version":3,"file":"numeric-input.component.d.ts","sourceRoot":"","sources":["../../../src/lib/numeric-input/numeric-input.component.ts"],"names":[],"mappings":"AACA,OAAO,EAAqB,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;;AAEzE;;GAEG;AACH,qBAYa,uBAAwB,YAAW,oBAAoB;IACzD,GAAG,EAAE,MAAM,GAAG,IAAI,CAAQ;IAC1B,GAAG,EAAE,MAAM,GAAG,IAAI,CAAQ;IAC1B,IAAI,EAAE,MAAM,CAAK;IACjB,MAAM,EAAE,MAAM,CAAM;IACpB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IACxC;;;;;OAKG;IACH,IACI,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAsD;IACjF,IAAI,QAAQ,IAAI,OAAO,CAA+B;IAC7C,WAAW,SAAM;IACkB,QAAQ,CAAC,SAAS,QAAQ;IAEtE,sGAAsG;IACtG,UAAU,UAAS;IACnB,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,GAAG,CAA6B;IAExC;;;;;;;;OAQG;IACH,OAAO,CAAC,YAAY;IAOpB,YAAY,EAAE,MAAM,GAAG,MAAM,CAAM;IACnC,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,QAAQ,CAA4C;IAC5D,OAAO,CAAC,SAAS,CAAwB;IAEzC,OAAO,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAU3B,MAAM,IAAI,IAAI;IAEd,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IACtC,gBAAgB,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,GAAG,IAAI;IAC1D,iBAAiB,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,IAAI;IACvC,gBAAgB,CAAC,UAAU,EAAE,OAAO,GAAG,IAAI;IAE3C,OAAO,CAAC,KAAK;IAOb,OAAO,CAAC,aAAa;yCArEV,uBAAuB;2CAAvB,uBAAuB;CAyEnC"}
@@ -1,4 +1,4 @@
1
- import { Component, Input, forwardRef, HostBinding } from '@angular/core';
1
+ import { Component, Input, forwardRef, HostBinding, ChangeDetectorRef, inject } from '@angular/core';
2
2
  import { NG_VALUE_ACCESSOR } from '@angular/forms';
3
3
  import * as i0 from "@angular/core";
4
4
  /**
@@ -10,10 +10,37 @@ export class MJNumericInputComponent {
10
10
  Step = 1;
11
11
  Format = '';
12
12
  Decimals = null;
13
- Disabled = false;
13
+ /**
14
+ * Host-driven disable. Composed with Angular Forms' `setDisabledState()` into `IsDisabled`
15
+ * (the actual gate) — see `syncDisabled`. A setter, not a bare field, because this input is
16
+ * routinely bound to an expression that changes over the control's lifetime, and the gate has
17
+ * to follow it every time.
18
+ */
19
+ set Disabled(value) { this.disabledInput = value; this.syncDisabled(); }
20
+ get Disabled() { return this.disabledInput; }
14
21
  Placeholder = '';
15
22
  hostClass = true;
23
+ /** The rendered `[disabled]` state — true when EITHER source says so. Assign via `syncDisabled()`. */
16
24
  IsDisabled = false;
25
+ disabledInput = false;
26
+ formDisabled = false;
27
+ cdr = inject(ChangeDetectorRef);
28
+ /**
29
+ * Recompute the gate from both of its sources. Called whenever either one changes.
30
+ *
31
+ * `IsDisabled` is derived state, and the only thing that assigned it was `setDisabledState()`.
32
+ * The forms-driven half was in fact fine — `setUpControl` also wires `registerOnDisabledChange`,
33
+ * so that hook fires on every `control.disable()`/`enable()`, not just at registration. What had
34
+ * no recompute path at all was the `Disabled` @Input: a plain field, so the gate froze at
35
+ * whatever the first compose produced and every later change to the input was dropped.
36
+ */
37
+ syncDisabled() {
38
+ const disabled = this.disabledInput || this.formDisabled;
39
+ if (disabled === this.IsDisabled)
40
+ return;
41
+ this.IsDisabled = disabled;
42
+ this.cdr.markForCheck();
43
+ }
17
44
  DisplayValue = '';
18
45
  internalValue = null;
19
46
  onChange = () => { };
@@ -36,7 +63,7 @@ export class MJNumericInputComponent {
36
63
  writeValue(value) { this.internalValue = value; this.formatDisplay(); }
37
64
  registerOnChange(fn) { this.onChange = fn; }
38
65
  registerOnTouched(fn) { this.onTouched = fn; }
39
- setDisabledState(isDisabled) { this.IsDisabled = isDisabled || this.Disabled; }
66
+ setDisabledState(isDisabled) { this.formDisabled = isDisabled; this.syncDisabled(); }
40
67
  clamp(value) {
41
68
  if (this.Min != null && value < this.Min)
42
69
  return this.Min;
@@ -1 +1 @@
1
- {"version":3,"file":"numeric-input.component.js","sourceRoot":"","sources":["../../../src/lib/numeric-input/numeric-input.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, forwardRef, HostBinding } from '@angular/core';\nimport { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';\n\n/**\n * mj-numeric-input — Numeric input with min/max/step. Replaces `<kendo-numerictextbox>`.\n */\n@Component({\n selector: 'mj-numeric-input',\n standalone: true,\n template: `\n <input type=\"number\" class=\"mj-input mj-numeric-input\"\n [attr.min]=\"Min\" [attr.max]=\"Max\" [attr.step]=\"Step\"\n [attr.placeholder]=\"Placeholder\" [disabled]=\"IsDisabled\"\n [value]=\"DisplayValue\"\n (input)=\"OnInput($event)\" (blur)=\"OnBlur()\" />\n `,\n providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => MJNumericInputComponent), multi: true }]\n})\nexport class MJNumericInputComponent implements ControlValueAccessor {\n @Input() Min: number | null = null;\n @Input() Max: number | null = null;\n @Input() Step: number = 1;\n @Input() Format: string = '';\n @Input() Decimals: number | null = null;\n @Input() Disabled = false;\n @Input() Placeholder = '';\n @HostBinding('class.mj-numeric-input-host') readonly hostClass = true;\n\n IsDisabled = false;\n DisplayValue: string | number = '';\n private internalValue: number | null = null;\n private onChange: (value: number | null) => void = () => {};\n private onTouched: () => void = () => {};\n\n OnInput(event: Event): void {\n const raw = (event.target as HTMLInputElement).value;\n if (raw === '' || raw === '-') { this.internalValue = null; this.onChange(null); return; }\n let num = parseFloat(raw);\n if (isNaN(num)) return;\n num = this.clamp(num);\n this.internalValue = num;\n this.onChange(num);\n }\n\n OnBlur(): void { this.onTouched(); this.formatDisplay(); }\n\n writeValue(value: number | null): void { this.internalValue = value; this.formatDisplay(); }\n registerOnChange(fn: (value: number | null) => void): void { this.onChange = fn; }\n registerOnTouched(fn: () => void): void { this.onTouched = fn; }\n setDisabledState(isDisabled: boolean): void { this.IsDisabled = isDisabled || this.Disabled; }\n\n private clamp(value: number): number {\n if (this.Min != null && value < this.Min) return this.Min;\n if (this.Max != null && value > this.Max) return this.Max;\n if (this.Decimals != null) { const f = Math.pow(10, this.Decimals); return Math.round(value * f) / f; }\n return value;\n }\n\n private formatDisplay(): void {\n if (this.internalValue == null) { this.DisplayValue = ''; return; }\n this.DisplayValue = this.Decimals != null ? this.internalValue.toFixed(this.Decimals) : this.internalValue;\n }\n}\n"]}
1
+ {"version":3,"file":"numeric-input.component.js","sourceRoot":"","sources":["../../../src/lib/numeric-input/numeric-input.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, forwardRef, HostBinding, ChangeDetectorRef, inject } from '@angular/core';\nimport { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';\n\n/**\n * mj-numeric-input — Numeric input with min/max/step. Replaces `<kendo-numerictextbox>`.\n */\n@Component({\n selector: 'mj-numeric-input',\n standalone: true,\n template: `\n <input type=\"number\" class=\"mj-input mj-numeric-input\"\n [attr.min]=\"Min\" [attr.max]=\"Max\" [attr.step]=\"Step\"\n [attr.placeholder]=\"Placeholder\" [disabled]=\"IsDisabled\"\n [value]=\"DisplayValue\"\n (input)=\"OnInput($event)\" (blur)=\"OnBlur()\" />\n `,\n providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => MJNumericInputComponent), multi: true }]\n})\nexport class MJNumericInputComponent implements ControlValueAccessor {\n @Input() Min: number | null = null;\n @Input() Max: number | null = null;\n @Input() Step: number = 1;\n @Input() Format: string = '';\n @Input() Decimals: number | null = null;\n /**\n * Host-driven disable. Composed with Angular Forms' `setDisabledState()` into `IsDisabled`\n * (the actual gate) — see `syncDisabled`. A setter, not a bare field, because this input is\n * routinely bound to an expression that changes over the control's lifetime, and the gate has\n * to follow it every time.\n */\n @Input()\n set Disabled(value: boolean) { this.disabledInput = value; this.syncDisabled(); }\n get Disabled(): boolean { return this.disabledInput; }\n @Input() Placeholder = '';\n @HostBinding('class.mj-numeric-input-host') readonly hostClass = true;\n\n /** The rendered `[disabled]` state — true when EITHER source says so. Assign via `syncDisabled()`. */\n IsDisabled = false;\n private disabledInput = false;\n private formDisabled = false;\n private cdr = inject(ChangeDetectorRef);\n\n /**\n * Recompute the gate from both of its sources. Called whenever either one changes.\n *\n * `IsDisabled` is derived state, and the only thing that assigned it was `setDisabledState()`.\n * The forms-driven half was in fact fine — `setUpControl` also wires `registerOnDisabledChange`,\n * so that hook fires on every `control.disable()`/`enable()`, not just at registration. What had\n * no recompute path at all was the `Disabled` @Input: a plain field, so the gate froze at\n * whatever the first compose produced and every later change to the input was dropped.\n */\n private syncDisabled(): void {\n const disabled = this.disabledInput || this.formDisabled;\n if (disabled === this.IsDisabled) return;\n this.IsDisabled = disabled;\n this.cdr.markForCheck();\n }\n\n DisplayValue: string | number = '';\n private internalValue: number | null = null;\n private onChange: (value: number | null) => void = () => {};\n private onTouched: () => void = () => {};\n\n OnInput(event: Event): void {\n const raw = (event.target as HTMLInputElement).value;\n if (raw === '' || raw === '-') { this.internalValue = null; this.onChange(null); return; }\n let num = parseFloat(raw);\n if (isNaN(num)) return;\n num = this.clamp(num);\n this.internalValue = num;\n this.onChange(num);\n }\n\n OnBlur(): void { this.onTouched(); this.formatDisplay(); }\n\n writeValue(value: number | null): void { this.internalValue = value; this.formatDisplay(); }\n registerOnChange(fn: (value: number | null) => void): void { this.onChange = fn; }\n registerOnTouched(fn: () => void): void { this.onTouched = fn; }\n setDisabledState(isDisabled: boolean): void { this.formDisabled = isDisabled; this.syncDisabled(); }\n\n private clamp(value: number): number {\n if (this.Min != null && value < this.Min) return this.Min;\n if (this.Max != null && value > this.Max) return this.Max;\n if (this.Decimals != null) { const f = Math.pow(10, this.Decimals); return Math.round(value * f) / f; }\n return value;\n }\n\n private formatDisplay(): void {\n if (this.internalValue == null) { this.DisplayValue = ''; return; }\n this.DisplayValue = this.Decimals != null ? this.internalValue.toFixed(this.Decimals) : this.internalValue;\n }\n}\n"]}
@@ -64,7 +64,7 @@ export class MJPageBodyComponent {
64
64
  } }, inputs: { Padding: "Padding", Flex: "Flex", Direction: "Direction" }, ngContentSelectors: _c0, decls: 1, vars: 0, template: function MJPageBodyComponent_Template(rf, ctx) { if (rf & 1) {
65
65
  i0.ɵɵprojectionDef();
66
66
  i0.ɵɵprojection(0);
67
- } }, styles: ["[_nghost-%COMP%] {\n display: block;\n flex: 1;\n min-height: 0;\n \n\n\n\n padding: var(--mj-space-6);\n overflow-y: auto;\n }\n .mj-page-body--no-padding[_nghost-%COMP%] {\n padding: 0;\n }\n .mj-page-body--flex[_nghost-%COMP%] {\n display: flex;\n flex-direction: column;\n position: relative;\n }\n \n\n\n\n\n .mj-page-body--flex.mj-page-body--row[_nghost-%COMP%] {\n flex-direction: row;\n }\n \n\n\n\n\n @media (max-width: 700px) {\n .mj-page-body--flex.mj-page-body--row[_nghost-%COMP%] {\n flex-direction: column;\n }\n }"] });
67
+ } }, styles: ["[_nghost-%COMP%] {\n display: block;\n flex: 1;\n min-height: 0;\n \n\n\n padding: var(--mj-space-6);\n overflow-y: auto;\n }\n .mj-page-body--no-padding[_nghost-%COMP%] {\n padding: 0;\n }\n .mj-page-body--flex[_nghost-%COMP%] {\n display: flex;\n flex-direction: column;\n position: relative;\n }\n \n\n\n\n .mj-page-body--flex.mj-page-body--row[_nghost-%COMP%] {\n flex-direction: row;\n }\n \n\n\n\n @media (max-width: 700px) {\n .mj-page-body--flex.mj-page-body--row[_nghost-%COMP%] {\n flex-direction: column;\n }\n }"] });
68
68
  }
69
69
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MJPageBodyComponent, [{
70
70
  type: Component,
@@ -70,7 +70,7 @@ export class MJPageBodyInteriorComponent {
70
70
  } }, inputs: { Padding: "Padding", Flex: "Flex", Direction: "Direction" }, ngContentSelectors: _c0, decls: 1, vars: 0, template: function MJPageBodyInteriorComponent_Template(rf, ctx) { if (rf & 1) {
71
71
  i0.ɵɵprojectionDef();
72
72
  i0.ɵɵprojection(0);
73
- } }, styles: ["[_nghost-%COMP%] {\n display: block;\n flex: 1 1 auto;\n min-height: 0;\n overflow-y: auto;\n overflow-x: hidden;\n -webkit-overflow-scrolling: touch;\n \n\n\n\n\n padding: var(--mj-space-2) var(--mj-space-4) var(--mj-space-4);\n background: var(--mj-bg-page);\n }\n\n @media (min-width: 768px) {\n [_nghost-%COMP%] { padding: var(--mj-space-2) var(--mj-space-6) var(--mj-space-6); }\n }\n\n @media (min-width: 1024px) {\n [_nghost-%COMP%] { padding: var(--mj-space-2) var(--mj-space-8) var(--mj-space-8); }\n }\n\n \n\n .mj-page-body-interior--no-padding[_nghost-%COMP%] {\n padding: 0;\n }\n\n \n\n .mj-page-body-interior--flex[_nghost-%COMP%] {\n display: flex;\n flex-direction: column;\n overflow: hidden;\n }\n\n .mj-page-body-interior--flex.mj-page-body-interior--row[_nghost-%COMP%] {\n flex-direction: row;\n }"] });
73
+ } }, styles: ["[_nghost-%COMP%] {\n display: block;\n flex: 1 1 auto;\n min-height: 0;\n overflow-y: auto;\n overflow-x: hidden;\n -webkit-overflow-scrolling: touch;\n \n\n\n\n padding: var(--mj-space-2) var(--mj-space-4) var(--mj-space-4);\n background: var(--mj-bg-page);\n }\n\n @media (min-width: 768px) {\n [_nghost-%COMP%] { padding: var(--mj-space-2) var(--mj-space-6) var(--mj-space-6); }\n }\n\n @media (min-width: 1024px) {\n [_nghost-%COMP%] { padding: var(--mj-space-2) var(--mj-space-8) var(--mj-space-8); }\n }\n\n \n .mj-page-body-interior--no-padding[_nghost-%COMP%] {\n padding: 0;\n }\n\n \n .mj-page-body-interior--flex[_nghost-%COMP%] {\n display: flex;\n flex-direction: column;\n overflow: hidden;\n }\n\n .mj-page-body-interior--flex.mj-page-body-interior--row[_nghost-%COMP%] {\n flex-direction: row;\n }"] });
74
74
  }
75
75
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MJPageBodyInteriorComponent, [{
76
76
  type: Component,
@@ -83,7 +83,7 @@ export class MJPageHeaderComponent {
83
83
  i0.ɵɵtextInterpolate(ctx.Title);
84
84
  i0.ɵɵadvance();
85
85
  i0.ɵɵconditional(ctx.Subtitle ? 7 : -1);
86
- } }, styles: ["[_nghost-%COMP%] {\n display: block;\n \n\n\n\n margin-bottom: var(--mj-space-6);\n}\n\n\n\n\n\n\nmj-page-layout[_nghost-%COMP%], mj-page-layout [_nghost-%COMP%] {\n margin-bottom: 0;\n}\n\n\n\n\n\n\n\n\n[_nghost-%COMP%] [meta], \n[_nghost-%COMP%] [actions], \n[_nghost-%COMP%] [toolbar] {\n display: contents;\n}\n\n.mj-page-header[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface);\n \n\n\n\n\n\n\n box-shadow: var(--mj-shadow-md);\n position: relative;\n z-index: 1;\n}\n\n.mj-page-header-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-3);\n padding: 0 var(--mj-space-6);\n}\n\n\n\n\n\n\n\n\n.mj-page-header-row--primary[_ngcontent-%COMP%] {\n justify-content: space-between;\n align-items: center;\n gap: var(--mj-space-4);\n padding-top: var(--mj-space-4);\n padding-bottom: var(--mj-space-4);\n}\n\n.mj-page-header-row--toolbar[_ngcontent-%COMP%] {\n flex-wrap: wrap;\n \n\n\n justify-content: flex-end;\n padding-top: 0;\n padding-bottom: var(--mj-space-4);\n border-top: 1px solid var(--mj-border-subtle);\n margin-top: 0;\n padding-top: var(--mj-space-3);\n}\n\n.mj-page-header-row--toolbar[_ngcontent-%COMP%]:empty {\n display: none;\n border-top: 0;\n padding: 0;\n}\n\n.mj-page-header-titlebar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-3);\n flex: 1 1 auto;\n min-width: 0;\n}\n\n.mj-page-header-icon[_ngcontent-%COMP%] {\n flex-shrink: 0;\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent);\n color: var(--mj-brand-primary);\n border-radius: var(--mj-radius-md);\n font-size: var(--mj-text-lg);\n}\n\n\n\n.mj-page-header-text[_ngcontent-%COMP%] {\n min-width: 0;\n flex: 1 1 auto;\n display: flex;\n flex-direction: column;\n}\n\n.mj-page-header-title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: var(--mj-text-xl);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n line-height: 1.25;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.mj-page-header-subtitle[_ngcontent-%COMP%] {\n margin: var(--mj-space-1) 0 0;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-secondary);\n line-height: 1.4;\n}\n\n\n\n\n\n\n.mj-page-header-meta[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--mj-space-2);\n margin-top: var(--mj-space-2);\n}\n\n.mj-page-header-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-3);\n flex-shrink: 0;\n}\n\n.mj-page-header-meta[_ngcontent-%COMP%]:empty, \n.mj-page-header-actions[_ngcontent-%COMP%]:empty {\n display: none;\n}\n\n\n\n\n\n\n\n@media (max-width: 768px) {\n .mj-page-header-row[_ngcontent-%COMP%] {\n padding-left: var(--mj-space-4);\n padding-right: var(--mj-space-4);\n gap: var(--mj-space-2);\n }\n .mj-page-header-row--primary[_ngcontent-%COMP%] {\n \n\n\n\n gap: var(--mj-space-2);\n padding-top: var(--mj-space-3);\n padding-bottom: var(--mj-space-3);\n }\n \n\n .mj-page-header-icon[_ngcontent-%COMP%], \n .mj-page-header-subtitle[_ngcontent-%COMP%] {\n display: none;\n }\n .mj-page-header-title[_ngcontent-%COMP%] {\n font-size: var(--mj-text-lg);\n line-height: 1.2;\n }\n .mj-page-header-meta[_ngcontent-%COMP%] {\n margin-top: var(--mj-space-1);\n }\n .mj-page-header-actions[_ngcontent-%COMP%] {\n flex-wrap: wrap;\n justify-content: flex-start;\n gap: var(--mj-space-2);\n }\n \n\n\n .mj-page-header-actions[_ngcontent-%COMP%] .action-btn-label {\n display: none;\n }\n .mj-page-header-row--toolbar[_ngcontent-%COMP%] {\n \n\n justify-content: flex-start;\n padding-top: var(--mj-space-2);\n padding-bottom: var(--mj-space-3);\n }\n \n\n\n .mj-page-header-row--toolbar[_ngcontent-%COMP%] mj-page-search {\n flex: 1;\n min-width: 0;\n }\n}"] });
86
+ } }, styles: ["[_nghost-%COMP%] {\n display: block;\n \n\n\n margin-bottom: var(--mj-space-6);\n}\n\n\n\n\n\nmj-page-layout[_nghost-%COMP%], mj-page-layout [_nghost-%COMP%] {\n margin-bottom: 0;\n}\n\n\n\n\n\n\n\n[_nghost-%COMP%] [meta], \n[_nghost-%COMP%] [actions], \n[_nghost-%COMP%] [toolbar] {\n display: contents;\n}\n\n.mj-page-header[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface);\n \n\n\n\n\n\n box-shadow: var(--mj-shadow-md);\n position: relative;\n z-index: 1;\n}\n\n.mj-page-header-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-3);\n padding: 0 var(--mj-space-6);\n}\n\n\n\n\n\n\n\n.mj-page-header-row--primary[_ngcontent-%COMP%] {\n justify-content: space-between;\n align-items: center;\n gap: var(--mj-space-4);\n padding-top: var(--mj-space-4);\n padding-bottom: var(--mj-space-4);\n}\n\n.mj-page-header-row--toolbar[_ngcontent-%COMP%] {\n flex-wrap: wrap;\n \n\n justify-content: flex-end;\n padding-top: 0;\n padding-bottom: var(--mj-space-4);\n border-top: 1px solid var(--mj-border-subtle);\n margin-top: 0;\n padding-top: var(--mj-space-3);\n}\n\n.mj-page-header-row--toolbar[_ngcontent-%COMP%]:empty {\n display: none;\n border-top: 0;\n padding: 0;\n}\n\n.mj-page-header-titlebar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-3);\n flex: 1 1 auto;\n min-width: 0;\n}\n\n.mj-page-header-icon[_ngcontent-%COMP%] {\n flex-shrink: 0;\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent);\n color: var(--mj-brand-primary);\n border-radius: var(--mj-radius-md);\n font-size: var(--mj-text-lg);\n}\n\n\n.mj-page-header-text[_ngcontent-%COMP%] {\n min-width: 0;\n flex: 1 1 auto;\n display: flex;\n flex-direction: column;\n}\n\n.mj-page-header-title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: var(--mj-text-xl);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n line-height: 1.25;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.mj-page-header-subtitle[_ngcontent-%COMP%] {\n margin: var(--mj-space-1) 0 0;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-secondary);\n line-height: 1.4;\n}\n\n\n\n\n\n.mj-page-header-meta[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--mj-space-2);\n margin-top: var(--mj-space-2);\n}\n\n.mj-page-header-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-3);\n flex-shrink: 0;\n}\n\n.mj-page-header-meta[_ngcontent-%COMP%]:empty, \n.mj-page-header-actions[_ngcontent-%COMP%]:empty {\n display: none;\n}\n\n\n\n\n\n\n@media (max-width: 768px) {\n .mj-page-header-row[_ngcontent-%COMP%] {\n padding-left: var(--mj-space-4);\n padding-right: var(--mj-space-4);\n gap: var(--mj-space-2);\n }\n .mj-page-header-row--primary[_ngcontent-%COMP%] {\n \n\n\n gap: var(--mj-space-2);\n padding-top: var(--mj-space-3);\n padding-bottom: var(--mj-space-3);\n }\n \n .mj-page-header-icon[_ngcontent-%COMP%], \n .mj-page-header-subtitle[_ngcontent-%COMP%] {\n display: none;\n }\n .mj-page-header-title[_ngcontent-%COMP%] {\n font-size: var(--mj-text-lg);\n line-height: 1.2;\n }\n .mj-page-header-meta[_ngcontent-%COMP%] {\n margin-top: var(--mj-space-1);\n }\n .mj-page-header-actions[_ngcontent-%COMP%] {\n flex-wrap: wrap;\n justify-content: flex-start;\n gap: var(--mj-space-2);\n }\n \n\n .mj-page-header-actions[_ngcontent-%COMP%] .action-btn-label {\n display: none;\n }\n .mj-page-header-row--toolbar[_ngcontent-%COMP%] {\n \n justify-content: flex-start;\n padding-top: var(--mj-space-2);\n padding-bottom: var(--mj-space-3);\n }\n \n\n .mj-page-header-row--toolbar[_ngcontent-%COMP%] mj-page-search {\n flex: 1;\n min-width: 0;\n }\n}"] });
87
87
  }
88
88
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MJPageHeaderComponent, [{
89
89
  type: Component,
@@ -133,7 +133,7 @@ export class MJPageHeaderInteriorComponent {
133
133
  i0.ɵɵconditional(ctx.Title ? 3 : -1);
134
134
  i0.ɵɵadvance();
135
135
  i0.ɵɵconditional(ctx.Subtitle ? 4 : -1);
136
- } }, styles: ["[_nghost-%COMP%] {\n display: block;\n margin: var(--mj-space-4) var(--mj-space-4) var(--mj-space-3);\n }\n\n .mj-page-header-interior[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\n box-shadow: var(--mj-shadow-sm);\n overflow: hidden;\n }\n\n \n\n\n\n\n\n [_nghost-%COMP%] [meta], \n [_nghost-%COMP%] [actions], \n [_nghost-%COMP%] [toolbar] {\n display: contents;\n }\n\n\n \n\n\n\n\n\n .mj-page-header-interior__row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-3);\n padding: var(--mj-space-3) var(--mj-space-4);\n }\n\n .mj-page-header-interior__row--primary[_ngcontent-%COMP%] {\n gap: var(--mj-space-4);\n }\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n .mj-page-header-interior__row--toolbar[_ngcontent-%COMP%] {\n display: none;\n }\n\n \n\n\n\n\n [_nghost-%COMP%] .mj-page-header-interior__row--toolbar:has(> [toolbar] > *) {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n \n\n justify-content: flex-end;\n gap: var(--mj-space-3);\n padding: var(--mj-space-3) var(--mj-space-4);\n border-top: 1px solid var(--mj-border-subtle);\n }\n\n .mj-page-header-interior__identity[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n justify-content: center;\n gap: 2px;\n flex-shrink: 1;\n min-width: 0;\n }\n\n \n\n\n\n .mj-page-header-interior__title[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xl);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n line-height: 1.25;\n }\n .mj-page-header-interior__subtitle[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n color: var(--mj-text-secondary);\n line-height: 1.4;\n }\n\n .mj-page-header-interior__spacer[_ngcontent-%COMP%] {\n flex: 1 1 auto;\n min-width: 0;\n }\n\n \n\n\n\n\n\n\n .mj-page-header-interior__meta[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--mj-space-2);\n margin-top: var(--mj-space-2);\n }\n\n .mj-page-header-interior__actions[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: var(--mj-space-3);\n flex-shrink: 0;\n }\n\n \n\n .mj-page-header-interior__meta[_ngcontent-%COMP%]:empty, \n .mj-page-header-interior__actions[_ngcontent-%COMP%]:empty {\n display: none;\n }\n\n \n\n\n\n .mj-page-header-interior__identity[_ngcontent-%COMP%]:not(:has(.mj-page-header-interior__title)):not(:has(.mj-page-header-interior__subtitle)):has(.mj-page-header-interior__meta:empty) {\n display: none;\n }\n\n \n\n\n\n\n \n\n\n\n\n\n @media (max-width: 768px) {\n [_nghost-%COMP%] {\n margin: 0;\n }\n .mj-page-header-interior__title[_ngcontent-%COMP%], \n .mj-page-header-interior__subtitle[_ngcontent-%COMP%] {\n display: none;\n }\n \n\n\n\n [_nghost-%COMP%] .mj-page-header-interior__actions .mj-action-label {\n display: none;\n }\n \n\n\n [_nghost-%COMP%] .mj-page-header-interior__row--toolbar:has(> [toolbar] > *) {\n flex-wrap: nowrap;\n overflow-x: auto;\n \n\n justify-content: flex-start;\n }\n \n\n [_nghost-%COMP%] .mj-page-header-interior__row--toolbar mj-page-search {\n flex: 1;\n min-width: 0;\n }\n }"] });
136
+ } }, styles: ["[_nghost-%COMP%] {\n display: block;\n margin: var(--mj-space-4) var(--mj-space-4) var(--mj-space-3);\n }\n\n .mj-page-header-interior[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\n box-shadow: var(--mj-shadow-sm);\n overflow: hidden;\n }\n\n \n\n\n\n\n [_nghost-%COMP%] [meta], \n [_nghost-%COMP%] [actions], \n [_nghost-%COMP%] [toolbar] {\n display: contents;\n }\n\n\n \n\n\n\n\n .mj-page-header-interior__row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-3);\n padding: var(--mj-space-3) var(--mj-space-4);\n }\n\n .mj-page-header-interior__row--primary[_ngcontent-%COMP%] {\n gap: var(--mj-space-4);\n }\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n .mj-page-header-interior__row--toolbar[_ngcontent-%COMP%] {\n display: none;\n }\n\n \n\n\n\n [_nghost-%COMP%] .mj-page-header-interior__row--toolbar:has(> [toolbar] > *) {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n \n justify-content: flex-end;\n gap: var(--mj-space-3);\n padding: var(--mj-space-3) var(--mj-space-4);\n border-top: 1px solid var(--mj-border-subtle);\n }\n\n .mj-page-header-interior__identity[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n justify-content: center;\n gap: 2px;\n flex-shrink: 1;\n min-width: 0;\n }\n\n \n\n\n .mj-page-header-interior__title[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xl);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n line-height: 1.25;\n }\n .mj-page-header-interior__subtitle[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n color: var(--mj-text-secondary);\n line-height: 1.4;\n }\n\n .mj-page-header-interior__spacer[_ngcontent-%COMP%] {\n flex: 1 1 auto;\n min-width: 0;\n }\n\n \n\n\n\n\n\n .mj-page-header-interior__meta[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--mj-space-2);\n margin-top: var(--mj-space-2);\n }\n\n .mj-page-header-interior__actions[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: var(--mj-space-3);\n flex-shrink: 0;\n }\n\n \n .mj-page-header-interior__meta[_ngcontent-%COMP%]:empty, \n .mj-page-header-interior__actions[_ngcontent-%COMP%]:empty {\n display: none;\n }\n\n \n\n\n .mj-page-header-interior__identity[_ngcontent-%COMP%]:not(:has(.mj-page-header-interior__title)):not(:has(.mj-page-header-interior__subtitle)):has(.mj-page-header-interior__meta:empty) {\n display: none;\n }\n\n \n\n\n\n \n\n\n\n\n @media (max-width: 768px) {\n [_nghost-%COMP%] {\n margin: 0;\n }\n .mj-page-header-interior__title[_ngcontent-%COMP%], \n .mj-page-header-interior__subtitle[_ngcontent-%COMP%] {\n display: none;\n }\n \n\n\n [_nghost-%COMP%] .mj-page-header-interior__actions .mj-action-label {\n display: none;\n }\n \n\n [_nghost-%COMP%] .mj-page-header-interior__row--toolbar:has(> [toolbar] > *) {\n flex-wrap: nowrap;\n overflow-x: auto;\n \n justify-content: flex-start;\n }\n \n [_nghost-%COMP%] .mj-page-header-interior__row--toolbar mj-page-search {\n flex: 1;\n min-width: 0;\n }\n }"] });
137
137
  }
138
138
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MJPageHeaderInteriorComponent, [{
139
139
  type: Component,
@@ -40,7 +40,7 @@ export class MJPageSearchComponent {
40
40
  i0.ɵɵclassMap(ctx.Icon);
41
41
  i0.ɵɵadvance();
42
42
  i0.ɵɵdomProperty("placeholder", ctx.Placeholder)("value", ctx.Value);
43
- } }, styles: ["[_nghost-%COMP%] {\n display: inline-flex;\n min-width: 220px;\n }\n\n \n\n\n\n\n\n .mj-page-search[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n width: 100%;\n padding: var(--mj-space-1) var(--mj-space-3);\n font-family: var(--mj-font-family);\n font-size: var(--mj-text-sm);\n line-height: 1.5;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-sm);\n transition: var(--mj-transition-colors), box-shadow var(--mj-transition-base);\n min-height: 32px;\n box-sizing: border-box;\n }\n\n .mj-page-search[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-border-strong);\n }\n\n .mj-page-search--focused[_ngcontent-%COMP%] {\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-focus-ring);\n }\n\n .mj-page-search[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 13px;\n flex-shrink: 0;\n }\n\n .mj-page-search[_ngcontent-%COMP%] input[_ngcontent-%COMP%] {\n flex: 1;\n border: none;\n outline: none;\n background: transparent;\n font: inherit;\n color: var(--mj-text-primary);\n min-width: 0;\n }\n\n .mj-page-search[_ngcontent-%COMP%] input[_ngcontent-%COMP%]::placeholder {\n color: var(--mj-text-disabled);\n }"] });
43
+ } }, styles: ["[_nghost-%COMP%] {\n display: inline-flex;\n min-width: 220px;\n }\n\n \n\n\n\n\n .mj-page-search[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n width: 100%;\n padding: var(--mj-space-1) var(--mj-space-3);\n font-family: var(--mj-font-family);\n font-size: var(--mj-text-sm);\n line-height: 1.5;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-sm);\n transition: var(--mj-transition-colors), box-shadow var(--mj-transition-base);\n min-height: 32px;\n box-sizing: border-box;\n }\n\n .mj-page-search[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-border-strong);\n }\n\n .mj-page-search--focused[_ngcontent-%COMP%] {\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-focus-ring);\n }\n\n .mj-page-search[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 13px;\n flex-shrink: 0;\n }\n\n .mj-page-search[_ngcontent-%COMP%] input[_ngcontent-%COMP%] {\n flex: 1;\n border: none;\n outline: none;\n background: transparent;\n font: inherit;\n color: var(--mj-text-primary);\n min-width: 0;\n }\n\n .mj-page-search[_ngcontent-%COMP%] input[_ngcontent-%COMP%]::placeholder {\n color: var(--mj-text-disabled);\n }"] });
44
44
  }
45
45
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MJPageSearchComponent, [{
46
46
  type: Component,
@@ -68,7 +68,7 @@ export class MJRefreshButtonComponent {
68
68
  i0.ɵɵclassProp("fa-spin", ctx.Loading);
69
69
  i0.ɵɵadvance();
70
70
  i0.ɵɵconditional(ctx.ShowLabel ? 2 : -1);
71
- } }, dependencies: [MJButtonDirective], styles: ["[_nghost-%COMP%] { display: inline-flex; }\n\n \n\n\n @media (max-width: 768px) {\n .mj-refresh-button__label[_ngcontent-%COMP%] {\n display: none;\n }\n }"] });
71
+ } }, dependencies: [MJButtonDirective], styles: ["[_nghost-%COMP%] { display: inline-flex; }\n\n \n\n @media (max-width: 768px) {\n .mj-refresh-button__label[_ngcontent-%COMP%] {\n display: none;\n }\n }"] });
72
72
  }
73
73
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MJRefreshButtonComponent, [{
74
74
  type: Component,
@@ -223,7 +223,7 @@ export class MjSlidePanelComponent {
223
223
  i0.ɵɵconditional(ctx.Mode === "slide" ? 1 : -1);
224
224
  i0.ɵɵadvance();
225
225
  i0.ɵɵconditional(ctx.Mode === "dialog" ? 2 : -1);
226
- } }, styles: ["\n\n\n\n\n\n\n.sp-backdrop[_ngcontent-%COMP%] {\n position: fixed;\n inset: 0;\n background: transparent;\n z-index: 1000;\n transition: background 0.3s ease;\n pointer-events: none;\n}\n\n\n\n\n\n\n\n.sp-backdrop.sp-open[_ngcontent-%COMP%] {\n background: var(--mj-bg-overlay);\n pointer-events: auto;\n}\n\n.sp-dialog-backdrop.sp-open[_ngcontent-%COMP%] {\n background: var(--mj-bg-overlay);\n}\n\n\n\n\n\n\n\n\n.sp-panel[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n right: 0;\n height: 100vh;\n background: var(--mj-bg-surface);\n box-shadow: var(--mj-shadow-lg);\n z-index: 1001;\n display: flex;\n flex-direction: column;\n transform: translateX(100%);\n transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1);\n min-width: 400px;\n max-width: 92vw;\n}\n\n.sp-panel.sp-open[_ngcontent-%COMP%] {\n \n\n\n\n\n\n transform: none;\n}\n\n\n\n\n\n\n\n\n.sp-dialog[_ngcontent-%COMP%] {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%) scale(0.95);\n max-height: 85vh;\n background: var(--mj-bg-surface);\n border-radius: 16px;\n box-shadow: var(--mj-shadow-lg);\n z-index: 1001;\n display: flex;\n flex-direction: column;\n opacity: 0;\n transition: opacity 0.25s ease, transform 0.25s cubic-bezier(0.16, 1, 0.3, 1);\n min-width: 360px;\n max-width: 95vw;\n}\n\n.sp-dialog.sp-open[_ngcontent-%COMP%] {\n opacity: 1;\n transform: translate(-50%, -50%) scale(1);\n}\n\n\n\n\n\n\n\n\n.sp-resize-handle[_ngcontent-%COMP%] {\n position: absolute;\n left: -4px;\n top: 0;\n width: 8px;\n height: 100%;\n cursor: col-resize;\n z-index: 10;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.sp-resize-handle[_ngcontent-%COMP%]:hover .sp-resize-grip[_ngcontent-%COMP%], \n.sp-resize-handle[_ngcontent-%COMP%]:active .sp-resize-grip[_ngcontent-%COMP%] {\n opacity: 1;\n background: var(--mj-brand-primary);\n}\n\n.sp-resize-grip[_ngcontent-%COMP%] {\n width: 3px;\n height: 40px;\n background: var(--mj-border-strong);\n border-radius: 3px;\n opacity: 0;\n transition: opacity 0.2s ease, background 0.2s ease;\n}\n\n.sp-resize-handle[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 4%, transparent);\n}\n\n\n\n\n\n\n\n\n.sp-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 24px;\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.sp-title[_ngcontent-%COMP%] {\n font-size: 18px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n flex: 1;\n}\n\n.sp-close-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n background: none;\n border: none;\n border-radius: 8px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.15s ease;\n font-size: 16px;\n flex-shrink: 0;\n}\n\n.sp-close-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n\n\n\n\n\n\n\n.sp-body[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n}\n\n.sp-dialog-body[_ngcontent-%COMP%] {\n padding: 0;\n}\n\n\n\n\n\n\n\n\n@media (max-width: 768px) {\n .sp-panel[_ngcontent-%COMP%] {\n width: 100% !important;\n min-width: unset;\n }\n\n .sp-resize-handle[_ngcontent-%COMP%] {\n display: none;\n }\n\n .sp-dialog[_ngcontent-%COMP%] {\n width: 95vw !important;\n max-height: 90vh;\n }\n}"], changeDetection: 0 });
226
+ } }, styles: ["\n\n\n\n.sp-backdrop[_ngcontent-%COMP%] {\n position: fixed;\n inset: 0;\n background: transparent;\n z-index: 1000;\n transition: background 0.3s ease;\n pointer-events: none;\n}\n\n\n\n\n\n\n.sp-backdrop.sp-open[_ngcontent-%COMP%] {\n background: var(--mj-bg-overlay);\n pointer-events: auto;\n}\n\n.sp-dialog-backdrop.sp-open[_ngcontent-%COMP%] {\n background: var(--mj-bg-overlay);\n}\n\n\n\n\n\n.sp-panel[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n right: 0;\n height: 100vh;\n background: var(--mj-bg-surface);\n box-shadow: var(--mj-shadow-lg);\n z-index: 1001;\n display: flex;\n flex-direction: column;\n transform: translateX(100%);\n transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1);\n min-width: 400px;\n max-width: 92vw;\n}\n\n.sp-panel.sp-open[_ngcontent-%COMP%] {\n \n\n\n\n\n transform: none;\n}\n\n\n\n\n\n.sp-dialog[_ngcontent-%COMP%] {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%) scale(0.95);\n max-height: 85vh;\n background: var(--mj-bg-surface);\n border-radius: 16px;\n box-shadow: var(--mj-shadow-lg);\n z-index: 1001;\n display: flex;\n flex-direction: column;\n opacity: 0;\n transition: opacity 0.25s ease, transform 0.25s cubic-bezier(0.16, 1, 0.3, 1);\n min-width: 360px;\n max-width: 95vw;\n}\n\n.sp-dialog.sp-open[_ngcontent-%COMP%] {\n opacity: 1;\n transform: translate(-50%, -50%) scale(1);\n}\n\n\n\n\n\n.sp-resize-handle[_ngcontent-%COMP%] {\n position: absolute;\n left: -4px;\n top: 0;\n width: 8px;\n height: 100%;\n cursor: col-resize;\n z-index: 10;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.sp-resize-handle[_ngcontent-%COMP%]:hover .sp-resize-grip[_ngcontent-%COMP%], \n.sp-resize-handle[_ngcontent-%COMP%]:active .sp-resize-grip[_ngcontent-%COMP%] {\n opacity: 1;\n background: var(--mj-brand-primary);\n}\n\n.sp-resize-grip[_ngcontent-%COMP%] {\n width: 3px;\n height: 40px;\n background: var(--mj-border-strong);\n border-radius: 3px;\n opacity: 0;\n transition: opacity 0.2s ease, background 0.2s ease;\n}\n\n.sp-resize-handle[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 4%, transparent);\n}\n\n\n\n\n\n.sp-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 24px;\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.sp-title[_ngcontent-%COMP%] {\n font-size: 18px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n flex: 1;\n}\n\n.sp-close-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n background: none;\n border: none;\n border-radius: 8px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.15s ease;\n font-size: 16px;\n flex-shrink: 0;\n}\n\n.sp-close-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n\n\n\n\n.sp-body[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n}\n\n.sp-dialog-body[_ngcontent-%COMP%] {\n padding: 0;\n}\n\n\n\n\n\n@media (max-width: 768px) {\n .sp-panel[_ngcontent-%COMP%] {\n width: 100% !important;\n min-width: unset;\n }\n\n .sp-resize-handle[_ngcontent-%COMP%] {\n display: none;\n }\n\n .sp-dialog[_ngcontent-%COMP%] {\n width: 95vw !important;\n max-height: 90vh;\n }\n}"], changeDetection: 0 });
227
227
  }
228
228
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MjSlidePanelComponent, [{
229
229
  type: Component,
@@ -110,7 +110,7 @@ export class MJStatBadgeComponent {
110
110
  i0.ɵɵconditional(ctx.Count != null ? 1 : -1);
111
111
  i0.ɵɵadvance();
112
112
  i0.ɵɵconditional(ctx.Label ? 2 : -1);
113
- } }, styles: ["[_nghost-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: var(--mj-space-1-5);\n padding: var(--mj-space-1) var(--mj-space-2-5);\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-full);\n font-size: var(--mj-text-xs);\n color: var(--mj-text-secondary);\n white-space: nowrap;\n line-height: 1.4;\n }\n\n [_nghost-%COMP%] strong[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n font-weight: 600;\n }\n\n \n\n\n\n .mj-stat-badge-of[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-weight: 400;\n }\n\n \n\n\n .mj-stat-badge--success[_nghost-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 10%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-status-success) 30%, var(--mj-border-default));\n color: var(--mj-status-success);\n }\n .mj-stat-badge--success[_nghost-%COMP%] strong[_ngcontent-%COMP%] { color: inherit; }\n\n .mj-stat-badge--error[_nghost-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-status-error) 30%, var(--mj-border-default));\n color: var(--mj-status-error);\n }\n .mj-stat-badge--error[_nghost-%COMP%] strong[_ngcontent-%COMP%] { color: inherit; }\n\n .mj-stat-badge--warning[_nghost-%COMP%], \n .mj-stat-badge--running[_nghost-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 10%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-status-warning) 30%, var(--mj-border-default));\n color: var(--mj-status-warning);\n }\n .mj-stat-badge--warning[_nghost-%COMP%] strong[_ngcontent-%COMP%], \n .mj-stat-badge--running[_nghost-%COMP%] strong[_ngcontent-%COMP%] { color: inherit; }\n\n .mj-stat-badge--info[_nghost-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-brand-primary) 30%, var(--mj-border-default));\n color: var(--mj-brand-primary);\n }\n .mj-stat-badge--info[_nghost-%COMP%] strong[_ngcontent-%COMP%] { color: inherit; }"] });
113
+ } }, styles: ["[_nghost-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: var(--mj-space-1-5);\n padding: var(--mj-space-1) var(--mj-space-2-5);\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-full);\n font-size: var(--mj-text-xs);\n color: var(--mj-text-secondary);\n white-space: nowrap;\n line-height: 1.4;\n }\n\n [_nghost-%COMP%] strong[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n font-weight: 600;\n }\n\n \n\n\n .mj-stat-badge-of[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-weight: 400;\n }\n\n \n\n .mj-stat-badge--success[_nghost-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 10%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-status-success) 30%, var(--mj-border-default));\n color: var(--mj-status-success);\n }\n .mj-stat-badge--success[_nghost-%COMP%] strong[_ngcontent-%COMP%] { color: inherit; }\n\n .mj-stat-badge--error[_nghost-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-status-error) 30%, var(--mj-border-default));\n color: var(--mj-status-error);\n }\n .mj-stat-badge--error[_nghost-%COMP%] strong[_ngcontent-%COMP%] { color: inherit; }\n\n .mj-stat-badge--warning[_nghost-%COMP%], \n .mj-stat-badge--running[_nghost-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 10%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-status-warning) 30%, var(--mj-border-default));\n color: var(--mj-status-warning);\n }\n .mj-stat-badge--warning[_nghost-%COMP%] strong[_ngcontent-%COMP%], \n .mj-stat-badge--running[_nghost-%COMP%] strong[_ngcontent-%COMP%] { color: inherit; }\n\n .mj-stat-badge--info[_nghost-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-brand-primary) 30%, var(--mj-border-default));\n color: var(--mj-brand-primary);\n }\n .mj-stat-badge--info[_nghost-%COMP%] strong[_ngcontent-%COMP%] { color: inherit; }"] });
114
114
  }
115
115
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MJStatBadgeComponent, [{
116
116
  type: Component,
@@ -6,12 +6,33 @@ import * as i0 from "@angular/core";
6
6
  export declare class MJSwitchComponent implements ControlValueAccessor {
7
7
  OnLabel: string;
8
8
  OffLabel: string;
9
- Disabled: boolean;
9
+ /**
10
+ * Host-driven disable. Composed with Angular Forms' `setDisabledState()` into `IsDisabled`
11
+ * (the actual gate) — see `syncDisabled`. A setter, not a bare field, because this input is
12
+ * routinely bound to an expression that changes over the control's lifetime, and the gate has
13
+ * to follow it every time.
14
+ */
15
+ set Disabled(value: boolean);
16
+ get Disabled(): boolean;
10
17
  readonly hostClass = true;
11
18
  Value: boolean;
19
+ /** The gate on `Toggle()` — true when EITHER source says so. Assign only via `syncDisabled()`. */
12
20
  IsDisabled: boolean;
21
+ private disabledInput;
22
+ private formDisabled;
23
+ private cdr;
13
24
  private onChange;
14
25
  private onTouched;
26
+ /**
27
+ * Recompute the gate from both of its sources. Called whenever either one changes.
28
+ *
29
+ * `IsDisabled` is derived state, and the only thing that assigned it was `setDisabledState()`.
30
+ * The forms-driven half was in fact fine — `setUpControl` also wires `registerOnDisabledChange`,
31
+ * so that hook fires on every `control.disable()`/`enable()`, not just at registration. What had
32
+ * no recompute path at all was the `Disabled` @Input: a plain field, so the gate froze at
33
+ * whatever the first compose produced and every later change to the input was dropped.
34
+ */
35
+ private syncDisabled;
15
36
  Toggle(): void;
16
37
  OnTouched(): void;
17
38
  writeValue(value: boolean): void;
@@ -1 +1 @@
1
- {"version":3,"file":"switch.component.d.ts","sourceRoot":"","sources":["../../../src/lib/switch/switch.component.ts"],"names":[],"mappings":"AACA,OAAO,EAAqB,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;;AAEzE;;GAEG;AACH,qBAgBa,iBAAkB,YAAW,oBAAoB;IACnD,OAAO,SAAM;IACb,QAAQ,SAAM;IACd,QAAQ,UAAS;IACW,QAAQ,CAAC,SAAS,QAAQ;IAE/D,KAAK,UAAS;IACd,UAAU,UAAS;IACnB,OAAO,CAAC,QAAQ,CAAsC;IACtD,OAAO,CAAC,SAAS,CAAwB;IAEzC,MAAM,IAAI,IAAI;IACd,SAAS,IAAI,IAAI;IACjB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAChC,gBAAgB,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,GAAG,IAAI;IACpD,iBAAiB,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,IAAI;IACvC,gBAAgB,CAAC,UAAU,EAAE,OAAO,GAAG,IAAI;yCAhBhC,iBAAiB;2CAAjB,iBAAiB;CAiB7B"}
1
+ {"version":3,"file":"switch.component.d.ts","sourceRoot":"","sources":["../../../src/lib/switch/switch.component.ts"],"names":[],"mappings":"AACA,OAAO,EAAqB,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;;AAEzE;;GAEG;AACH,qBAgBa,iBAAkB,YAAW,oBAAoB;IACnD,OAAO,SAAM;IACb,QAAQ,SAAM;IACvB;;;;;OAKG;IACH,IACI,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAsD;IACjF,IAAI,QAAQ,IAAI,OAAO,CAA+B;IACjB,QAAQ,CAAC,SAAS,QAAQ;IAE/D,KAAK,UAAS;IACd,kGAAkG;IAClG,UAAU,UAAS;IACnB,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,GAAG,CAA6B;IACxC,OAAO,CAAC,QAAQ,CAAsC;IACtD,OAAO,CAAC,SAAS,CAAwB;IAEzC;;;;;;;;OAQG;IACH,OAAO,CAAC,YAAY;IAOpB,MAAM,IAAI,IAAI;IACd,SAAS,IAAI,IAAI;IACjB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAChC,gBAAgB,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,GAAG,IAAI;IACpD,iBAAiB,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,IAAI;IACvC,gBAAgB,CAAC,UAAU,EAAE,OAAO,GAAG,IAAI;yCA5ChC,iBAAiB;2CAAjB,iBAAiB;CA6C7B"}
@@ -1,4 +1,4 @@
1
- import { Component, Input, forwardRef, HostBinding } from '@angular/core';
1
+ import { Component, Input, forwardRef, HostBinding, ChangeDetectorRef, inject } from '@angular/core';
2
2
  import { NG_VALUE_ACCESSOR } from '@angular/forms';
3
3
  import * as i0 from "@angular/core";
4
4
  function MJSwitchComponent_Conditional_3_Template(rf, ctx) { if (rf & 1) {
@@ -16,12 +16,39 @@ function MJSwitchComponent_Conditional_3_Template(rf, ctx) { if (rf & 1) {
16
16
  export class MJSwitchComponent {
17
17
  OnLabel = '';
18
18
  OffLabel = '';
19
- Disabled = false;
19
+ /**
20
+ * Host-driven disable. Composed with Angular Forms' `setDisabledState()` into `IsDisabled`
21
+ * (the actual gate) — see `syncDisabled`. A setter, not a bare field, because this input is
22
+ * routinely bound to an expression that changes over the control's lifetime, and the gate has
23
+ * to follow it every time.
24
+ */
25
+ set Disabled(value) { this.disabledInput = value; this.syncDisabled(); }
26
+ get Disabled() { return this.disabledInput; }
20
27
  hostClass = true;
21
28
  Value = false;
29
+ /** The gate on `Toggle()` — true when EITHER source says so. Assign only via `syncDisabled()`. */
22
30
  IsDisabled = false;
31
+ disabledInput = false;
32
+ formDisabled = false;
33
+ cdr = inject(ChangeDetectorRef);
23
34
  onChange = () => { };
24
35
  onTouched = () => { };
36
+ /**
37
+ * Recompute the gate from both of its sources. Called whenever either one changes.
38
+ *
39
+ * `IsDisabled` is derived state, and the only thing that assigned it was `setDisabledState()`.
40
+ * The forms-driven half was in fact fine — `setUpControl` also wires `registerOnDisabledChange`,
41
+ * so that hook fires on every `control.disable()`/`enable()`, not just at registration. What had
42
+ * no recompute path at all was the `Disabled` @Input: a plain field, so the gate froze at
43
+ * whatever the first compose produced and every later change to the input was dropped.
44
+ */
45
+ syncDisabled() {
46
+ const disabled = this.disabledInput || this.formDisabled;
47
+ if (disabled === this.IsDisabled)
48
+ return;
49
+ this.IsDisabled = disabled;
50
+ this.cdr.markForCheck();
51
+ }
25
52
  Toggle() { if (!this.IsDisabled) {
26
53
  this.Value = !this.Value;
27
54
  this.onChange(this.Value);
@@ -30,7 +57,7 @@ export class MJSwitchComponent {
30
57
  writeValue(value) { this.Value = !!value; }
31
58
  registerOnChange(fn) { this.onChange = fn; }
32
59
  registerOnTouched(fn) { this.onTouched = fn; }
33
- setDisabledState(isDisabled) { this.IsDisabled = isDisabled || this.Disabled; }
60
+ setDisabledState(isDisabled) { this.formDisabled = isDisabled; this.syncDisabled(); }
34
61
  static ɵfac = function MJSwitchComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || MJSwitchComponent)(); };
35
62
  static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MJSwitchComponent, selectors: [["mj-switch"]], hostVars: 2, hostBindings: function MJSwitchComponent_HostBindings(rf, ctx) { if (rf & 2) {
36
63
  i0.ɵɵclassProp("mj-switch-host", ctx.hostClass);
@@ -1 +1 @@
1
- {"version":3,"file":"switch.component.js","sourceRoot":"","sources":["../../../src/lib/switch/switch.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC1E,OAAO,EAAE,iBAAiB,EAAwB,MAAM,gBAAgB,CAAC;;;IAejE,kCAA8B;IAAA,YAAgC;IAAA,oBAAO;;;IAAvC,cAAgC;IAAhC,qEAAgC;;AAbtE;;GAEG;AAiBH,MAAM,OAAO,iBAAiB;IACnB,OAAO,GAAG,EAAE,CAAC;IACb,QAAQ,GAAG,EAAE,CAAC;IACd,QAAQ,GAAG,KAAK,CAAC;IACoB,SAAS,GAAG,IAAI,CAAC;IAE/D,KAAK,GAAG,KAAK,CAAC;IACd,UAAU,GAAG,KAAK,CAAC;IACX,QAAQ,GAA6B,GAAG,EAAE,GAAE,CAAC,CAAC;IAC9C,SAAS,GAAe,GAAG,EAAE,GAAE,CAAC,CAAC;IAEzC,MAAM,KAAW,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;QAAC,IAAI,CAAC,KAAK,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC;QAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAAC,CAAC,CAAC,CAAC;IACjG,SAAS,KAAW,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;IACvC,UAAU,CAAC,KAAc,IAAU,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;IAC1D,gBAAgB,CAAC,EAA4B,IAAU,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC,CAAC,CAAC;IAC5E,iBAAiB,CAAC,EAAc,IAAU,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC,CAAC,CAAC;IAChE,gBAAgB,CAAC,UAAmB,IAAU,IAAI,CAAC,UAAU,GAAG,UAAU,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;2GAhBnF,iBAAiB;6DAAjB,iBAAiB;YAAjB,+CAAiB;0HAFjB,CAAC,EAAE,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,UAAU,CAAC,GAAG,EAAE,CAAC,iBAAiB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;YAVxG,oCAG0C;YAArB,AAAnB,iGAAS,YAAQ,IAAC,+EAAS,eAAW,IAAC;YACvC,kCAA8B;YAAA,6BAAqC;YAAA,oBAAO;YAC1E,oFAA2B;YAG7B,oBAAS;;YAPuB,AAA9B,0CAA6B,uCAAyC;YAC1C,4CAAuB;;YAGnD,eAEC;YAFD,sDAEC;;;iFAKM,iBAAiB;cAhB7B,SAAS;eAAC;gBACT,QAAQ,EAAE,WAAW;gBACrB,UAAU,EAAE,IAAI;gBAChB,QAAQ,EAAE;;;;;;;;;;GAUT;gBACD,SAAS,EAAE,CAAC,EAAE,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,UAAU,CAAC,GAAG,EAAE,kBAAkB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;aAC3G;;kBAEE,KAAK;;kBACL,KAAK;;kBACL,KAAK;;kBACL,WAAW;mBAAC,sBAAsB;;kFAJxB,iBAAiB","sourcesContent":["import { Component, Input, forwardRef, HostBinding } from '@angular/core';\nimport { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';\n\n/**\n * mj-switch — Toggle switch. Replaces `<kendo-switch>`.\n */\n@Component({\n selector: 'mj-switch',\n standalone: true,\n template: `\n <button type=\"button\" role=\"switch\" class=\"mj-switch\"\n [class.mj-switch--on]=\"Value\" [class.mj-switch--disabled]=\"IsDisabled\"\n [attr.aria-checked]=\"Value\" [disabled]=\"IsDisabled\"\n (click)=\"Toggle()\" (blur)=\"OnTouched()\">\n <span class=\"mj-switch-track\"><span class=\"mj-switch-thumb\"></span></span>\n @if (OnLabel || OffLabel) {\n <span class=\"mj-switch-label\">{{ Value ? OnLabel : OffLabel }}</span>\n }\n </button>\n `,\n providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => MJSwitchComponent), multi: true }]\n})\nexport class MJSwitchComponent implements ControlValueAccessor {\n @Input() OnLabel = '';\n @Input() OffLabel = '';\n @Input() Disabled = false;\n @HostBinding('class.mj-switch-host') readonly hostClass = true;\n\n Value = false;\n IsDisabled = false;\n private onChange: (value: boolean) => void = () => {};\n private onTouched: () => void = () => {};\n\n Toggle(): void { if (!this.IsDisabled) { this.Value = !this.Value; this.onChange(this.Value); } }\n OnTouched(): void { this.onTouched(); }\n writeValue(value: boolean): void { this.Value = !!value; }\n registerOnChange(fn: (value: boolean) => void): void { this.onChange = fn; }\n registerOnTouched(fn: () => void): void { this.onTouched = fn; }\n setDisabledState(isDisabled: boolean): void { this.IsDisabled = isDisabled || this.Disabled; }\n}\n"]}
1
+ {"version":3,"file":"switch.component.js","sourceRoot":"","sources":["../../../src/lib/switch/switch.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, forwardRef, HostBinding, ChangeDetectorRef, inject } from '@angular/core';\nimport { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';\n\n/**\n * mj-switch — Toggle switch. Replaces `<kendo-switch>`.\n */\n@Component({\n selector: 'mj-switch',\n standalone: true,\n template: `\n <button type=\"button\" role=\"switch\" class=\"mj-switch\"\n [class.mj-switch--on]=\"Value\" [class.mj-switch--disabled]=\"IsDisabled\"\n [attr.aria-checked]=\"Value\" [disabled]=\"IsDisabled\"\n (click)=\"Toggle()\" (blur)=\"OnTouched()\">\n <span class=\"mj-switch-track\"><span class=\"mj-switch-thumb\"></span></span>\n @if (OnLabel || OffLabel) {\n <span class=\"mj-switch-label\">{{ Value ? OnLabel : OffLabel }}</span>\n }\n </button>\n `,\n providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => MJSwitchComponent), multi: true }]\n})\nexport class MJSwitchComponent implements ControlValueAccessor {\n @Input() OnLabel = '';\n @Input() OffLabel = '';\n /**\n * Host-driven disable. Composed with Angular Forms' `setDisabledState()` into `IsDisabled`\n * (the actual gate) — see `syncDisabled`. A setter, not a bare field, because this input is\n * routinely bound to an expression that changes over the control's lifetime, and the gate has\n * to follow it every time.\n */\n @Input()\n set Disabled(value: boolean) { this.disabledInput = value; this.syncDisabled(); }\n get Disabled(): boolean { return this.disabledInput; }\n @HostBinding('class.mj-switch-host') readonly hostClass = true;\n\n Value = false;\n /** The gate on `Toggle()` — true when EITHER source says so. Assign only via `syncDisabled()`. */\n IsDisabled = false;\n private disabledInput = false;\n private formDisabled = false;\n private cdr = inject(ChangeDetectorRef);\n private onChange: (value: boolean) => void = () => {};\n private onTouched: () => void = () => {};\n\n /**\n * Recompute the gate from both of its sources. Called whenever either one changes.\n *\n * `IsDisabled` is derived state, and the only thing that assigned it was `setDisabledState()`.\n * The forms-driven half was in fact fine — `setUpControl` also wires `registerOnDisabledChange`,\n * so that hook fires on every `control.disable()`/`enable()`, not just at registration. What had\n * no recompute path at all was the `Disabled` @Input: a plain field, so the gate froze at\n * whatever the first compose produced and every later change to the input was dropped.\n */\n private syncDisabled(): void {\n const disabled = this.disabledInput || this.formDisabled;\n if (disabled === this.IsDisabled) return;\n this.IsDisabled = disabled;\n this.cdr.markForCheck();\n }\n\n Toggle(): void { if (!this.IsDisabled) { this.Value = !this.Value; this.onChange(this.Value); } }\n OnTouched(): void { this.onTouched(); }\n writeValue(value: boolean): void { this.Value = !!value; }\n registerOnChange(fn: (value: boolean) => void): void { this.onChange = fn; }\n registerOnTouched(fn: () => void): void { this.onTouched = fn; }\n setDisabledState(isDisabled: boolean): void { this.formDisabled = isDisabled; this.syncDisabled(); }\n}\n"]}
@@ -69,7 +69,7 @@ export class MJTabNavComponent {
69
69
  } if (rf & 2) {
70
70
  i0.ɵɵadvance();
71
71
  i0.ɵɵrepeater(ctx.Tabs);
72
- } }, styles: ["[_nghost-%COMP%] { display: inline-flex; }\n\n .mj-tab-nav[_ngcontent-%COMP%] {\n display: inline-flex;\n gap: var(--mj-space-1);\n padding: var(--mj-space-1);\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\n }\n\n .mj-tab-nav-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: var(--mj-space-2);\n padding: 7px var(--mj-space-3-5);\n background: transparent;\n border: none;\n border-radius: var(--mj-radius-md);\n color: var(--mj-text-secondary);\n font-family: inherit;\n font-size: 13px;\n font-weight: 500;\n line-height: 1.2;\n cursor: pointer;\n transition: background-color 0.15s ease, color 0.15s ease, box-shadow 0.15s ease;\n white-space: nowrap;\n }\n\n .mj-tab-nav-btn[_ngcontent-%COMP%]:hover:not(.mj-tab-nav-btn--active) {\n background: color-mix(in srgb, var(--mj-bg-surface) 70%, transparent);\n color: var(--mj-text-primary);\n }\n\n .mj-tab-nav-btn--active[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n box-shadow: 0 1px 3px color-mix(in srgb, var(--mj-text-primary) 12%, transparent);\n }\n\n .mj-tab-nav-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 13px;\n }\n\n .mj-tab-nav-label[_ngcontent-%COMP%] {\n font-weight: 500;\n }\n\n \n\n .mj-tab-nav-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 22px;\n height: 18px;\n padding: 0 var(--mj-space-1-5);\n border-radius: 9px;\n background: var(--mj-border-default);\n color: var(--mj-text-muted);\n font-size: 11px;\n font-weight: 600;\n line-height: 1;\n }\n\n .mj-tab-nav-btn--active[_ngcontent-%COMP%] .mj-tab-nav-badge[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n color: var(--mj-brand-primary);\n }\n\n .mj-tab-nav-badge--error[_ngcontent-%COMP%] {\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n }\n .mj-tab-nav-badge--warning[_ngcontent-%COMP%] {\n background: var(--mj-status-warning);\n color: var(--mj-text-inverse);\n }\n .mj-tab-nav-badge--success[_ngcontent-%COMP%] {\n background: var(--mj-status-success);\n color: var(--mj-text-inverse);\n }"] });
72
+ } }, styles: ["[_nghost-%COMP%] { display: inline-flex; }\n\n .mj-tab-nav[_ngcontent-%COMP%] {\n display: inline-flex;\n gap: var(--mj-space-1);\n padding: var(--mj-space-1);\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\n }\n\n .mj-tab-nav-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: var(--mj-space-2);\n padding: 7px var(--mj-space-3-5);\n background: transparent;\n border: none;\n border-radius: var(--mj-radius-md);\n color: var(--mj-text-secondary);\n font-family: inherit;\n font-size: 13px;\n font-weight: 500;\n line-height: 1.2;\n cursor: pointer;\n transition: background-color 0.15s ease, color 0.15s ease, box-shadow 0.15s ease;\n white-space: nowrap;\n }\n\n .mj-tab-nav-btn[_ngcontent-%COMP%]:hover:not(.mj-tab-nav-btn--active) {\n background: color-mix(in srgb, var(--mj-bg-surface) 70%, transparent);\n color: var(--mj-text-primary);\n }\n\n .mj-tab-nav-btn--active[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n box-shadow: 0 1px 3px color-mix(in srgb, var(--mj-text-primary) 12%, transparent);\n }\n\n .mj-tab-nav-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 13px;\n }\n\n .mj-tab-nav-label[_ngcontent-%COMP%] {\n font-weight: 500;\n }\n\n \n .mj-tab-nav-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 22px;\n height: 18px;\n padding: 0 var(--mj-space-1-5);\n border-radius: 9px;\n background: var(--mj-border-default);\n color: var(--mj-text-muted);\n font-size: 11px;\n font-weight: 600;\n line-height: 1;\n }\n\n .mj-tab-nav-btn--active[_ngcontent-%COMP%] .mj-tab-nav-badge[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n color: var(--mj-brand-primary);\n }\n\n .mj-tab-nav-badge--error[_ngcontent-%COMP%] {\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n }\n .mj-tab-nav-badge--warning[_ngcontent-%COMP%] {\n background: var(--mj-status-warning);\n color: var(--mj-text-inverse);\n }\n .mj-tab-nav-badge--success[_ngcontent-%COMP%] {\n background: var(--mj-status-success);\n color: var(--mj-text-inverse);\n }"] });
73
73
  }
74
74
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MJTabNavComponent, [{
75
75
  type: Component,
@@ -67,7 +67,7 @@ export class MJViewToggleComponent {
67
67
  } if (rf & 2) {
68
68
  i0.ɵɵadvance();
69
69
  i0.ɵɵrepeater(ctx.Options);
70
- } }, styles: ["[_nghost-%COMP%] { display: inline-flex; }\n\n .mj-view-toggle[_ngcontent-%COMP%] {\n display: inline-flex;\n gap: var(--mj-space-0-5);\n padding: 3px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n }\n\n .mj-view-toggle-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--mj-space-1-5);\n width: 28px;\n height: 28px;\n background: transparent;\n border: none;\n border-radius: var(--mj-radius-sm);\n color: var(--mj-text-muted);\n font-size: 13px;\n line-height: 1;\n cursor: pointer;\n transition: background-color 0.15s ease, color 0.15s ease;\n }\n\n \n\n .mj-view-toggle-btn--text[_ngcontent-%COMP%] {\n width: auto;\n padding: 0 var(--mj-space-3);\n font-weight: 600;\n }\n\n .mj-view-toggle-label[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n line-height: 1;\n white-space: nowrap;\n }\n\n .mj-view-toggle-btn[_ngcontent-%COMP%]:hover:not(.mj-view-toggle-btn--active) {\n background: color-mix(in srgb, var(--mj-bg-surface) 70%, transparent);\n color: var(--mj-text-primary);\n }\n\n .mj-view-toggle-btn--active[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n box-shadow: 0 1px 2px color-mix(in srgb, var(--mj-text-primary) 12%, transparent);\n }"] });
70
+ } }, styles: ["[_nghost-%COMP%] { display: inline-flex; }\n\n .mj-view-toggle[_ngcontent-%COMP%] {\n display: inline-flex;\n gap: var(--mj-space-0-5);\n padding: 3px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n }\n\n .mj-view-toggle-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--mj-space-1-5);\n width: 28px;\n height: 28px;\n background: transparent;\n border: none;\n border-radius: var(--mj-radius-sm);\n color: var(--mj-text-muted);\n font-size: 13px;\n line-height: 1;\n cursor: pointer;\n transition: background-color 0.15s ease, color 0.15s ease;\n }\n\n \n .mj-view-toggle-btn--text[_ngcontent-%COMP%] {\n width: auto;\n padding: 0 var(--mj-space-3);\n font-weight: 600;\n }\n\n .mj-view-toggle-label[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n line-height: 1;\n white-space: nowrap;\n }\n\n .mj-view-toggle-btn[_ngcontent-%COMP%]:hover:not(.mj-view-toggle-btn--active) {\n background: color-mix(in srgb, var(--mj-bg-surface) 70%, transparent);\n color: var(--mj-text-primary);\n }\n\n .mj-view-toggle-btn--active[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n box-shadow: 0 1px 2px color-mix(in srgb, var(--mj-text-primary) 12%, transparent);\n }"] });
71
71
  }
72
72
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MJViewToggleComponent, [{
73
73
  type: Component,
@@ -48,7 +48,7 @@ function MJWindowComponent_Conditional_0_Template(rf, ctx) { if (rf & 1) {
48
48
  i0.ɵɵconditionalCreate(3, MJWindowComponent_Conditional_0_Conditional_3_Template, 2, 2, "h3", 3);
49
49
  i0.ɵɵprojection(4);
50
50
  i0.ɵɵdomElementStart(5, "button", 4);
51
- i0.ɵɵdomListener("click", function MJWindowComponent_Conditional_0_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r1); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnCloseClick()); })("mousedown", function MJWindowComponent_Conditional_0_Template_button_mousedown_5_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView($event.stopPropagation()); });
51
+ i0.ɵɵdomListener("click", function MJWindowComponent_Conditional_0_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r1); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnCloseClick()); })("mousedown", function MJWindowComponent_Conditional_0_Template_button_mousedown_5_listener($event) { return $event.stopPropagation(); });
52
52
  i0.ɵɵdomElement(6, "i", 5);
53
53
  i0.ɵɵdomElementEnd()();
54
54
  i0.ɵɵdomElementStart(7, "div", 6);
@@ -1 +1 @@
1
- {"version":3,"file":"window.component.js","sourceRoot":"","sources":["../../../src/lib/window/window.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,EAAa,UAAU,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;;;;;;IA2CrI,iCAA2F;IAAzC,kNAAa,6BAAsB,GAAG,CAAC,KAAC;IAAC,oBAAM;IACjG,iCAA2F;IAAzC,kNAAa,6BAAsB,GAAG,CAAC,KAAC;IAAC,oBAAM;IACjG,iCAA2F;IAAzC,kNAAa,6BAAsB,GAAG,CAAC,KAAC;IAAC,oBAAM;IACjG,kCAA2F;IAAzC,kNAAa,6BAAsB,GAAG,CAAC,KAAC;IAAC,oBAAM;IACjG,kCAA6F;IAA1C,kNAAa,6BAAsB,IAAI,CAAC,KAAC;IAAC,oBAAM;IACnG,kCAA6F;IAA1C,kNAAa,6BAAsB,IAAI,CAAC,KAAC;IAAC,oBAAM;IACnG,kCAA6F;IAA1C,kNAAa,6BAAsB,IAAI,CAAC,KAAC;IAAC,oBAAM;IACnG,kCAA6F;IAA1C,kNAAa,6BAAsB,IAAI,CAAC,KAAC;IAAC,oBAAM;;;IAMjG,gCAAiE;IAAA,YAAW;IAAA,oBAAK;;;IAArD,4DAAoC;IAAC,cAAW;IAAX,kCAAW;;;;IAhClF,iCAewE;IAGtE,uFAA0C;IAW1C,iCACoC;IAAlC,mMAAa,0BAAmB,KAAC;IACjC,gGAAa;IAGb,kBAAqD;IACrD,oCAA0H;IAAjE,AAAzB,wLAAS,qBAAc,KAAC,mJAAc,wBAAwB,KAAC;IAC7F,0BAAiC;IAErC,AADE,oBAAS,EACL;IAEN,iCAA4B;IAC1B,qBAAyB;IAC3B,oBAAM;IAEN,qBAAoD;IACtD,oBAAM;;;IAhCJ,AADA,AADA,AADA,AADA,AADA,AADA,AADA,AADA,AADA,sFAA+D,0EACE,gEACV,kEACE,uCACpB,8DACgB,iEACG,8DACI,+DACC,4DACH;IAV1D,AADA,AADA,oEAAoD,0CACZ,0EACyB;;IAejE,cASC;IATD,2EASC;IAIC,eAEC;IAFD,uCAEC;;;AAvDX;;;;;;;;;;;;;;;;GAgBG;AAuDH,MAAM,OAAO,iBAAiB;IACpB,QAAQ,GAAG,KAAK,CAAC;IACjB,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;IAE1B,IACI,OAAO,CAAC,KAAc,IAAI,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC;IACtD,IAAI,OAAO,KAAc,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEvC,KAAK,GAAG,EAAE,CAAC;IACpB,IACI,KAAK,CAAC,KAA6B;QACrC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,IAAI,KAAK,IAAI,IAAI;YAAE,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC/D,CAAC;IACD,IAAI,KAAK,KAA6B,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IAE3D,IACI,MAAM,CAAC,KAA6B;QACtC,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACrB,IAAI,KAAK,IAAI,IAAI;YAAE,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAChE,CAAC;IACD,IAAI,MAAM,KAA6B,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IAC7D,IACI,GAAG,CAAC,KAAoB,IAAI,IAAI,KAAK,IAAI,IAAI;QAAE,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC;IAC7E,IAAI,GAAG,KAAoB,OAAO,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;IAEpD,IACI,IAAI,CAAC,KAAoB,IAAI,IAAI,KAAK,IAAI,IAAI;QAAE,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,CAAC,CAAC;IAC/E,IAAI,IAAI,KAAoB,OAAO,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;IAC7C,QAAQ,GAAkB,IAAI,CAAC;IAC/B,SAAS,GAAkB,IAAI,CAAC;IAChC,SAAS,GAAG,KAAK,CAAC;IAClB,SAAS,GAAG,KAAK,CAAC;IAE3B,8CAA8C;IAC9C,IACI,KAAK,CAAC,KAA8B;QACtC,IAAI,KAAK,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC;YAC1B,IAAI,KAAK,KAAK,WAAW,EAAE,CAAC;gBAC1B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC;gBAChC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC;gBAClC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,YAAY,CAAC;gBACpC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,aAAa,CAAC;YACxC,CAAC;iBAAM,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;gBACvC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC;gBAChC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC;gBAClC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,UAAU,CAAC;gBACpC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,WAAW,CAAC;YACxC,CAAC;YACD,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;YACpB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;IACD,IAAI,KAAK,KAA8B,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IAElD,KAAK,GAAG,IAAI,YAAY,EAAQ,CAAC;IACjC,WAAW,GAAG,IAAI,YAAY,EAA2B,CAAC;IAC1D,MAAM,GAAG,IAAI,YAAY,EAAQ,CAAC;IAE5C,QAAQ,GAAG,iBAAiB,CAAC,MAAM,EAAE,CAAC;IAEtC,kCAAkC;IAC1B,MAAM,GAA4B,SAAS,CAAC;IAC5C,MAAM,GAA2B,IAAI,CAAC;IACtC,OAAO,GAA2B,IAAI,CAAC;IACvC,UAAU,GAAkB,IAAI,CAAC;IACjC,WAAW,GAAkB,IAAI,CAAC;IAClC,YAAY,GAAkB,IAAI,CAAC;IACnC,aAAa,GAAkB,IAAI,CAAC;IAE5C,6CAA6C;IACrC,QAAQ,GAAkB,IAAI,CAAC;IAC/B,SAAS,GAAkB,IAAI,CAAC;IAChC,UAAU,GAAkB,IAAI,CAAC;IACjC,WAAW,GAAkB,IAAI,CAAC;IAE1C,aAAa;IACL,UAAU,GAAG,KAAK,CAAC;IACnB,UAAU,GAAG,CAAC,CAAC;IACf,UAAU,GAAG,CAAC,CAAC;IACf,YAAY,GAAG,CAAC,CAAC;IACjB,aAAa,GAAG,CAAC,CAAC;IAE1B,eAAe;IACP,UAAU,GAAG,KAAK,CAAC;IACnB,eAAe,GAAG,EAAE,CAAC;IACrB,YAAY,GAAG,CAAC,CAAC;IACjB,YAAY,GAAG,CAAC,CAAC;IACjB,gBAAgB,GAAG,CAAC,CAAC;IACrB,iBAAiB,GAAG,CAAC,CAAC;IACtB,cAAc,GAAG,CAAC,CAAC;IACnB,eAAe,GAAG,CAAC,CAAC;IAEpB,gBAAgB,GAAqC,IAAI,CAAC;IAC1D,cAAc,GAAqC,IAAI,CAAC;IAExD,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;IAChC,GAAG,GAAG,MAAM,CAAC,iBAAiB,CAAC,CAAC;IAChC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IAEhC,IAAI,mBAAmB;QACrB,OAAO,IAAI,CAAC,UAAU,IAAI,IAAI,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC;IAC7D,CAAC;IAED,IAAI,iBAAiB;QACnB,IAAI,IAAI,CAAC,KAAK,KAAK,WAAW;YAAE,OAAO,MAAM,CAAC;QAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC;QACvC,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC;QACzC,IAAI,MAAM,IAAI,OAAO;YAAE,OAAO,MAAM,CAAC;QACrC,IAAI,MAAM,IAAI,CAAC,OAAO;YAAE,OAAO,kBAAkB,CAAC;QAClD,IAAI,CAAC,MAAM,IAAI,OAAO;YAAE,OAAO,kBAAkB,CAAC;QAClD,OAAO,uBAAuB,CAAC;IACjC,CAAC;IAED,IAAI,aAAa;QACf,IAAI,IAAI,CAAC,YAAY,IAAI,IAAI;YAAE,OAAO,GAAG,IAAI,CAAC,YAAY,IAAI,CAAC;QAC/D,IAAI,IAAI,CAAC,KAAK;YAAE,OAAO,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;QACvF,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,IAAI,cAAc;QAChB,IAAI,IAAI,CAAC,aAAa,IAAI,IAAI;YAAE,OAAO,GAAG,IAAI,CAAC,aAAa,IAAI,CAAC;QACjE,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;QAC3F,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,UAAU,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;IAClE,CAAC;IAED,IAAI,YAAY;QACd,OAAO,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,WAAW,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;IACpE,CAAC;IAGD,WAAW;QACT,IAAI,IAAI,CAAC,OAAO;YAAE,IAAI,CAAC,YAAY,EAAE,CAAC;IACxC,CAAC;IAED,YAAY;QACV,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IACpB,CAAC;IAED,wBAAwB;IAExB,WAAW,CAAC,KAAiB;QAC3B,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,KAAK,KAAK,WAAW;YAAE,OAAO;QAC1D,iDAAiD;QACjD,IAAK,KAAK,CAAC,MAAsB,CAAC,OAAO,CAAC,QAAQ,CAAC;YAAE,OAAO;QAE5D,KAAK,CAAC,cAAc,EAAE,CAAC;QACvB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC;QAChC,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC;QAEhC,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACzC,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,IAAI,GAAG,QAAQ,CAAC,qBAAqB,EAAE,CAAC;YAC9C,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC;YAC7B,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC;YAE/B,+DAA+D;YAC/D,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,EAAE,CAAC;gBAC5B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC;gBAC3B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC;gBAC7B,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;YAC3B,CAAC;QACH,CAAC;QAED,IAAI,CAAC,oBAAoB,EAAE,CAAC;IAC9B,CAAC;IAED,0BAA0B;IAE1B,aAAa,CAAC,KAAiB,EAAE,SAAiB;QAChD,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,KAAK,KAAK,WAAW;YAAE,OAAO;QAC1D,KAAK,CAAC,cAAc,EAAE,CAAC;QACvB,KAAK,CAAC,eAAe,EAAE,CAAC;QAExB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,IAAI,CAAC,eAAe,GAAG,SAAS,CAAC;QACjC,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC;QAClC,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC;QAElC,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACzC,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,IAAI,GAAG,QAAQ,CAAC,qBAAqB,EAAE,CAAC;YAC9C,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,KAAK,CAAC;YACnC,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,MAAM,CAAC;YACrC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC;YAC/B,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC;YAEjC,8BAA8B;YAC9B,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,EAAE,CAAC;gBAC5B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC;gBAC3B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC;YAC/B,CAAC;YACD,IAAI,IAAI,CAAC,YAAY,IAAI,IAAI,EAAE,CAAC;gBAC9B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC;YACjC,CAAC;YACD,IAAI,IAAI,CAAC,aAAa,IAAI,IAAI,EAAE,CAAC;gBAC/B,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,MAAM,CAAC;YACnC,CAAC;QACH,CAAC;QAED,IAAI,CAAC,oBAAoB,EAAE,CAAC;IAC9B,CAAC;IAEO,oBAAoB;QAC1B,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,GAAG,EAAE;YACjC,IAAI,CAAC,gBAAgB,GAAG,CAAC,CAAa,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;YAC/D,IAAI,CAAC,cAAc,GAAG,CAAC,CAAa,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;YAC3D,QAAQ,CAAC,gBAAgB,CAAC,WAAW,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;YAC9D,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QAC5D,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,WAAW,CAAC,KAAiB;QACnC,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,MAAM,EAAE,GAAG,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC;YAC3C,MAAM,EAAE,GAAG,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC;YAC3C,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC,CAAC;YACtD,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC,CAAC;YACxD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC,CAAC;QAClD,CAAC;aAAM,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YAC3B,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;YACzB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE;gBACnB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;gBACzB,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YACrB,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAEO,YAAY,CAAC,KAAiB;QACpC,MAAM,EAAE,GAAG,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC;QAC7C,MAAM,EAAE,GAAG,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC;QAC7C,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,IAAI,GAAG,CAAC;QAClC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,IAAI,GAAG,CAAC;QACnC,MAAM,GAAG,GAAG,IAAI,CAAC,eAAe,CAAC;QAEjC,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YACtB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC,CAAC;QACjE,CAAC;QACD,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YACtB,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC,CAAC;YAC5D,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,eAAe,GAAG,CAAC,IAAI,CAAC,gBAAgB,GAAG,QAAQ,CAAC,CAAC;YAC7E,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAC;QAC/B,CAAC;QACD,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YACtB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC,CAAC;QACnE,CAAC;QACD,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YACtB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC,CAAC;YAC9D,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,cAAc,GAAG,CAAC,IAAI,CAAC,iBAAiB,GAAG,SAAS,CAAC,CAAC;YAC7E,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC;QACjC,CAAC;IACH,CAAC;IAEO,SAAS,CAAC,MAAkB;QAClC,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;QACxB,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;QACxB,IAAI,CAAC,oBAAoB,EAAE,CAAC;IAC9B,CAAC;IAEO,oBAAoB;QAC1B,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC1B,QAAQ,CAAC,mBAAmB,CAAC,WAAW,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;YACjE,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;QAC/B,CAAC;QACD,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,QAAQ,CAAC,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;YAC7D,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC7B,CAAC;IACH,CAAC;IAEO,gBAAgB;QACtB,OAAO,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;IACnE,CAAC;IAEO,SAAS,CAAC,KAAsB;QACtC,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAC;QAC5C,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC;QAC/E,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,GAAG,MAAM,CAAC,WAAW,CAAC;QAChF,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC;QACnD,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;QACjC,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;IACvC,CAAC;IAED,6CAA6C;IAC7C,WAAW,CAAC,GAAW,EAAE,IAAY;QACnC,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC;QACtB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC3B,CAAC;IAED,yCAAyC;IACzC,OAAO,CAAC,KAAa,EAAE,MAAc;QACnC,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;QAC1B,IAAI,CAAC,aAAa,GAAG,MAAM,CAAC;QAC5B,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC3B,CAAC;IAED,qDAAqD;IACrD,gBAAgB;QACd,OAAO,IAAI,CAAC,gBAAgB,EAAE,CAAC;IACjC,CAAC;IAED,WAAW;QACT,IAAI,CAAC,oBAAoB,EAAE,CAAC;IAC9B,CAAC;2GArTU,iBAAiB;6DAAjB,iBAAiB;YAAjB,wGAAA,iBAAa,0BAAI;;;YAlD1B,qFAAe;;YAAf,sCA+CC;;;iFAGQ,iBAAiB;cAtD7B,SAAS;eAAC;gBACT,QAAQ,EAAE,WAAW;gBACrB,UAAU,EAAE,IAAI;gBAChB,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDT;aACF;;kBAKE,KAAK;;kBAIL,KAAK;;kBACL,KAAK;;kBAOL,KAAK;;kBAML,KAAK;;kBAIL,KAAK;;kBAGL,KAAK;;kBACL,KAAK;;kBACL,KAAK;;kBACL,KAAK;;kBAGL,KAAK;;kBAoBL,MAAM;;kBACN,MAAM;;kBACN,MAAM;;kBA6EN,YAAY;mBAAC,yBAAyB;;kFAtI5B,iBAAiB;AAwT9B;;GAEG;AAOH,MAAM,OAAO,yBAAyB;mHAAzB,yBAAyB;6DAAzB,yBAAyB;;YAHzB,kBAAyB;;;iFAGzB,yBAAyB;cANrC,SAAS;2BACE,oBAAoB,cAClB,IAAI,YACN,2BAA2B;;kFAG1B,yBAAyB;AAEtC;;GAEG;AAMH,MAAM,OAAO,wBAAwB;kHAAxB,wBAAwB;6DAAxB,wBAAwB;;YAFxB,iCAA+B;YAAA,kBAAyB;YAAA,oBAAM;;;iFAE9D,wBAAwB;cALpC,SAAS;eAAC;gBACT,QAAQ,EAAE,mBAAmB;gBAC7B,UAAU,EAAE,IAAI;gBAChB,QAAQ,EAAE,gEAAgE;aAC3E;;kFACY,wBAAwB","sourcesContent":["import { Component, Input, Output, EventEmitter, HostListener, OnDestroy, ElementRef, ChangeDetectorRef, NgZone, inject } from '@angular/core';\n\n/**\n * mj-window — Floating window panel. Replaces `<kendo-window>`.\n *\n * Unlike mj-dialog, this does NOT have a backdrop and does NOT block interaction\n * with the rest of the page. It's a floating panel, similar to Kendo's Window.\n *\n * Supports dragging (via titlebar), resizing (via edges/corners), minimize, and maximize.\n *\n * @example\n * ```html\n * <mj-window [Visible]=\"showWindow\" Title=\"Details\" [Width]=\"600\" [Height]=\"400\"\n * [Draggable]=\"true\" [Resizable]=\"true\" (Close)=\"onClose()\"\n * (StateChange)=\"onStateChange($event)\">\n * <p>Window content</p>\n * </mj-window>\n * ```\n */\n@Component({\n selector: 'mj-window',\n standalone: true,\n template: `\n @if (Visible) {\n <div class=\"mj-window\"\n [class.mj-window--maximized]=\"State === 'maximized'\"\n [class.mj-window--draggable]=\"Draggable\"\n [class.mj-window--resizable]=\"Resizable && State !== 'maximized'\"\n [style.width]=\"State === 'maximized' ? '100vw' : resolvedWidth\"\n [style.height]=\"State === 'maximized' ? '100vh' : resolvedHeight\"\n [style.top]=\"State === 'maximized' ? '0' : resolvedTop\"\n [style.left]=\"State === 'maximized' ? '0' : resolvedLeft\"\n [style.transform]=\"ResolvedTransform\"\n [style.min-width]=\"MinWidth ? MinWidth + 'px' : null\"\n [style.min-height]=\"MinHeight ? MinHeight + 'px' : null\"\n [style.max-width]=\"State === 'maximized' ? '100vw' : '90vw'\"\n [style.max-height]=\"State === 'maximized' ? '100vh' : '90vh'\"\n [style.border-radius]=\"State === 'maximized' ? '0' : null\"\n role=\"dialog\"\n [attr.aria-labelledby]=\"Title ? 'mj-window-title-' + WindowId : null\">\n\n <!-- Resize handles -->\n @if (Resizable && State !== 'maximized') {\n <div class=\"mj-window-resize mj-window-resize--n\" (mousedown)=\"OnResizeStart($event, 'n')\"></div>\n <div class=\"mj-window-resize mj-window-resize--s\" (mousedown)=\"OnResizeStart($event, 's')\"></div>\n <div class=\"mj-window-resize mj-window-resize--e\" (mousedown)=\"OnResizeStart($event, 'e')\"></div>\n <div class=\"mj-window-resize mj-window-resize--w\" (mousedown)=\"OnResizeStart($event, 'w')\"></div>\n <div class=\"mj-window-resize mj-window-resize--ne\" (mousedown)=\"OnResizeStart($event, 'ne')\"></div>\n <div class=\"mj-window-resize mj-window-resize--nw\" (mousedown)=\"OnResizeStart($event, 'nw')\"></div>\n <div class=\"mj-window-resize mj-window-resize--se\" (mousedown)=\"OnResizeStart($event, 'se')\"></div>\n <div class=\"mj-window-resize mj-window-resize--sw\" (mousedown)=\"OnResizeStart($event, 'sw')\"></div>\n }\n\n <div class=\"mj-window-titlebar\"\n (mousedown)=\"OnDragStart($event)\">\n @if (Title) {\n <h3 class=\"mj-window-title\" [id]=\"'mj-window-title-' + WindowId\">{{ Title }}</h3>\n }\n <ng-content select=\"mj-window-titlebar\"></ng-content>\n <button class=\"mj-window-close\" (click)=\"OnCloseClick()\" (mousedown)=\"$event.stopPropagation()\" aria-label=\"Close window\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n <div class=\"mj-window-body\">\n <ng-content></ng-content>\n </div>\n\n <ng-content select=\"mj-window-actions\"></ng-content>\n </div>\n }\n `\n})\nexport class MJWindowComponent implements OnDestroy {\n private _visible = false;\n private static nextId = 0;\n\n @Input()\n set Visible(value: boolean) { this._visible = value; }\n get Visible(): boolean { return this._visible; }\n\n @Input() Title = '';\n @Input()\n set Width(value: number | string | null) {\n this._width = value;\n if (value != null) this.currentWidth = this.parseSize(value);\n }\n get Width(): number | string | null { return this._width; }\n\n @Input()\n set Height(value: number | string | null) {\n this._height = value;\n if (value != null) this.currentHeight = this.parseSize(value);\n }\n get Height(): number | string | null { return this._height; }\n @Input()\n set Top(value: number | null) { if (value != null) this.currentTop = value; }\n get Top(): number | null { return this.currentTop; }\n\n @Input()\n set Left(value: number | null) { if (value != null) this.currentLeft = value; }\n get Left(): number | null { return this.currentLeft; }\n @Input() MinWidth: number | null = null;\n @Input() MinHeight: number | null = null;\n @Input() Draggable = false;\n @Input() Resizable = false;\n\n /** Window state: 'default' or 'maximized'. */\n @Input()\n set State(value: 'default' | 'maximized') {\n if (value !== this._state) {\n if (value === 'maximized') {\n this.savedTop = this.currentTop;\n this.savedLeft = this.currentLeft;\n this.savedWidth = this.currentWidth;\n this.savedHeight = this.currentHeight;\n } else if (this._state === 'maximized') {\n this.currentTop = this.savedTop;\n this.currentLeft = this.savedLeft;\n this.currentWidth = this.savedWidth;\n this.currentHeight = this.savedHeight;\n }\n this._state = value;\n this.StateChange.emit(value);\n }\n }\n get State(): 'default' | 'maximized' { return this._state; }\n\n @Output() Close = new EventEmitter<void>();\n @Output() StateChange = new EventEmitter<'default' | 'maximized'>();\n @Output() Resize = new EventEmitter<void>();\n\n WindowId = MJWindowComponent.nextId++;\n\n // Internal position/size tracking\n private _state: 'default' | 'maximized' = 'default';\n private _width: number | string | null = null;\n private _height: number | string | null = null;\n private currentTop: number | null = null;\n private currentLeft: number | null = null;\n private currentWidth: number | null = null;\n private currentHeight: number | null = null;\n\n // Saved dimensions for restore from maximize\n private savedTop: number | null = null;\n private savedLeft: number | null = null;\n private savedWidth: number | null = null;\n private savedHeight: number | null = null;\n\n // Drag state\n private isDragging = false;\n private dragStartX = 0;\n private dragStartY = 0;\n private dragStartTop = 0;\n private dragStartLeft = 0;\n\n // Resize state\n private isResizing = false;\n private resizeDirection = '';\n private resizeStartX = 0;\n private resizeStartY = 0;\n private resizeStartWidth = 0;\n private resizeStartHeight = 0;\n private resizeStartTop = 0;\n private resizeStartLeft = 0;\n\n private boundOnMouseMove: ((e: MouseEvent) => void) | null = null;\n private boundOnMouseUp: ((e: MouseEvent) => void) | null = null;\n\n private elementRef = inject(ElementRef);\n private cdr = inject(ChangeDetectorRef);\n private ngZone = inject(NgZone);\n\n get hasExplicitPosition(): boolean {\n return this.currentTop != null && this.currentLeft != null;\n }\n\n get ResolvedTransform(): string {\n if (this.State === 'maximized') return 'none';\n const hasTop = this.currentTop != null;\n const hasLeft = this.currentLeft != null;\n if (hasTop && hasLeft) return 'none';\n if (hasTop && !hasLeft) return 'translateX(-50%)';\n if (!hasTop && hasLeft) return 'translateY(-50%)';\n return 'translate(-50%, -50%)';\n }\n\n get resolvedWidth(): string {\n if (this.currentWidth != null) return `${this.currentWidth}px`;\n if (this.Width) return typeof this.Width === 'number' ? `${this.Width}px` : this.Width;\n return '500px';\n }\n\n get resolvedHeight(): string {\n if (this.currentHeight != null) return `${this.currentHeight}px`;\n if (this.Height) return typeof this.Height === 'number' ? `${this.Height}px` : this.Height;\n return 'auto';\n }\n\n get resolvedTop(): string {\n return this.currentTop != null ? `${this.currentTop}px` : '50%';\n }\n\n get resolvedLeft(): string {\n return this.currentLeft != null ? `${this.currentLeft}px` : '50%';\n }\n\n @HostListener('document:keydown.escape')\n OnEscapeKey(): void {\n if (this.Visible) this.OnCloseClick();\n }\n\n OnCloseClick(): void {\n this.Close.emit();\n }\n\n // --- Drag handling ---\n\n OnDragStart(event: MouseEvent): void {\n if (!this.Draggable || this.State === 'maximized') return;\n // Don't drag if clicking buttons inside titlebar\n if ((event.target as HTMLElement).closest('button')) return;\n\n event.preventDefault();\n this.isDragging = true;\n this.dragStartX = event.clientX;\n this.dragStartY = event.clientY;\n\n const windowEl = this.getWindowElement();\n if (windowEl) {\n const rect = windowEl.getBoundingClientRect();\n this.dragStartTop = rect.top;\n this.dragStartLeft = rect.left;\n\n // Ensure we're using absolute positioning once dragging starts\n if (this.currentTop == null) {\n this.currentTop = rect.top;\n this.currentLeft = rect.left;\n this.cdr.detectChanges();\n }\n }\n\n this.attachMouseListeners();\n }\n\n // --- Resize handling ---\n\n OnResizeStart(event: MouseEvent, direction: string): void {\n if (!this.Resizable || this.State === 'maximized') return;\n event.preventDefault();\n event.stopPropagation();\n\n this.isResizing = true;\n this.resizeDirection = direction;\n this.resizeStartX = event.clientX;\n this.resizeStartY = event.clientY;\n\n const windowEl = this.getWindowElement();\n if (windowEl) {\n const rect = windowEl.getBoundingClientRect();\n this.resizeStartWidth = rect.width;\n this.resizeStartHeight = rect.height;\n this.resizeStartTop = rect.top;\n this.resizeStartLeft = rect.left;\n\n // Ensure absolute positioning\n if (this.currentTop == null) {\n this.currentTop = rect.top;\n this.currentLeft = rect.left;\n }\n if (this.currentWidth == null) {\n this.currentWidth = rect.width;\n }\n if (this.currentHeight == null) {\n this.currentHeight = rect.height;\n }\n }\n\n this.attachMouseListeners();\n }\n\n private attachMouseListeners(): void {\n this.ngZone.runOutsideAngular(() => {\n this.boundOnMouseMove = (e: MouseEvent) => this.onMouseMove(e);\n this.boundOnMouseUp = (e: MouseEvent) => this.onMouseUp(e);\n document.addEventListener('mousemove', this.boundOnMouseMove);\n document.addEventListener('mouseup', this.boundOnMouseUp);\n });\n }\n\n private onMouseMove(event: MouseEvent): void {\n if (this.isDragging) {\n const dx = event.clientX - this.dragStartX;\n const dy = event.clientY - this.dragStartY;\n this.currentTop = Math.max(0, this.dragStartTop + dy);\n this.currentLeft = Math.max(0, this.dragStartLeft + dx);\n this.ngZone.run(() => this.cdr.detectChanges());\n } else if (this.isResizing) {\n this.handleResize(event);\n this.ngZone.run(() => {\n this.cdr.detectChanges();\n this.Resize.emit();\n });\n }\n }\n\n private handleResize(event: MouseEvent): void {\n const dx = event.clientX - this.resizeStartX;\n const dy = event.clientY - this.resizeStartY;\n const minW = this.MinWidth || 200;\n const minH = this.MinHeight || 150;\n const dir = this.resizeDirection;\n\n if (dir.includes('e')) {\n this.currentWidth = Math.max(minW, this.resizeStartWidth + dx);\n }\n if (dir.includes('w')) {\n const newWidth = Math.max(minW, this.resizeStartWidth - dx);\n this.currentLeft = this.resizeStartLeft + (this.resizeStartWidth - newWidth);\n this.currentWidth = newWidth;\n }\n if (dir.includes('s')) {\n this.currentHeight = Math.max(minH, this.resizeStartHeight + dy);\n }\n if (dir.includes('n')) {\n const newHeight = Math.max(minH, this.resizeStartHeight - dy);\n this.currentTop = this.resizeStartTop + (this.resizeStartHeight - newHeight);\n this.currentHeight = newHeight;\n }\n }\n\n private onMouseUp(_event: MouseEvent): void {\n this.isDragging = false;\n this.isResizing = false;\n this.detachMouseListeners();\n }\n\n private detachMouseListeners(): void {\n if (this.boundOnMouseMove) {\n document.removeEventListener('mousemove', this.boundOnMouseMove);\n this.boundOnMouseMove = null;\n }\n if (this.boundOnMouseUp) {\n document.removeEventListener('mouseup', this.boundOnMouseUp);\n this.boundOnMouseUp = null;\n }\n }\n\n private getWindowElement(): HTMLElement | null {\n return this.elementRef.nativeElement.querySelector('.mj-window');\n }\n\n private parseSize(value: string | number): number | null {\n if (typeof value === 'number') return value;\n if (value.endsWith('vw')) return (parseFloat(value) / 100) * window.innerWidth;\n if (value.endsWith('vh')) return (parseFloat(value) / 100) * window.innerHeight;\n if (value.endsWith('px')) return parseFloat(value);\n const parsed = parseFloat(value);\n return isNaN(parsed) ? null : parsed;\n }\n\n /** Programmatic method to update position */\n SetPosition(top: number, left: number): void {\n this.currentTop = top;\n this.currentLeft = left;\n this.cdr.detectChanges();\n }\n\n /** Programmatic method to update size */\n SetSize(width: number, height: number): void {\n this.currentWidth = width;\n this.currentHeight = height;\n this.cdr.detectChanges();\n }\n\n /** Get the current window element for DOM queries */\n GetWindowElement(): HTMLElement | null {\n return this.getWindowElement();\n }\n\n ngOnDestroy(): void {\n this.detachMouseListeners();\n }\n}\n\n/**\n * mj-window-titlebar — Custom titlebar for mj-window. Replaces `<kendo-window-titlebar>`.\n */\n@Component({\n selector: 'mj-window-titlebar',\n standalone: true,\n template: `<ng-content></ng-content>`,\n styles: [`:host { display: contents; }`]\n})\nexport class MJWindowTitlebarComponent {}\n\n/**\n * mj-window-actions — Footer actions for mj-window.\n */\n@Component({\n selector: 'mj-window-actions',\n standalone: true,\n template: `<div class=\"mj-window-actions\"><ng-content></ng-content></div>`\n})\nexport class MJWindowActionsComponent {}\n"]}
1
+ {"version":3,"file":"window.component.js","sourceRoot":"","sources":["../../../src/lib/window/window.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,EAAa,UAAU,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;;;;;;IA2CrI,iCAA2F;IAAzC,kNAAa,6BAAsB,GAAG,CAAC,KAAC;IAAC,oBAAM;IACjG,iCAA2F;IAAzC,kNAAa,6BAAsB,GAAG,CAAC,KAAC;IAAC,oBAAM;IACjG,iCAA2F;IAAzC,kNAAa,6BAAsB,GAAG,CAAC,KAAC;IAAC,oBAAM;IACjG,kCAA2F;IAAzC,kNAAa,6BAAsB,GAAG,CAAC,KAAC;IAAC,oBAAM;IACjG,kCAA6F;IAA1C,kNAAa,6BAAsB,IAAI,CAAC,KAAC;IAAC,oBAAM;IACnG,kCAA6F;IAA1C,kNAAa,6BAAsB,IAAI,CAAC,KAAC;IAAC,oBAAM;IACnG,kCAA6F;IAA1C,kNAAa,6BAAsB,IAAI,CAAC,KAAC;IAAC,oBAAM;IACnG,kCAA6F;IAA1C,kNAAa,6BAAsB,IAAI,CAAC,KAAC;IAAC,oBAAM;;;IAMjG,gCAAiE;IAAA,YAAW;IAAA,oBAAK;;;IAArD,4DAAoC;IAAC,cAAW;IAAX,kCAAW;;;;IAhClF,iCAewE;IAGtE,uFAA0C;IAW1C,iCACoC;IAAlC,mMAAa,0BAAmB,KAAC;IACjC,gGAAa;IAGb,kBAAqD;IACrD,oCAA0H;IAAjE,AAAzB,wLAAS,qBAAc,KAAC,6GAAc,wBAAwB,IAAC;IAC7F,0BAAiC;IAErC,AADE,oBAAS,EACL;IAEN,iCAA4B;IAC1B,qBAAyB;IAC3B,oBAAM;IAEN,qBAAoD;IACtD,oBAAM;;;IAhCJ,AADA,AADA,AADA,AADA,AADA,AADA,AADA,AADA,AADA,sFAA+D,0EACE,gEACV,kEACE,uCACpB,8DACgB,iEACG,8DACI,+DACC,4DACH;IAV1D,AADA,AADA,oEAAoD,0CACZ,0EACyB;;IAejE,cASC;IATD,2EASC;IAIC,eAEC;IAFD,uCAEC;;;AAvDX;;;;;;;;;;;;;;;;GAgBG;AAuDH,MAAM,OAAO,iBAAiB;IACpB,QAAQ,GAAG,KAAK,CAAC;IACjB,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;IAE1B,IACI,OAAO,CAAC,KAAc,IAAI,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC;IACtD,IAAI,OAAO,KAAc,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEvC,KAAK,GAAG,EAAE,CAAC;IACpB,IACI,KAAK,CAAC,KAA6B;QACrC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,IAAI,KAAK,IAAI,IAAI;YAAE,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC/D,CAAC;IACD,IAAI,KAAK,KAA6B,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IAE3D,IACI,MAAM,CAAC,KAA6B;QACtC,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACrB,IAAI,KAAK,IAAI,IAAI;YAAE,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAChE,CAAC;IACD,IAAI,MAAM,KAA6B,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IAC7D,IACI,GAAG,CAAC,KAAoB,IAAI,IAAI,KAAK,IAAI,IAAI;QAAE,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC;IAC7E,IAAI,GAAG,KAAoB,OAAO,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;IAEpD,IACI,IAAI,CAAC,KAAoB,IAAI,IAAI,KAAK,IAAI,IAAI;QAAE,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,CAAC,CAAC;IAC/E,IAAI,IAAI,KAAoB,OAAO,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;IAC7C,QAAQ,GAAkB,IAAI,CAAC;IAC/B,SAAS,GAAkB,IAAI,CAAC;IAChC,SAAS,GAAG,KAAK,CAAC;IAClB,SAAS,GAAG,KAAK,CAAC;IAE3B,8CAA8C;IAC9C,IACI,KAAK,CAAC,KAA8B;QACtC,IAAI,KAAK,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC;YAC1B,IAAI,KAAK,KAAK,WAAW,EAAE,CAAC;gBAC1B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC;gBAChC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC;gBAClC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,YAAY,CAAC;gBACpC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,aAAa,CAAC;YACxC,CAAC;iBAAM,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;gBACvC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC;gBAChC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC;gBAClC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,UAAU,CAAC;gBACpC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,WAAW,CAAC;YACxC,CAAC;YACD,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;YACpB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;IACD,IAAI,KAAK,KAA8B,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IAElD,KAAK,GAAG,IAAI,YAAY,EAAQ,CAAC;IACjC,WAAW,GAAG,IAAI,YAAY,EAA2B,CAAC;IAC1D,MAAM,GAAG,IAAI,YAAY,EAAQ,CAAC;IAE5C,QAAQ,GAAG,iBAAiB,CAAC,MAAM,EAAE,CAAC;IAEtC,kCAAkC;IAC1B,MAAM,GAA4B,SAAS,CAAC;IAC5C,MAAM,GAA2B,IAAI,CAAC;IACtC,OAAO,GAA2B,IAAI,CAAC;IACvC,UAAU,GAAkB,IAAI,CAAC;IACjC,WAAW,GAAkB,IAAI,CAAC;IAClC,YAAY,GAAkB,IAAI,CAAC;IACnC,aAAa,GAAkB,IAAI,CAAC;IAE5C,6CAA6C;IACrC,QAAQ,GAAkB,IAAI,CAAC;IAC/B,SAAS,GAAkB,IAAI,CAAC;IAChC,UAAU,GAAkB,IAAI,CAAC;IACjC,WAAW,GAAkB,IAAI,CAAC;IAE1C,aAAa;IACL,UAAU,GAAG,KAAK,CAAC;IACnB,UAAU,GAAG,CAAC,CAAC;IACf,UAAU,GAAG,CAAC,CAAC;IACf,YAAY,GAAG,CAAC,CAAC;IACjB,aAAa,GAAG,CAAC,CAAC;IAE1B,eAAe;IACP,UAAU,GAAG,KAAK,CAAC;IACnB,eAAe,GAAG,EAAE,CAAC;IACrB,YAAY,GAAG,CAAC,CAAC;IACjB,YAAY,GAAG,CAAC,CAAC;IACjB,gBAAgB,GAAG,CAAC,CAAC;IACrB,iBAAiB,GAAG,CAAC,CAAC;IACtB,cAAc,GAAG,CAAC,CAAC;IACnB,eAAe,GAAG,CAAC,CAAC;IAEpB,gBAAgB,GAAqC,IAAI,CAAC;IAC1D,cAAc,GAAqC,IAAI,CAAC;IAExD,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;IAChC,GAAG,GAAG,MAAM,CAAC,iBAAiB,CAAC,CAAC;IAChC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IAEhC,IAAI,mBAAmB;QACrB,OAAO,IAAI,CAAC,UAAU,IAAI,IAAI,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC;IAC7D,CAAC;IAED,IAAI,iBAAiB;QACnB,IAAI,IAAI,CAAC,KAAK,KAAK,WAAW;YAAE,OAAO,MAAM,CAAC;QAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC;QACvC,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC;QACzC,IAAI,MAAM,IAAI,OAAO;YAAE,OAAO,MAAM,CAAC;QACrC,IAAI,MAAM,IAAI,CAAC,OAAO;YAAE,OAAO,kBAAkB,CAAC;QAClD,IAAI,CAAC,MAAM,IAAI,OAAO;YAAE,OAAO,kBAAkB,CAAC;QAClD,OAAO,uBAAuB,CAAC;IACjC,CAAC;IAED,IAAI,aAAa;QACf,IAAI,IAAI,CAAC,YAAY,IAAI,IAAI;YAAE,OAAO,GAAG,IAAI,CAAC,YAAY,IAAI,CAAC;QAC/D,IAAI,IAAI,CAAC,KAAK;YAAE,OAAO,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;QACvF,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,IAAI,cAAc;QAChB,IAAI,IAAI,CAAC,aAAa,IAAI,IAAI;YAAE,OAAO,GAAG,IAAI,CAAC,aAAa,IAAI,CAAC;QACjE,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;QAC3F,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,UAAU,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;IAClE,CAAC;IAED,IAAI,YAAY;QACd,OAAO,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,WAAW,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;IACpE,CAAC;IAGD,WAAW;QACT,IAAI,IAAI,CAAC,OAAO;YAAE,IAAI,CAAC,YAAY,EAAE,CAAC;IACxC,CAAC;IAED,YAAY;QACV,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IACpB,CAAC;IAED,wBAAwB;IAExB,WAAW,CAAC,KAAiB;QAC3B,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,KAAK,KAAK,WAAW;YAAE,OAAO;QAC1D,iDAAiD;QACjD,IAAK,KAAK,CAAC,MAAsB,CAAC,OAAO,CAAC,QAAQ,CAAC;YAAE,OAAO;QAE5D,KAAK,CAAC,cAAc,EAAE,CAAC;QACvB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC;QAChC,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC;QAEhC,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACzC,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,IAAI,GAAG,QAAQ,CAAC,qBAAqB,EAAE,CAAC;YAC9C,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC;YAC7B,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC;YAE/B,+DAA+D;YAC/D,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,EAAE,CAAC;gBAC5B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC;gBAC3B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC;gBAC7B,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;YAC3B,CAAC;QACH,CAAC;QAED,IAAI,CAAC,oBAAoB,EAAE,CAAC;IAC9B,CAAC;IAED,0BAA0B;IAE1B,aAAa,CAAC,KAAiB,EAAE,SAAiB;QAChD,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,KAAK,KAAK,WAAW;YAAE,OAAO;QAC1D,KAAK,CAAC,cAAc,EAAE,CAAC;QACvB,KAAK,CAAC,eAAe,EAAE,CAAC;QAExB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,IAAI,CAAC,eAAe,GAAG,SAAS,CAAC;QACjC,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC;QAClC,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC;QAElC,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACzC,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,IAAI,GAAG,QAAQ,CAAC,qBAAqB,EAAE,CAAC;YAC9C,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,KAAK,CAAC;YACnC,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,MAAM,CAAC;YACrC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC;YAC/B,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC;YAEjC,8BAA8B;YAC9B,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,EAAE,CAAC;gBAC5B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC;gBAC3B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC;YAC/B,CAAC;YACD,IAAI,IAAI,CAAC,YAAY,IAAI,IAAI,EAAE,CAAC;gBAC9B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC;YACjC,CAAC;YACD,IAAI,IAAI,CAAC,aAAa,IAAI,IAAI,EAAE,CAAC;gBAC/B,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,MAAM,CAAC;YACnC,CAAC;QACH,CAAC;QAED,IAAI,CAAC,oBAAoB,EAAE,CAAC;IAC9B,CAAC;IAEO,oBAAoB;QAC1B,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,GAAG,EAAE;YACjC,IAAI,CAAC,gBAAgB,GAAG,CAAC,CAAa,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;YAC/D,IAAI,CAAC,cAAc,GAAG,CAAC,CAAa,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;YAC3D,QAAQ,CAAC,gBAAgB,CAAC,WAAW,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;YAC9D,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QAC5D,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,WAAW,CAAC,KAAiB;QACnC,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,MAAM,EAAE,GAAG,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC;YAC3C,MAAM,EAAE,GAAG,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC;YAC3C,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC,CAAC;YACtD,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC,CAAC;YACxD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC,CAAC;QAClD,CAAC;aAAM,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YAC3B,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;YACzB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE;gBACnB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;gBACzB,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YACrB,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAEO,YAAY,CAAC,KAAiB;QACpC,MAAM,EAAE,GAAG,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC;QAC7C,MAAM,EAAE,GAAG,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC;QAC7C,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,IAAI,GAAG,CAAC;QAClC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,IAAI,GAAG,CAAC;QACnC,MAAM,GAAG,GAAG,IAAI,CAAC,eAAe,CAAC;QAEjC,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YACtB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC,CAAC;QACjE,CAAC;QACD,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YACtB,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC,CAAC;YAC5D,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,eAAe,GAAG,CAAC,IAAI,CAAC,gBAAgB,GAAG,QAAQ,CAAC,CAAC;YAC7E,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAC;QAC/B,CAAC;QACD,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YACtB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC,CAAC;QACnE,CAAC;QACD,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YACtB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC,CAAC;YAC9D,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,cAAc,GAAG,CAAC,IAAI,CAAC,iBAAiB,GAAG,SAAS,CAAC,CAAC;YAC7E,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC;QACjC,CAAC;IACH,CAAC;IAEO,SAAS,CAAC,MAAkB;QAClC,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;QACxB,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;QACxB,IAAI,CAAC,oBAAoB,EAAE,CAAC;IAC9B,CAAC;IAEO,oBAAoB;QAC1B,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC1B,QAAQ,CAAC,mBAAmB,CAAC,WAAW,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;YACjE,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;QAC/B,CAAC;QACD,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,QAAQ,CAAC,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;YAC7D,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC7B,CAAC;IACH,CAAC;IAEO,gBAAgB;QACtB,OAAO,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;IACnE,CAAC;IAEO,SAAS,CAAC,KAAsB;QACtC,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAC;QAC5C,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC;QAC/E,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,GAAG,MAAM,CAAC,WAAW,CAAC;QAChF,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC;QACnD,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;QACjC,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;IACvC,CAAC;IAED,6CAA6C;IAC7C,WAAW,CAAC,GAAW,EAAE,IAAY;QACnC,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC;QACtB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC3B,CAAC;IAED,yCAAyC;IACzC,OAAO,CAAC,KAAa,EAAE,MAAc;QACnC,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;QAC1B,IAAI,CAAC,aAAa,GAAG,MAAM,CAAC;QAC5B,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC3B,CAAC;IAED,qDAAqD;IACrD,gBAAgB;QACd,OAAO,IAAI,CAAC,gBAAgB,EAAE,CAAC;IACjC,CAAC;IAED,WAAW;QACT,IAAI,CAAC,oBAAoB,EAAE,CAAC;IAC9B,CAAC;2GArTU,iBAAiB;6DAAjB,iBAAiB;YAAjB,wGAAA,iBAAa,0BAAI;;;YAlD1B,qFAAe;;YAAf,sCA+CC;;;iFAGQ,iBAAiB;cAtD7B,SAAS;eAAC;gBACT,QAAQ,EAAE,WAAW;gBACrB,UAAU,EAAE,IAAI;gBAChB,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDT;aACF;;kBAKE,KAAK;;kBAIL,KAAK;;kBACL,KAAK;;kBAOL,KAAK;;kBAML,KAAK;;kBAIL,KAAK;;kBAGL,KAAK;;kBACL,KAAK;;kBACL,KAAK;;kBACL,KAAK;;kBAGL,KAAK;;kBAoBL,MAAM;;kBACN,MAAM;;kBACN,MAAM;;kBA6EN,YAAY;mBAAC,yBAAyB;;kFAtI5B,iBAAiB;AAwT9B;;GAEG;AAOH,MAAM,OAAO,yBAAyB;mHAAzB,yBAAyB;6DAAzB,yBAAyB;;YAHzB,kBAAyB;;;iFAGzB,yBAAyB;cANrC,SAAS;2BACE,oBAAoB,cAClB,IAAI,YACN,2BAA2B;;kFAG1B,yBAAyB;AAEtC;;GAEG;AAMH,MAAM,OAAO,wBAAwB;kHAAxB,wBAAwB;6DAAxB,wBAAwB;;YAFxB,iCAA+B;YAAA,kBAAyB;YAAA,oBAAM;;;iFAE9D,wBAAwB;cALpC,SAAS;eAAC;gBACT,QAAQ,EAAE,mBAAmB;gBAC7B,UAAU,EAAE,IAAI;gBAChB,QAAQ,EAAE,gEAAgE;aAC3E;;kFACY,wBAAwB","sourcesContent":["import { Component, Input, Output, EventEmitter, HostListener, OnDestroy, ElementRef, ChangeDetectorRef, NgZone, inject } from '@angular/core';\n\n/**\n * mj-window — Floating window panel. Replaces `<kendo-window>`.\n *\n * Unlike mj-dialog, this does NOT have a backdrop and does NOT block interaction\n * with the rest of the page. It's a floating panel, similar to Kendo's Window.\n *\n * Supports dragging (via titlebar), resizing (via edges/corners), minimize, and maximize.\n *\n * @example\n * ```html\n * <mj-window [Visible]=\"showWindow\" Title=\"Details\" [Width]=\"600\" [Height]=\"400\"\n * [Draggable]=\"true\" [Resizable]=\"true\" (Close)=\"onClose()\"\n * (StateChange)=\"onStateChange($event)\">\n * <p>Window content</p>\n * </mj-window>\n * ```\n */\n@Component({\n selector: 'mj-window',\n standalone: true,\n template: `\n @if (Visible) {\n <div class=\"mj-window\"\n [class.mj-window--maximized]=\"State === 'maximized'\"\n [class.mj-window--draggable]=\"Draggable\"\n [class.mj-window--resizable]=\"Resizable && State !== 'maximized'\"\n [style.width]=\"State === 'maximized' ? '100vw' : resolvedWidth\"\n [style.height]=\"State === 'maximized' ? '100vh' : resolvedHeight\"\n [style.top]=\"State === 'maximized' ? '0' : resolvedTop\"\n [style.left]=\"State === 'maximized' ? '0' : resolvedLeft\"\n [style.transform]=\"ResolvedTransform\"\n [style.min-width]=\"MinWidth ? MinWidth + 'px' : null\"\n [style.min-height]=\"MinHeight ? MinHeight + 'px' : null\"\n [style.max-width]=\"State === 'maximized' ? '100vw' : '90vw'\"\n [style.max-height]=\"State === 'maximized' ? '100vh' : '90vh'\"\n [style.border-radius]=\"State === 'maximized' ? '0' : null\"\n role=\"dialog\"\n [attr.aria-labelledby]=\"Title ? 'mj-window-title-' + WindowId : null\">\n\n <!-- Resize handles -->\n @if (Resizable && State !== 'maximized') {\n <div class=\"mj-window-resize mj-window-resize--n\" (mousedown)=\"OnResizeStart($event, 'n')\"></div>\n <div class=\"mj-window-resize mj-window-resize--s\" (mousedown)=\"OnResizeStart($event, 's')\"></div>\n <div class=\"mj-window-resize mj-window-resize--e\" (mousedown)=\"OnResizeStart($event, 'e')\"></div>\n <div class=\"mj-window-resize mj-window-resize--w\" (mousedown)=\"OnResizeStart($event, 'w')\"></div>\n <div class=\"mj-window-resize mj-window-resize--ne\" (mousedown)=\"OnResizeStart($event, 'ne')\"></div>\n <div class=\"mj-window-resize mj-window-resize--nw\" (mousedown)=\"OnResizeStart($event, 'nw')\"></div>\n <div class=\"mj-window-resize mj-window-resize--se\" (mousedown)=\"OnResizeStart($event, 'se')\"></div>\n <div class=\"mj-window-resize mj-window-resize--sw\" (mousedown)=\"OnResizeStart($event, 'sw')\"></div>\n }\n\n <div class=\"mj-window-titlebar\"\n (mousedown)=\"OnDragStart($event)\">\n @if (Title) {\n <h3 class=\"mj-window-title\" [id]=\"'mj-window-title-' + WindowId\">{{ Title }}</h3>\n }\n <ng-content select=\"mj-window-titlebar\"></ng-content>\n <button class=\"mj-window-close\" (click)=\"OnCloseClick()\" (mousedown)=\"$event.stopPropagation()\" aria-label=\"Close window\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n <div class=\"mj-window-body\">\n <ng-content></ng-content>\n </div>\n\n <ng-content select=\"mj-window-actions\"></ng-content>\n </div>\n }\n `\n})\nexport class MJWindowComponent implements OnDestroy {\n private _visible = false;\n private static nextId = 0;\n\n @Input()\n set Visible(value: boolean) { this._visible = value; }\n get Visible(): boolean { return this._visible; }\n\n @Input() Title = '';\n @Input()\n set Width(value: number | string | null) {\n this._width = value;\n if (value != null) this.currentWidth = this.parseSize(value);\n }\n get Width(): number | string | null { return this._width; }\n\n @Input()\n set Height(value: number | string | null) {\n this._height = value;\n if (value != null) this.currentHeight = this.parseSize(value);\n }\n get Height(): number | string | null { return this._height; }\n @Input()\n set Top(value: number | null) { if (value != null) this.currentTop = value; }\n get Top(): number | null { return this.currentTop; }\n\n @Input()\n set Left(value: number | null) { if (value != null) this.currentLeft = value; }\n get Left(): number | null { return this.currentLeft; }\n @Input() MinWidth: number | null = null;\n @Input() MinHeight: number | null = null;\n @Input() Draggable = false;\n @Input() Resizable = false;\n\n /** Window state: 'default' or 'maximized'. */\n @Input()\n set State(value: 'default' | 'maximized') {\n if (value !== this._state) {\n if (value === 'maximized') {\n this.savedTop = this.currentTop;\n this.savedLeft = this.currentLeft;\n this.savedWidth = this.currentWidth;\n this.savedHeight = this.currentHeight;\n } else if (this._state === 'maximized') {\n this.currentTop = this.savedTop;\n this.currentLeft = this.savedLeft;\n this.currentWidth = this.savedWidth;\n this.currentHeight = this.savedHeight;\n }\n this._state = value;\n this.StateChange.emit(value);\n }\n }\n get State(): 'default' | 'maximized' { return this._state; }\n\n @Output() Close = new EventEmitter<void>();\n @Output() StateChange = new EventEmitter<'default' | 'maximized'>();\n @Output() Resize = new EventEmitter<void>();\n\n WindowId = MJWindowComponent.nextId++;\n\n // Internal position/size tracking\n private _state: 'default' | 'maximized' = 'default';\n private _width: number | string | null = null;\n private _height: number | string | null = null;\n private currentTop: number | null = null;\n private currentLeft: number | null = null;\n private currentWidth: number | null = null;\n private currentHeight: number | null = null;\n\n // Saved dimensions for restore from maximize\n private savedTop: number | null = null;\n private savedLeft: number | null = null;\n private savedWidth: number | null = null;\n private savedHeight: number | null = null;\n\n // Drag state\n private isDragging = false;\n private dragStartX = 0;\n private dragStartY = 0;\n private dragStartTop = 0;\n private dragStartLeft = 0;\n\n // Resize state\n private isResizing = false;\n private resizeDirection = '';\n private resizeStartX = 0;\n private resizeStartY = 0;\n private resizeStartWidth = 0;\n private resizeStartHeight = 0;\n private resizeStartTop = 0;\n private resizeStartLeft = 0;\n\n private boundOnMouseMove: ((e: MouseEvent) => void) | null = null;\n private boundOnMouseUp: ((e: MouseEvent) => void) | null = null;\n\n private elementRef = inject(ElementRef);\n private cdr = inject(ChangeDetectorRef);\n private ngZone = inject(NgZone);\n\n get hasExplicitPosition(): boolean {\n return this.currentTop != null && this.currentLeft != null;\n }\n\n get ResolvedTransform(): string {\n if (this.State === 'maximized') return 'none';\n const hasTop = this.currentTop != null;\n const hasLeft = this.currentLeft != null;\n if (hasTop && hasLeft) return 'none';\n if (hasTop && !hasLeft) return 'translateX(-50%)';\n if (!hasTop && hasLeft) return 'translateY(-50%)';\n return 'translate(-50%, -50%)';\n }\n\n get resolvedWidth(): string {\n if (this.currentWidth != null) return `${this.currentWidth}px`;\n if (this.Width) return typeof this.Width === 'number' ? `${this.Width}px` : this.Width;\n return '500px';\n }\n\n get resolvedHeight(): string {\n if (this.currentHeight != null) return `${this.currentHeight}px`;\n if (this.Height) return typeof this.Height === 'number' ? `${this.Height}px` : this.Height;\n return 'auto';\n }\n\n get resolvedTop(): string {\n return this.currentTop != null ? `${this.currentTop}px` : '50%';\n }\n\n get resolvedLeft(): string {\n return this.currentLeft != null ? `${this.currentLeft}px` : '50%';\n }\n\n @HostListener('document:keydown.escape')\n OnEscapeKey(): void {\n if (this.Visible) this.OnCloseClick();\n }\n\n OnCloseClick(): void {\n this.Close.emit();\n }\n\n // --- Drag handling ---\n\n OnDragStart(event: MouseEvent): void {\n if (!this.Draggable || this.State === 'maximized') return;\n // Don't drag if clicking buttons inside titlebar\n if ((event.target as HTMLElement).closest('button')) return;\n\n event.preventDefault();\n this.isDragging = true;\n this.dragStartX = event.clientX;\n this.dragStartY = event.clientY;\n\n const windowEl = this.getWindowElement();\n if (windowEl) {\n const rect = windowEl.getBoundingClientRect();\n this.dragStartTop = rect.top;\n this.dragStartLeft = rect.left;\n\n // Ensure we're using absolute positioning once dragging starts\n if (this.currentTop == null) {\n this.currentTop = rect.top;\n this.currentLeft = rect.left;\n this.cdr.detectChanges();\n }\n }\n\n this.attachMouseListeners();\n }\n\n // --- Resize handling ---\n\n OnResizeStart(event: MouseEvent, direction: string): void {\n if (!this.Resizable || this.State === 'maximized') return;\n event.preventDefault();\n event.stopPropagation();\n\n this.isResizing = true;\n this.resizeDirection = direction;\n this.resizeStartX = event.clientX;\n this.resizeStartY = event.clientY;\n\n const windowEl = this.getWindowElement();\n if (windowEl) {\n const rect = windowEl.getBoundingClientRect();\n this.resizeStartWidth = rect.width;\n this.resizeStartHeight = rect.height;\n this.resizeStartTop = rect.top;\n this.resizeStartLeft = rect.left;\n\n // Ensure absolute positioning\n if (this.currentTop == null) {\n this.currentTop = rect.top;\n this.currentLeft = rect.left;\n }\n if (this.currentWidth == null) {\n this.currentWidth = rect.width;\n }\n if (this.currentHeight == null) {\n this.currentHeight = rect.height;\n }\n }\n\n this.attachMouseListeners();\n }\n\n private attachMouseListeners(): void {\n this.ngZone.runOutsideAngular(() => {\n this.boundOnMouseMove = (e: MouseEvent) => this.onMouseMove(e);\n this.boundOnMouseUp = (e: MouseEvent) => this.onMouseUp(e);\n document.addEventListener('mousemove', this.boundOnMouseMove);\n document.addEventListener('mouseup', this.boundOnMouseUp);\n });\n }\n\n private onMouseMove(event: MouseEvent): void {\n if (this.isDragging) {\n const dx = event.clientX - this.dragStartX;\n const dy = event.clientY - this.dragStartY;\n this.currentTop = Math.max(0, this.dragStartTop + dy);\n this.currentLeft = Math.max(0, this.dragStartLeft + dx);\n this.ngZone.run(() => this.cdr.detectChanges());\n } else if (this.isResizing) {\n this.handleResize(event);\n this.ngZone.run(() => {\n this.cdr.detectChanges();\n this.Resize.emit();\n });\n }\n }\n\n private handleResize(event: MouseEvent): void {\n const dx = event.clientX - this.resizeStartX;\n const dy = event.clientY - this.resizeStartY;\n const minW = this.MinWidth || 200;\n const minH = this.MinHeight || 150;\n const dir = this.resizeDirection;\n\n if (dir.includes('e')) {\n this.currentWidth = Math.max(minW, this.resizeStartWidth + dx);\n }\n if (dir.includes('w')) {\n const newWidth = Math.max(minW, this.resizeStartWidth - dx);\n this.currentLeft = this.resizeStartLeft + (this.resizeStartWidth - newWidth);\n this.currentWidth = newWidth;\n }\n if (dir.includes('s')) {\n this.currentHeight = Math.max(minH, this.resizeStartHeight + dy);\n }\n if (dir.includes('n')) {\n const newHeight = Math.max(minH, this.resizeStartHeight - dy);\n this.currentTop = this.resizeStartTop + (this.resizeStartHeight - newHeight);\n this.currentHeight = newHeight;\n }\n }\n\n private onMouseUp(_event: MouseEvent): void {\n this.isDragging = false;\n this.isResizing = false;\n this.detachMouseListeners();\n }\n\n private detachMouseListeners(): void {\n if (this.boundOnMouseMove) {\n document.removeEventListener('mousemove', this.boundOnMouseMove);\n this.boundOnMouseMove = null;\n }\n if (this.boundOnMouseUp) {\n document.removeEventListener('mouseup', this.boundOnMouseUp);\n this.boundOnMouseUp = null;\n }\n }\n\n private getWindowElement(): HTMLElement | null {\n return this.elementRef.nativeElement.querySelector('.mj-window');\n }\n\n private parseSize(value: string | number): number | null {\n if (typeof value === 'number') return value;\n if (value.endsWith('vw')) return (parseFloat(value) / 100) * window.innerWidth;\n if (value.endsWith('vh')) return (parseFloat(value) / 100) * window.innerHeight;\n if (value.endsWith('px')) return parseFloat(value);\n const parsed = parseFloat(value);\n return isNaN(parsed) ? null : parsed;\n }\n\n /** Programmatic method to update position */\n SetPosition(top: number, left: number): void {\n this.currentTop = top;\n this.currentLeft = left;\n this.cdr.detectChanges();\n }\n\n /** Programmatic method to update size */\n SetSize(width: number, height: number): void {\n this.currentWidth = width;\n this.currentHeight = height;\n this.cdr.detectChanges();\n }\n\n /** Get the current window element for DOM queries */\n GetWindowElement(): HTMLElement | null {\n return this.getWindowElement();\n }\n\n ngOnDestroy(): void {\n this.detachMouseListeners();\n }\n}\n\n/**\n * mj-window-titlebar — Custom titlebar for mj-window. Replaces `<kendo-window-titlebar>`.\n */\n@Component({\n selector: 'mj-window-titlebar',\n standalone: true,\n template: `<ng-content></ng-content>`,\n styles: [`:host { display: contents; }`]\n})\nexport class MJWindowTitlebarComponent {}\n\n/**\n * mj-window-actions — Footer actions for mj-window.\n */\n@Component({\n selector: 'mj-window-actions',\n standalone: true,\n template: `<div class=\"mj-window-actions\"><ng-content></ng-content></div>`\n})\nexport class MJWindowActionsComponent {}\n"]}