@copilotkitnext/angular 0.0.2 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/README.md +3 -3
- package/dist/components/chat/copilot-chat-assistant-message.component.d.ts +10 -10
- package/dist/components/chat/copilot-chat-message-view.component.d.ts +42 -42
- package/dist/components/chat/copilot-chat-view.component.d.ts +14 -14
- package/dist/core/copilotkit.providers.d.ts +1 -1
- package/dist/core/copilotkit.service.d.ts +5 -5
- package/dist/core/copilotkit.types.d.ts +8 -10
- package/dist/directives/copilotkit-frontend-tool.directive.d.ts +1 -1
- package/dist/esm2022/components/chat/copilot-chat-assistant-message-buttons.component.mjs +384 -0
- package/dist/esm2022/components/chat/copilot-chat-assistant-message-renderer.component.mjs +286 -0
- package/dist/esm2022/components/chat/copilot-chat-assistant-message-toolbar.component.mjs +27 -0
- package/dist/esm2022/components/chat/copilot-chat-assistant-message.component.mjs +433 -0
- package/dist/esm2022/components/chat/copilot-chat-assistant-message.types.mjs +2 -0
- package/dist/esm2022/components/chat/copilot-chat-audio-recorder.component.mjs +202 -0
- package/dist/esm2022/components/chat/copilot-chat-buttons.component.mjs +321 -0
- package/dist/esm2022/components/chat/copilot-chat-input-defaults.mjs +38 -0
- package/dist/esm2022/components/chat/copilot-chat-input.component.mjs +666 -0
- package/dist/esm2022/components/chat/copilot-chat-input.types.mjs +10 -0
- package/dist/esm2022/components/chat/copilot-chat-message-view-cursor.component.mjs +45 -0
- package/dist/esm2022/components/chat/copilot-chat-message-view.component.mjs +296 -0
- package/dist/esm2022/components/chat/copilot-chat-message-view.types.mjs +2 -0
- package/dist/esm2022/components/chat/copilot-chat-textarea.component.mjs +188 -0
- package/dist/esm2022/components/chat/copilot-chat-tool-calls-view.component.mjs +216 -0
- package/dist/esm2022/components/chat/copilot-chat-toolbar.component.mjs +25 -0
- package/dist/esm2022/components/chat/copilot-chat-tools-menu.component.mjs +199 -0
- package/dist/esm2022/components/chat/copilot-chat-user-message-branch-navigation.component.mjs +137 -0
- package/dist/esm2022/components/chat/copilot-chat-user-message-buttons.component.mjs +207 -0
- package/dist/esm2022/components/chat/copilot-chat-user-message-renderer.component.mjs +35 -0
- package/dist/esm2022/components/chat/copilot-chat-user-message-toolbar.component.mjs +34 -0
- package/dist/esm2022/components/chat/copilot-chat-user-message.component.mjs +341 -0
- package/dist/esm2022/components/chat/copilot-chat-user-message.types.mjs +2 -0
- package/dist/esm2022/components/chat/copilot-chat-view-disclaimer.component.mjs +52 -0
- package/dist/esm2022/components/chat/copilot-chat-view-feather.component.mjs +55 -0
- package/dist/esm2022/components/chat/copilot-chat-view-handlers.service.mjs +19 -0
- package/dist/esm2022/components/chat/copilot-chat-view-input-container.component.mjs +110 -0
- package/dist/esm2022/components/chat/copilot-chat-view-scroll-to-bottom-button.component.mjs +93 -0
- package/dist/esm2022/components/chat/copilot-chat-view-scroll-view.component.mjs +443 -0
- package/dist/esm2022/components/chat/copilot-chat-view.component.mjs +479 -0
- package/dist/esm2022/components/chat/copilot-chat-view.types.mjs +2 -0
- package/dist/esm2022/components/chat/copilot-chat.component.mjs +214 -0
- package/dist/esm2022/components/copilotkit-tool-render.component.mjs +153 -0
- package/dist/esm2022/copilotkitnext-angular.mjs +5 -0
- package/dist/esm2022/core/chat-configuration/chat-configuration.providers.mjs +65 -0
- package/dist/esm2022/core/chat-configuration/chat-configuration.service.mjs +145 -0
- package/dist/esm2022/core/chat-configuration/chat-configuration.types.mjs +26 -0
- package/dist/esm2022/core/copilotkit.providers.mjs +34 -0
- package/dist/esm2022/core/copilotkit.service.mjs +426 -0
- package/dist/esm2022/core/copilotkit.types.mjs +13 -0
- package/dist/esm2022/directives/copilotkit-agent-context.directive.mjs +130 -0
- package/dist/esm2022/directives/copilotkit-agent.directive.mjs +217 -0
- package/dist/esm2022/directives/copilotkit-chat-config.directive.mjs +218 -0
- package/dist/esm2022/directives/copilotkit-config.directive.mjs +94 -0
- package/dist/esm2022/directives/copilotkit-frontend-tool.directive.mjs +128 -0
- package/dist/esm2022/directives/copilotkit-human-in-the-loop.directive.mjs +265 -0
- package/dist/esm2022/directives/stick-to-bottom.directive.mjs +181 -0
- package/dist/esm2022/index.mjs +70 -0
- package/dist/esm2022/lib/directives/tooltip.directive.mjs +211 -0
- package/dist/esm2022/lib/slots/copilot-slot.component.mjs +144 -0
- package/dist/esm2022/lib/slots/slot.types.mjs +6 -0
- package/dist/esm2022/lib/slots/slot.utils.mjs +222 -0
- package/dist/esm2022/lib/utils.mjs +10 -0
- package/dist/esm2022/services/resize-observer.service.mjs +152 -0
- package/dist/esm2022/services/scroll-position.service.mjs +124 -0
- package/dist/esm2022/types/frontend-tool.mjs +2 -0
- package/dist/esm2022/types/human-in-the-loop.mjs +2 -0
- package/dist/esm2022/utils/agent-context.utils.mjs +114 -0
- package/dist/esm2022/utils/agent.utils.mjs +204 -0
- package/dist/esm2022/utils/chat-config.utils.mjs +186 -0
- package/dist/esm2022/utils/copilotkit.utils.mjs +20 -0
- package/dist/esm2022/utils/frontend-tool.utils.mjs +224 -0
- package/dist/esm2022/utils/human-in-the-loop.utils.mjs +293 -0
- package/dist/fesm2022/copilotkitnext-angular.mjs +174 -187
- package/dist/fesm2022/copilotkitnext-angular.mjs.map +1 -1
- package/dist/utils/frontend-tool.utils.d.ts +1 -1
- package/package.json +23 -20
- package/vitest.config.mts +32 -21
- package/.turbo/turbo-build.log +0 -38
- package/.turbo/turbo-check-types.log +0 -0
- package/.turbo/turbo-test.log +0 -71
- package/ng-package.json +0 -19
- package/src/components/chat/__tests__/copilot-chat-assistant-message.component.spec.ts +0 -282
- package/src/components/chat/__tests__/copilot-chat-input.component.spec.ts +0 -419
- package/src/components/chat/__tests__/copilot-chat-message-view.component.spec.ts +0 -372
- package/src/components/chat/__tests__/copilot-chat-user-message.component.spec.ts +0 -249
- package/src/components/chat/copilot-chat-assistant-message-buttons.component.ts +0 -292
- package/src/components/chat/copilot-chat-assistant-message-renderer.component.ts +0 -472
- package/src/components/chat/copilot-chat-assistant-message-toolbar.component.ts +0 -29
- package/src/components/chat/copilot-chat-assistant-message.component.ts +0 -463
- package/src/components/chat/copilot-chat-assistant-message.types.ts +0 -50
- package/src/components/chat/copilot-chat-audio-recorder.component.ts +0 -241
- package/src/components/chat/copilot-chat-buttons.component.ts +0 -308
- package/src/components/chat/copilot-chat-buttons.component.ts.bak +0 -471
- package/src/components/chat/copilot-chat-input-defaults.ts +0 -47
- package/src/components/chat/copilot-chat-input.component.ts +0 -512
- package/src/components/chat/copilot-chat-input.types.ts +0 -148
- package/src/components/chat/copilot-chat-message-view-cursor.component.ts +0 -51
- package/src/components/chat/copilot-chat-message-view.component.ts +0 -233
- package/src/components/chat/copilot-chat-message-view.types.ts +0 -39
- package/src/components/chat/copilot-chat-textarea.component.ts +0 -220
- package/src/components/chat/copilot-chat-tool-calls-view.component.ts +0 -261
- package/src/components/chat/copilot-chat-toolbar.component.ts +0 -35
- package/src/components/chat/copilot-chat-tools-menu.component.ts +0 -185
- package/src/components/chat/copilot-chat-user-message-branch-navigation.component.ts +0 -121
- package/src/components/chat/copilot-chat-user-message-buttons.component.ts +0 -170
- package/src/components/chat/copilot-chat-user-message-renderer.component.ts +0 -37
- package/src/components/chat/copilot-chat-user-message-toolbar.component.ts +0 -37
- package/src/components/chat/copilot-chat-user-message.component.ts +0 -247
- package/src/components/chat/copilot-chat-user-message.types.ts +0 -42
- package/src/components/chat/copilot-chat-view-disclaimer.component.ts +0 -51
- package/src/components/chat/copilot-chat-view-feather.component.ts +0 -47
- package/src/components/chat/copilot-chat-view-handlers.service.ts +0 -14
- package/src/components/chat/copilot-chat-view-input-container.component.ts +0 -87
- package/src/components/chat/copilot-chat-view-scroll-to-bottom-button.component.ts +0 -79
- package/src/components/chat/copilot-chat-view-scroll-view.component.ts +0 -322
- package/src/components/chat/copilot-chat-view.component.ts +0 -420
- package/src/components/chat/copilot-chat-view.types.ts +0 -52
- package/src/components/chat/copilot-chat.component.ts +0 -232
- package/src/components/copilotkit-tool-render.component.ts +0 -169
- package/src/core/__tests__/copilotkit.service.spec.ts +0 -1051
- package/src/core/__tests__/copilotkit.service.wildcard.spec.ts +0 -316
- package/src/core/chat-configuration/__tests__/chat-configuration.service.spec.ts +0 -287
- package/src/core/chat-configuration/chat-configuration.providers.ts +0 -71
- package/src/core/chat-configuration/chat-configuration.service.ts +0 -162
- package/src/core/chat-configuration/chat-configuration.types.ts +0 -57
- package/src/core/copilotkit.providers.ts +0 -59
- package/src/core/copilotkit.service.ts +0 -542
- package/src/core/copilotkit.types.ts +0 -132
- package/src/directives/__tests__/copilotkit-agent-context.directive.spec.ts +0 -384
- package/src/directives/__tests__/copilotkit-agent.directive.spec.ts +0 -253
- package/src/directives/__tests__/copilotkit-chat-config.directive.spec.ts +0 -385
- package/src/directives/__tests__/copilotkit-config.directive.spec.ts +0 -69
- package/src/directives/__tests__/copilotkit-frontend-tool-simple.directive.spec.ts +0 -60
- package/src/directives/__tests__/copilotkit-frontend-tool.directive.spec.ts +0 -108
- package/src/directives/__tests__/copilotkit-human-in-the-loop.directive.spec.ts +0 -452
- package/src/directives/copilotkit-agent-context.directive.ts +0 -138
- package/src/directives/copilotkit-agent.directive.ts +0 -225
- package/src/directives/copilotkit-chat-config.directive.ts +0 -241
- package/src/directives/copilotkit-config.directive.ts +0 -81
- package/src/directives/copilotkit-frontend-tool.directive.ts +0 -145
- package/src/directives/copilotkit-human-in-the-loop.directive.ts +0 -281
- package/src/directives/stick-to-bottom.directive.ts +0 -204
- package/src/index.ts +0 -105
- package/src/lib/directives/tooltip.directive.ts +0 -292
- package/src/lib/slots/__tests__/slot.utils.spec.ts +0 -377
- package/src/lib/slots/copilot-slot.component.ts +0 -135
- package/src/lib/slots/index.ts +0 -3
- package/src/lib/slots/slot.types.ts +0 -64
- package/src/lib/slots/slot.utils.ts +0 -289
- package/src/lib/utils.ts +0 -10
- package/src/public-api.ts +0 -1
- package/src/services/resize-observer.service.ts +0 -181
- package/src/services/scroll-position.service.ts +0 -169
- package/src/styles/globals.css +0 -266
- package/src/styles/index.css +0 -3
- package/src/test-setup.ts +0 -15
- package/src/testing/index.ts +0 -3
- package/src/testing/testing.utils.ts +0 -248
- package/src/types/frontend-tool.ts +0 -44
- package/src/types/human-in-the-loop.ts +0 -52
- package/src/utils/__tests__/agent.utils.spec.ts +0 -234
- package/src/utils/__tests__/chat-config.utils.spec.ts +0 -306
- package/src/utils/__tests__/frontend-tool-inject.spec.ts +0 -350
- package/src/utils/__tests__/frontend-tool-integration.spec.ts +0 -199
- package/src/utils/__tests__/frontend-tool.utils.spec.ts +0 -272
- package/src/utils/__tests__/human-in-the-loop.utils.spec.ts +0 -365
- package/src/utils/agent-context.utils.ts +0 -133
- package/src/utils/agent.utils.ts +0 -239
- package/src/utils/chat-config.utils.ts +0 -221
- package/src/utils/copilotkit.utils.ts +0 -20
- package/src/utils/frontend-tool.utils.ts +0 -266
- package/src/utils/human-in-the-loop.utils.ts +0 -359
- package/tsconfig.spec.json +0 -12
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { Component, Input, TemplateRef, ViewContainerRef, Inject, ChangeDetectionStrategy, ViewChild } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import { renderSlot } from './slot.utils';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
import * as i1 from "@angular/common";
|
|
6
|
+
/**
|
|
7
|
+
* @internal - This component is for internal use only.
|
|
8
|
+
* Simple slot component for rendering custom content or defaults.
|
|
9
|
+
* Supports templates and components only.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```html
|
|
13
|
+
* <!-- With template -->
|
|
14
|
+
* <copilot-slot [slot]="sendButtonTemplate" [context]="buttonContext">
|
|
15
|
+
* <button class="default-btn">Default</button>
|
|
16
|
+
* </copilot-slot>
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export class CopilotSlotComponent {
|
|
20
|
+
viewContainer;
|
|
21
|
+
cdr;
|
|
22
|
+
slot;
|
|
23
|
+
context;
|
|
24
|
+
defaultComponent;
|
|
25
|
+
outputs;
|
|
26
|
+
slotContainer;
|
|
27
|
+
componentRef;
|
|
28
|
+
constructor(viewContainer, cdr) {
|
|
29
|
+
this.viewContainer = viewContainer;
|
|
30
|
+
this.cdr = cdr;
|
|
31
|
+
}
|
|
32
|
+
ngOnInit() {
|
|
33
|
+
this.renderSlot();
|
|
34
|
+
}
|
|
35
|
+
ngOnChanges(changes) {
|
|
36
|
+
if (changes['slot']) {
|
|
37
|
+
// Slot changed, need to re-render completely
|
|
38
|
+
this.renderSlot();
|
|
39
|
+
}
|
|
40
|
+
else if (changes['context'] && this.componentRef) {
|
|
41
|
+
// Just context changed, update existing component
|
|
42
|
+
this.updateComponentProps();
|
|
43
|
+
this.cdr.detectChanges();
|
|
44
|
+
}
|
|
45
|
+
else if (changes['context']) {
|
|
46
|
+
// No component ref yet, render the slot
|
|
47
|
+
this.renderSlot();
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
isTemplate(value) {
|
|
51
|
+
return value instanceof TemplateRef;
|
|
52
|
+
}
|
|
53
|
+
renderSlot() {
|
|
54
|
+
// Skip if it's a template (handled by ngTemplateOutlet)
|
|
55
|
+
if (this.slot && this.isTemplate(this.slot)) {
|
|
56
|
+
this.componentRef = null;
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
// Clear previous content
|
|
60
|
+
this.slotContainer.clear();
|
|
61
|
+
this.componentRef = null;
|
|
62
|
+
// Skip if no slot and no default component
|
|
63
|
+
if (!this.slot && !this.defaultComponent) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
// Use the utility to render other slot types
|
|
67
|
+
if (this.slot || this.defaultComponent) {
|
|
68
|
+
this.componentRef = renderSlot(this.slotContainer, {
|
|
69
|
+
slot: this.slot,
|
|
70
|
+
defaultComponent: this.defaultComponent,
|
|
71
|
+
props: this.context,
|
|
72
|
+
outputs: this.outputs
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
updateComponentProps() {
|
|
77
|
+
if (!this.componentRef || !this.componentRef.instance) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
const props = this.context;
|
|
81
|
+
// Update props using setInput
|
|
82
|
+
if (props) {
|
|
83
|
+
for (const key in props) {
|
|
84
|
+
const value = props[key];
|
|
85
|
+
this.componentRef.setInput(key, value);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// Trigger change detection
|
|
89
|
+
if (this.componentRef.changeDetectorRef) {
|
|
90
|
+
this.componentRef.changeDetectorRef.detectChanges();
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CopilotSlotComponent, deps: [{ token: ViewContainerRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
94
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: CopilotSlotComponent, isStandalone: true, selector: "copilot-slot", inputs: { slot: "slot", context: "context", defaultComponent: "defaultComponent", outputs: "outputs" }, viewQueries: [{ propertyName: "slotContainer", first: true, predicate: ["slotContainer"], descendants: true, read: ViewContainerRef, static: true }], usesOnChanges: true, ngImport: i0, template: `
|
|
95
|
+
<!-- If slot template provided, render it -->
|
|
96
|
+
<ng-container *ngIf="slot && isTemplate(slot)"
|
|
97
|
+
[ngTemplateOutlet]="slot"
|
|
98
|
+
[ngTemplateOutletContext]="context || {}">
|
|
99
|
+
</ng-container>
|
|
100
|
+
|
|
101
|
+
<!-- If not a template, we'll handle in code -->
|
|
102
|
+
<ng-container #slotContainer></ng-container>
|
|
103
|
+
|
|
104
|
+
<!-- Default content (only shown if no slot) -->
|
|
105
|
+
<ng-content *ngIf="!slot && !defaultComponent"></ng-content>
|
|
106
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
107
|
+
}
|
|
108
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CopilotSlotComponent, decorators: [{
|
|
109
|
+
type: Component,
|
|
110
|
+
args: [{
|
|
111
|
+
selector: 'copilot-slot',
|
|
112
|
+
standalone: true,
|
|
113
|
+
imports: [CommonModule],
|
|
114
|
+
template: `
|
|
115
|
+
<!-- If slot template provided, render it -->
|
|
116
|
+
<ng-container *ngIf="slot && isTemplate(slot)"
|
|
117
|
+
[ngTemplateOutlet]="slot"
|
|
118
|
+
[ngTemplateOutletContext]="context || {}">
|
|
119
|
+
</ng-container>
|
|
120
|
+
|
|
121
|
+
<!-- If not a template, we'll handle in code -->
|
|
122
|
+
<ng-container #slotContainer></ng-container>
|
|
123
|
+
|
|
124
|
+
<!-- Default content (only shown if no slot) -->
|
|
125
|
+
<ng-content *ngIf="!slot && !defaultComponent"></ng-content>
|
|
126
|
+
`,
|
|
127
|
+
changeDetection: ChangeDetectionStrategy.OnPush
|
|
128
|
+
}]
|
|
129
|
+
}], ctorParameters: () => [{ type: i0.ViewContainerRef, decorators: [{
|
|
130
|
+
type: Inject,
|
|
131
|
+
args: [ViewContainerRef]
|
|
132
|
+
}] }, { type: i0.ChangeDetectorRef }], propDecorators: { slot: [{
|
|
133
|
+
type: Input
|
|
134
|
+
}], context: [{
|
|
135
|
+
type: Input
|
|
136
|
+
}], defaultComponent: [{
|
|
137
|
+
type: Input
|
|
138
|
+
}], outputs: [{
|
|
139
|
+
type: Input
|
|
140
|
+
}], slotContainer: [{
|
|
141
|
+
type: ViewChild,
|
|
142
|
+
args: ['slotContainer', { read: ViewContainerRef, static: true }]
|
|
143
|
+
}] } });
|
|
144
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29waWxvdC1zbG90LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvc2xvdHMvY29waWxvdC1zbG90LmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUNULEtBQUssRUFDTCxXQUFXLEVBQ1gsZ0JBQWdCLEVBSWhCLE1BQU0sRUFDTix1QkFBdUIsRUFFdkIsU0FBUyxFQUNWLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sY0FBYyxDQUFDOzs7QUFHMUM7Ozs7Ozs7Ozs7OztHQVlHO0FBb0JILE1BQU0sT0FBTyxvQkFBb0I7SUFZSztJQUMxQjtJQVpELElBQUksQ0FBZ0M7SUFDcEMsT0FBTyxDQUFPO0lBQ2QsZ0JBQWdCLENBQWE7SUFDN0IsT0FBTyxDQUF3QztJQUdoRCxhQUFhLENBQW9CO0lBRWpDLFlBQVksQ0FBTztJQUUzQixZQUNvQyxhQUErQixFQUN6RCxHQUFzQjtRQURJLGtCQUFhLEdBQWIsYUFBYSxDQUFrQjtRQUN6RCxRQUFHLEdBQUgsR0FBRyxDQUFtQjtJQUM3QixDQUFDO0lBRUosUUFBUTtRQUNOLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztJQUNwQixDQUFDO0lBRUQsV0FBVyxDQUFDLE9BQXNCO1FBQ2hDLElBQUksT0FBTyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7WUFDcEIsNkNBQTZDO1lBQzdDLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUNwQixDQUFDO2FBQU0sSUFBSSxPQUFPLENBQUMsU0FBUyxDQUFDLElBQUksSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQ25ELGtEQUFrRDtZQUNsRCxJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztZQUM1QixJQUFJLENBQUMsR0FBRyxDQUFDLGFBQWEs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InNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENvbXBvbmVudCxcbiAgSW5wdXQsXG4gIFRlbXBsYXRlUmVmLFxuICBWaWV3Q29udGFpbmVyUmVmLFxuICBPbkluaXQsXG4gIE9uQ2hhbmdlcyxcbiAgU2ltcGxlQ2hhbmdlcyxcbiAgSW5qZWN0LFxuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIFZpZXdDaGlsZFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyByZW5kZXJTbG90IH0gZnJvbSAnLi9zbG90LnV0aWxzJztcbmltcG9ydCB7IFR5cGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuLyoqXG4gKiBAaW50ZXJuYWwgLSBUaGlzIGNvbXBvbmVudCBpcyBmb3IgaW50ZXJuYWwgdXNlIG9ubHkuXG4gKiBTaW1wbGUgc2xvdCBjb21wb25lbnQgZm9yIHJlbmRlcmluZyBjdXN0b20gY29udGVudCBvciBkZWZhdWx0cy5cbiAqIFN1cHBvcnRzIHRlbXBsYXRlcyBhbmQgY29tcG9uZW50cyBvbmx5LlxuICogXG4gKiBAZXhhbXBsZVxuICogYGBgaHRtbFxuICogPCEtLSBXaXRoIHRlbXBsYXRlIC0tPlxuICogPGNvcGlsb3Qtc2xvdCBbc2xvdF09XCJzZW5kQnV0dG9uVGVtcGxhdGVcIiBbY29udGV4dF09XCJidXR0b25Db250ZXh0XCI+XG4gKiAgIDxidXR0b24gY2xhc3M9XCJkZWZhdWx0LWJ0blwiPkRlZmF1bHQ8L2J1dHRvbj5cbiAqIDwvY29waWxvdC1zbG90PlxuICogYGBgXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2NvcGlsb3Qtc2xvdCcsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtDb21tb25Nb2R1bGVdLFxuICB0ZW1wbGF0ZTogYFxuICAgIDwhLS0gSWYgc2xvdCB0ZW1wbGF0ZSBwcm92aWRlZCwgcmVuZGVyIGl0IC0tPlxuICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJzbG90ICYmIGlzVGVtcGxhdGUoc2xvdClcIlxuICAgICAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRdPVwic2xvdFwiXG4gICAgICAgICAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwiY29udGV4dCB8fCB7fVwiPlxuICAgIDwvbmctY29udGFpbmVyPlxuICAgIFxuICAgIDwhLS0gSWYgbm90IGEgdGVtcGxhdGUsIHdlJ2xsIGhhbmRsZSBpbiBjb2RlIC0tPlxuICAgIDxuZy1jb250YWluZXIgI3Nsb3RDb250YWluZXI+PC9uZy1jb250YWluZXI+XG4gICAgXG4gICAgPCEtLSBEZWZhdWx0IGNvbnRlbnQgKG9ubHkgc2hvd24gaWYgbm8gc2xvdCkgLS0+XG4gICAgPG5nLWNvbnRlbnQgKm5nSWY9XCIhc2xvdCAmJiAhZGVmYXVsdENvbXBvbmVudFwiPjwvbmctY29udGVudD5cbiAgYCxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2hcbn0pXG5leHBvcnQgY2xhc3MgQ29waWxvdFNsb3RDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcyB7XG4gIEBJbnB1dCgpIHNsb3Q/OiBUZW1wbGF0ZVJlZjxhbnk+IHwgVHlwZTxhbnk+O1xuICBASW5wdXQoKSBjb250ZXh0PzogYW55O1xuICBASW5wdXQoKSBkZWZhdWx0Q29tcG9uZW50PzogVHlwZTxhbnk+O1xuICBASW5wdXQoKSBvdXRwdXRzPzogUmVjb3JkPHN0cmluZywgKGV2ZW50OiBhbnkpID0+IHZvaWQ+O1xuICBcbiAgQFZpZXdDaGlsZCgnc2xvdENvbnRhaW5lcicsIHsgcmVhZDogVmlld0NvbnRhaW5lclJlZiwgc3RhdGljOiB0cnVlIH0pIFxuICBwcml2YXRlIHNsb3RDb250YWluZXIhOiBWaWV3Q29udGFpbmVyUmVmO1xuICBcbiAgcHJpdmF0ZSBjb21wb25lbnRSZWY/OiBhbnk7XG4gIFxuICBjb25zdHJ1Y3RvcihcbiAgICBASW5qZWN0KFZpZXdDb250YWluZXJSZWYpIHByaXZhdGUgdmlld0NvbnRhaW5lcjogVmlld0NvbnRhaW5lclJlZixcbiAgICBwcml2YXRlIGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWZcbiAgKSB7fVxuICBcbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5yZW5kZXJTbG90KCk7XG4gIH1cbiAgXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICBpZiAoY2hhbmdlc1snc2xvdCddKSB7XG4gICAgICAvLyBTbG90IGNoYW5nZWQsIG5lZWQgdG8gcmUtcmVuZGVyIGNvbXBsZXRlbHlcbiAgICAgIHRoaXMucmVuZGVyU2xvdCgpO1xuICAgIH0gZWxzZSBpZiAoY2hhbmdlc1snY29udGV4dCddICYmIHRoaXMuY29tcG9uZW50UmVmKSB7XG4gICAgICAvLyBKdXN0IGNvbnRleHQgY2hhbmdlZCwgdXBkYXRlIGV4aXN0aW5nIGNvbXBvbmVudFxuICAgICAgdGhpcy51cGRhdGVDb21wb25lbnRQcm9wcygpO1xuICAgICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICAgIH0gZWxzZSBpZiAoY2hhbmdlc1snY29udGV4dCddKSB7XG4gICAgICAvLyBObyBjb21wb25lbnQgcmVmIHlldCwgcmVuZGVyIHRoZSBzbG90XG4gICAgICB0aGlzLnJlbmRlclNsb3QoKTtcbiAgICB9XG4gIH1cbiAgXG4gIGlzVGVtcGxhdGUodmFsdWU6IGFueSk6IHZhbHVlIGlzIFRlbXBsYXRlUmVmPGFueT4ge1xuICAgIHJldHVybiB2YWx1ZSBpbnN0YW5jZW9mIFRlbXBsYXRlUmVmO1xuICB9XG4gIFxuICBwcml2YXRlIHJlbmRlclNsb3QoKTogdm9pZCB7XG4gICAgLy8gU2tpcCBpZiBpdCdzIGEgdGVtcGxhdGUgKGhhbmRsZWQgYnkgbmdUZW1wbGF0ZU91dGxldClcbiAgICBpZiAodGhpcy5zbG90ICYmIHRoaXMuaXNUZW1wbGF0ZSh0aGlzLnNsb3QpKSB7XG4gICAgICB0aGlzLmNvbXBvbmVudFJlZiA9IG51bGw7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIFxuICAgIC8vIENsZWFyIHByZXZpb3VzIGNvbnRlbnRcbiAgICB0aGlzLnNsb3RDb250YWluZXIuY2xlYXIoKTtcbiAgICB0aGlzLmNvbXBvbmVudFJlZiA9IG51bGw7XG4gICAgXG4gICAgLy8gU2tpcCBpZiBubyBzbG90IGFuZCBubyBkZWZhdWx0IGNvbXBvbmVudFxuICAgIGlmICghdGhpcy5zbG90ICYmICF0aGlzLmRlZmF1bHRDb21wb25lbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgXG4gICAgLy8gVXNlIHRoZSB1dGlsaXR5IHRvIHJlbmRlciBvdGhlciBzbG90IHR5cGVzXG4gICAgaWYgKHRoaXMuc2xvdCB8fCB0aGlzLmRlZmF1bHRDb21wb25lbnQpIHtcbiAgICAgIHRoaXMuY29tcG9uZW50UmVmID0gcmVuZGVyU2xvdCh0aGlzLnNsb3RDb250YWluZXIsIHtcbiAgICAgICAgc2xvdDogdGhpcy5zbG90LFxuICAgICAgICBkZWZhdWx0Q29tcG9uZW50OiB0aGlzLmRlZmF1bHRDb21wb25lbnQhLFxuICAgICAgICBwcm9wczogdGhpcy5jb250ZXh0LFxuICAgICAgICBvdXRwdXRzOiB0aGlzLm91dHB1dHNcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuICBcbiAgcHJpdmF0ZSB1cGRhdGVDb21wb25lbnRQcm9wcygpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuY29tcG9uZW50UmVmIHx8ICF0aGlzLmNvbXBvbmVudFJlZi5pbnN0YW5jZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBcbiAgICBjb25zdCBwcm9wcyA9IHRoaXMuY29udGV4dDtcbiAgICBcbiAgICAvLyBVcGRhdGUgcHJvcHMgdXNpbmcgc2V0SW5wdXRcbiAgICBpZiAocHJvcHMpIHtcbiAgICAgIGZvciAoY29uc3Qga2V5IGluIHByb3BzKSB7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gcHJvcHNba2V5XTtcbiAgICAgICAgdGhpcy5jb21wb25lbnRSZWYuc2V0SW5wdXQoa2V5LCB2YWx1ZSk7XG4gICAgICB9XG4gICAgfVxuICAgIFxuICAgIC8vIFRyaWdnZXIgY2hhbmdlIGRldGVjdGlvblxuICAgIGlmICh0aGlzLmNvbXBvbmVudFJlZi5jaGFuZ2VEZXRlY3RvclJlZikge1xuICAgICAgdGhpcy5jb21wb25lbnRSZWYuY2hhbmdlRGV0ZWN0b3JSZWYuZGV0ZWN0Q2hhbmdlcygpO1xuICAgIH1cbiAgfVxufSJdfQ==
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { InjectionToken } from '@angular/core';
|
|
2
|
+
/**
|
|
3
|
+
* Injection token for slot configuration
|
|
4
|
+
*/
|
|
5
|
+
export const SLOT_CONFIG = new InjectionToken('SLOT_CONFIG');
|
|
6
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2xvdC50eXBlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvc2xvdHMvc2xvdC50eXBlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQXFCLGNBQWMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQWlEbEU7O0dBRUc7QUFDSCxNQUFNLENBQUMsTUFBTSxXQUFXLEdBQUcsSUFBSSxjQUFjLENBQXlDLGFBQWEsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgVHlwZSwgVGVtcGxhdGVSZWYsIEluamVjdGlvblRva2VuIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbi8qKlxuICogUmVwcmVzZW50cyBhIHZhbHVlIHRoYXQgY2FuIGJlIHVzZWQgYXMgYSBzbG90IG92ZXJyaWRlLlxuICogQ2FuIGJlIGEgY29tcG9uZW50IHR5cGUgb3IgdGVtcGxhdGUgcmVmZXJlbmNlIG9ubHkuXG4gKiBAaW50ZXJuYWwgLSBUaGlzIHR5cGUgaXMgZm9yIGludGVybmFsIHVzZSBvbmx5XG4gKi9cbmV4cG9ydCB0eXBlIFNsb3RWYWx1ZTxUID0gYW55PiA9IFxuICB8IFR5cGU8VD5cbiAgfCBUZW1wbGF0ZVJlZjxUPjtcblxuLyoqXG4gKiBDb25maWd1cmF0aW9uIGZvciBhIHNsb3RcbiAqIEBpbnRlcm5hbCAtIFRoaXMgaW50ZXJmYWNlIGlzIGZvciBpbnRlcm5hbCB1c2Ugb25seVxuICovXG5leHBvcnQgaW50ZXJmYWNlIFNsb3RDb25maWc8VCA9IGFueT4ge1xuICB2YWx1ZT86IFNsb3RWYWx1ZTxUPjtcbiAgZGVmYXVsdD86IFR5cGU8VD47XG59XG5cbi8qKlxuICogQ29udGV4dCBwYXNzZWQgdG8gc2xvdCB0ZW1wbGF0ZXNcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTbG90Q29udGV4dDxUID0gYW55PiB7XG4gICRpbXBsaWNpdDogVDtcbiAgcHJvcHM/OiBQYXJ0aWFsPFQ+O1xuICBba2V5OiBzdHJpbmddOiBhbnk7XG59XG5cbi8qKlxuICogU2xvdCByZWdpc3RyeSBlbnRyeVxuICogQGludGVybmFsIC0gVGhpcyBpbnRlcmZhY2UgaXMgZm9yIGludGVybmFsIHVzZSBvbmx5XG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2xvdFJlZ2lzdHJ5RW50cnk8VCA9IGFueT4ge1xuICBjb21wb25lbnQ/OiBUeXBlPFQ+O1xuICB0ZW1wbGF0ZT86IFRlbXBsYXRlUmVmPFQ+O1xufVxuXG4vKipcbiAqIE9wdGlvbnMgZm9yIHJlbmRlcmluZyBhIHNsb3RcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZW5kZXJTbG90T3B0aW9uczxUID0gYW55PiB7XG4gIHNsb3Q/OiBTbG90VmFsdWU8VD47XG4gIGRlZmF1bHRDb21wb25lbnQ6IFR5cGU8VD47XG4gIHByb3BzPzogUGFydGlhbDxUPjtcbiAgaW5qZWN0b3I/OiBhbnk7XG4gIG91dHB1dHM/OiBSZWNvcmQ8c3RyaW5nLCAoZXZlbnQ6IGFueSkgPT4gdm9pZD47XG59XG5cbi8qKlxuICogSW5qZWN0aW9uIHRva2VuIGZvciBzbG90IGNvbmZpZ3VyYXRpb25cbiAqL1xuZXhwb3J0IGNvbnN0IFNMT1RfQ09ORklHID0gbmV3IEluamVjdGlvblRva2VuPFJlYWRvbmx5TWFwPHN0cmluZywgU2xvdFJlZ2lzdHJ5RW50cnk+PignU0xPVF9DT05GSUcnKTtcblxuLyoqXG4gKiBUeXBlIGZvciBjb21wb25lbnRzIHdpdGggc2xvdHNcbiAqL1xuZXhwb3J0IHR5cGUgV2l0aFNsb3RzPFMgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCBUeXBlPGFueT4+LCBSZXN0ID0gb2JqZWN0PiA9IHtcbiAgW0sgaW4ga2V5b2YgUyBhcyBgJHtzdHJpbmcgJiBLfUNvbXBvbmVudGBdPzogVHlwZTxhbnk+O1xufSAmIHtcbiAgW0sgaW4ga2V5b2YgUyBhcyBgJHtzdHJpbmcgJiBLfVRlbXBsYXRlYF0/OiBUZW1wbGF0ZVJlZjxhbnk+O1xufSAmIHtcbiAgW0sgaW4ga2V5b2YgUyBhcyBgJHtzdHJpbmcgJiBLfUNsYXNzYF0/OiBzdHJpbmc7XG59ICYgUmVzdDsiXX0=
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import { TemplateRef, inject } from '@angular/core';
|
|
2
|
+
import { SLOT_CONFIG } from './slot.types';
|
|
3
|
+
/**
|
|
4
|
+
* Renders a slot value into a ViewContainerRef.
|
|
5
|
+
* This is the core utility for slot rendering.
|
|
6
|
+
*
|
|
7
|
+
* @param viewContainer - The ViewContainerRef to render into
|
|
8
|
+
* @param options - Options for rendering the slot
|
|
9
|
+
* @returns The created component or embedded view reference
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* export class MyComponent {
|
|
14
|
+
* @ViewChild('container', { read: ViewContainerRef }) container!: ViewContainerRef;
|
|
15
|
+
*
|
|
16
|
+
* renderButton() {
|
|
17
|
+
* renderSlot(this.container, {
|
|
18
|
+
* slot: this.buttonOverride,
|
|
19
|
+
* defaultComponent: DefaultButton,
|
|
20
|
+
* props: { text: 'Click me' },
|
|
21
|
+
* outputs: { click: (event) => this.handleClick(event) }
|
|
22
|
+
* });
|
|
23
|
+
* }
|
|
24
|
+
* }
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export function renderSlot(viewContainer, options) {
|
|
28
|
+
const { slot, defaultComponent, props, injector, outputs } = options;
|
|
29
|
+
viewContainer.clear();
|
|
30
|
+
const effectiveSlot = slot ?? defaultComponent;
|
|
31
|
+
const effectiveInjector = injector ?? viewContainer.injector;
|
|
32
|
+
if (effectiveSlot instanceof TemplateRef) {
|
|
33
|
+
// TemplateRef: render template
|
|
34
|
+
return viewContainer.createEmbeddedView(effectiveSlot, {
|
|
35
|
+
$implicit: props ?? {},
|
|
36
|
+
props: props ?? {}
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
else if (isComponentType(effectiveSlot)) {
|
|
40
|
+
// Component type - wrap in try/catch for safety
|
|
41
|
+
try {
|
|
42
|
+
return createComponent(viewContainer, effectiveSlot, props, effectiveInjector, outputs);
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
console.warn('Failed to create component:', effectiveSlot, error);
|
|
46
|
+
// Fall through to default component
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// Default: render default component if provided
|
|
50
|
+
return defaultComponent ? createComponent(viewContainer, defaultComponent, props, effectiveInjector, outputs) : null;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Creates a component and applies properties.
|
|
54
|
+
*/
|
|
55
|
+
function createComponent(viewContainer, component, props, injector, outputs) {
|
|
56
|
+
const componentRef = viewContainer.createComponent(component, {
|
|
57
|
+
injector
|
|
58
|
+
});
|
|
59
|
+
if (props) {
|
|
60
|
+
// Apply props using setInput
|
|
61
|
+
for (const key in props) {
|
|
62
|
+
const value = props[key];
|
|
63
|
+
componentRef.setInput(key, value);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
if (outputs) {
|
|
67
|
+
// Wire up output event handlers with proper cleanup
|
|
68
|
+
const instance = componentRef.instance;
|
|
69
|
+
const subscriptions = [];
|
|
70
|
+
for (const [eventName, handler] of Object.entries(outputs)) {
|
|
71
|
+
if (instance[eventName]?.subscribe) {
|
|
72
|
+
const subscription = instance[eventName].subscribe(handler);
|
|
73
|
+
subscriptions.push(subscription);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
// Register cleanup on component destroy
|
|
77
|
+
componentRef.onDestroy(() => {
|
|
78
|
+
subscriptions.forEach(sub => sub.unsubscribe());
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
// Trigger change detection
|
|
82
|
+
componentRef.changeDetectorRef.detectChanges();
|
|
83
|
+
return componentRef;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Checks if a value is a component type.
|
|
87
|
+
* Simplified check - rely on try/catch for actual validation.
|
|
88
|
+
*/
|
|
89
|
+
export function isComponentType(value) {
|
|
90
|
+
// Arrow functions and regular functions without a prototype are not components
|
|
91
|
+
return typeof value === 'function' && !!value.prototype;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Checks if a value is a valid slot value.
|
|
95
|
+
*/
|
|
96
|
+
export function isSlotValue(value) {
|
|
97
|
+
return value instanceof TemplateRef || isComponentType(value);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Normalizes a slot value to a consistent format.
|
|
101
|
+
*/
|
|
102
|
+
export function normalizeSlotValue(value, defaultComponent) {
|
|
103
|
+
if (!value) {
|
|
104
|
+
return { component: defaultComponent };
|
|
105
|
+
}
|
|
106
|
+
if (value instanceof TemplateRef) {
|
|
107
|
+
return { template: value };
|
|
108
|
+
}
|
|
109
|
+
if (isComponentType(value)) {
|
|
110
|
+
return { component: value };
|
|
111
|
+
}
|
|
112
|
+
return { component: defaultComponent };
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Creates a slot configuration map for a component.
|
|
116
|
+
*
|
|
117
|
+
* @example
|
|
118
|
+
* ```typescript
|
|
119
|
+
* const slots = createSlotConfig({
|
|
120
|
+
* sendButton: CustomSendButton,
|
|
121
|
+
* toolbar: 'custom-toolbar-class',
|
|
122
|
+
* footer: footerTemplate
|
|
123
|
+
* }, {
|
|
124
|
+
* sendButton: DefaultSendButton,
|
|
125
|
+
* toolbar: DefaultToolbar,
|
|
126
|
+
* footer: DefaultFooter
|
|
127
|
+
* });
|
|
128
|
+
* ```
|
|
129
|
+
*/
|
|
130
|
+
export function createSlotConfig(overrides, defaults) {
|
|
131
|
+
const config = new Map();
|
|
132
|
+
for (const key in defaults) {
|
|
133
|
+
const override = overrides[key];
|
|
134
|
+
const defaultComponent = defaults[key];
|
|
135
|
+
config.set(key, normalizeSlotValue(override, defaultComponent));
|
|
136
|
+
}
|
|
137
|
+
return config;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Provides slot configuration to child components via DI.
|
|
141
|
+
*
|
|
142
|
+
* @example
|
|
143
|
+
* ```typescript
|
|
144
|
+
* @Component({
|
|
145
|
+
* providers: [
|
|
146
|
+
* provideSlots({
|
|
147
|
+
* sendButton: CustomSendButton,
|
|
148
|
+
* toolbar: CustomToolbar
|
|
149
|
+
* })
|
|
150
|
+
* ]
|
|
151
|
+
* })
|
|
152
|
+
* ```
|
|
153
|
+
*/
|
|
154
|
+
export function provideSlots(slots) {
|
|
155
|
+
const slotMap = new Map();
|
|
156
|
+
// Only accept component types in DI (templates lack view context)
|
|
157
|
+
for (const [key, value] of Object.entries(slots)) {
|
|
158
|
+
if (isComponentType(value)) {
|
|
159
|
+
slotMap.set(key, { component: value });
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return {
|
|
163
|
+
provide: SLOT_CONFIG,
|
|
164
|
+
useValue: slotMap
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Gets slot configuration from DI.
|
|
169
|
+
* Must be called within an injection context.
|
|
170
|
+
*
|
|
171
|
+
* @example
|
|
172
|
+
* ```typescript
|
|
173
|
+
* export class MyComponent {
|
|
174
|
+
* slots = getSlotConfig();
|
|
175
|
+
*
|
|
176
|
+
* ngOnInit() {
|
|
177
|
+
* const sendButton = this.slots?.get('sendButton');
|
|
178
|
+
* }
|
|
179
|
+
* }
|
|
180
|
+
* ```
|
|
181
|
+
*/
|
|
182
|
+
export function getSlotConfig() {
|
|
183
|
+
return inject(SLOT_CONFIG, { optional: true });
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Creates a render function for a specific slot.
|
|
187
|
+
* Useful for creating reusable slot renderers.
|
|
188
|
+
*
|
|
189
|
+
* @example
|
|
190
|
+
* ```typescript
|
|
191
|
+
* const renderSendButton = createSlotRenderer(
|
|
192
|
+
* DefaultSendButton,
|
|
193
|
+
* 'sendButton'
|
|
194
|
+
* );
|
|
195
|
+
*
|
|
196
|
+
* // Later in template
|
|
197
|
+
* renderSendButton(this.viewContainer, this.sendButtonOverride);
|
|
198
|
+
* ```
|
|
199
|
+
*/
|
|
200
|
+
export function createSlotRenderer(defaultComponent, slotName) {
|
|
201
|
+
// Get config in the injection context when the renderer is created
|
|
202
|
+
const config = slotName ? getSlotConfig() : null;
|
|
203
|
+
return (viewContainer, slot, props, outputs) => {
|
|
204
|
+
// Check DI for overrides if slot name provided
|
|
205
|
+
if (slotName && !slot && config) {
|
|
206
|
+
const entry = config.get(slotName);
|
|
207
|
+
if (entry) {
|
|
208
|
+
if (entry.component)
|
|
209
|
+
slot = entry.component;
|
|
210
|
+
else if (entry.template)
|
|
211
|
+
slot = entry.template;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
return renderSlot(viewContainer, {
|
|
215
|
+
slot,
|
|
216
|
+
defaultComponent,
|
|
217
|
+
props,
|
|
218
|
+
outputs
|
|
219
|
+
});
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2xvdC51dGlscy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvc2xvdHMvc2xvdC51dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBRUwsV0FBVyxFQUtYLE1BQU0sRUFDUCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQW1ELFdBQVcsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUU1Rjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0F1Qkc7QUFDSCxNQUFNLFVBQVUsVUFBVSxDQUN4QixhQUErQixFQUMvQixPQUE2QjtJQUU3QixNQUFNLEVBQUUsSUFBSSxFQUFFLGdCQUFnQixFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLEdBQUcsT0FBTyxDQUFDO0lBRXJFLGFBQWEsQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUV0QixNQUFNLGFBQWEsR0FBRyxJQUFJLElBQUksZ0JBQWdCLENBQUM7SUFDL0MsTUFBTSxpQkFBaUIsR0FBRyxRQUFRLElBQUksYUFBYSxDQUFDLFFBQVEsQ0FBQztJQUU3RCxJQUFJLGFBQWEsWUFBWSxXQUFXLEVBQUUsQ0FBQztRQUN6QywrQkFBK0I7UUFDL0IsT0FBTyxhQUFhLENBQUMsa0JBQWtCLENBQUMsYUFBYSxFQUFFO1lBQ3JELFNBQVMsRUFBRSxLQUFLLElBQUksRUFBRTtZQUN0QixLQUFLLEVBQUUsS0FBSyxJQUFJLEVBQUU7U0FDWixDQUFDLENBQUM7SUFDWixDQUFDO1NBQU0sSUFBSSxlQUFlLENBQUMsYUFBYSxDQUFDLEVBQUUsQ0FBQztRQUMxQyxnREFBZ0Q7UUFDaEQsSUFBSSxDQUFDO1lBQ0gsT0FBTyxlQUFlLENBQ3BCLGFBQWEsRUFDYixhQUF3QixFQUN4QixLQUFLLEVBQ0wsaUJBQWlCLEVBQ2pCLE9BQU8sQ0FDUixDQUFDO1FBQ0osQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixPQUFPLENBQUMsSUFBSSxDQUFDLDZC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O0FBRUQ7Ozs7Ozs7Ozs7Ozs7O0dBY0c7QUFDSCxNQUFNLFVBQVUsa0JBQWtCLENBQ2hDLGdCQUF5QixFQUN6QixRQUFpQjtJQUVqQixtRUFBbUU7SUFDbkUsTUFBTSxNQUFNLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQyxhQUFhLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO0lBRWpELE9BQU8sQ0FDTCxhQUErQixFQUMvQixJQUFtQixFQUNuQixLQUFrQixFQUNsQixPQUE4QyxFQUM5QyxFQUFFO1FBQ0YsK0NBQStDO1FBQy9DLElBQUksUUFBUSxJQUFJLENBQUMsSUFBSSxJQUFJLE1BQU0sRUFBRSxDQUFDO1lBQ2hDLE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDbkMsSUFBSSxLQUFLLEVBQUUsQ0FBQztnQkFDVixJQUFJLEtBQUssQ0FBQyxTQUFTO29CQUFFLElBQUksR0FBRyxLQUFLLENBQUMsU0FBUyxDQUFDO3FCQUN2QyxJQUFJLEtBQUssQ0FBQyxRQUFRO29CQUFFLElBQUksR0FBRyxLQUFLLENBQUMsUUFBUSxDQUFDO1lBQ2pELENBQUM7UUFDSCxDQUFDO1FBRUQsT0FBTyxVQUFVLENBQUMsYUFBYSxFQUFFO1lBQy9CLElBQUk7WUFDSixnQkFBZ0I7WUFDaEIsS0FBSztZQUNMLE9BQU87U0FDUixDQUFDLENBQUM7SUFDTCxDQUFDLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgXG4gIFR5cGUsIFxuICBUZW1wbGF0ZVJlZiwgXG4gIFZpZXdDb250YWluZXJSZWYsXG4gIENvbXBvbmVudFJlZixcbiAgRW1iZWRkZWRWaWV3UmVmLFxuICBJbmplY3RvcixcbiAgaW5qZWN0XG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgU2xvdFZhbHVlLCBSZW5kZXJTbG90T3B0aW9ucywgU2xvdFJlZ2lzdHJ5RW50cnksIFNMT1RfQ09ORklHIH0gZnJvbSAnLi9zbG90LnR5cGVzJztcblxuLyoqXG4gKiBSZW5kZXJzIGEgc2xvdCB2YWx1ZSBpbnRvIGEgVmlld0NvbnRhaW5lclJlZi5cbiAqIFRoaXMgaXMgdGhlIGNvcmUgdXRpbGl0eSBmb3Igc2xvdCByZW5kZXJpbmcuXG4gKiBcbiAqIEBwYXJhbSB2aWV3Q29udGFpbmVyIC0gVGhlIFZpZXdDb250YWluZXJSZWYgdG8gcmVuZGVyIGludG9cbiAqIEBwYXJhbSBvcHRpb25zIC0gT3B0aW9ucyBmb3IgcmVuZGVyaW5nIHRoZSBzbG90XG4gKiBAcmV0dXJucyBUaGUgY3JlYXRlZCBjb21wb25lbnQgb3IgZW1iZWRkZWQgdmlldyByZWZlcmVuY2VcbiAqIFxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGV4cG9ydCBjbGFzcyBNeUNvbXBvbmVudCB7XG4gKiAgIEBWaWV3Q2hpbGQoJ2NvbnRhaW5lcicsIHsgcmVhZDogVmlld0NvbnRhaW5lclJlZiB9KSBjb250YWluZXIhOiBWaWV3Q29udGFpbmVyUmVmO1xuICogICBcbiAqICAgcmVuZGVyQnV0dG9uKCkge1xuICogICAgIHJlbmRlclNsb3QodGhpcy5jb250YWluZXIsIHtcbiAqICAgICAgIHNsb3Q6IHRoaXMuYnV0dG9uT3ZlcnJpZGUsXG4gKiAgICAgICBkZWZhdWx0Q29tcG9uZW50OiBEZWZhdWx0QnV0dG9uLFxuICogICAgICAgcHJvcHM6IHsgdGV4dDogJ0NsaWNrIG1lJyB9LFxuICogICAgICAgb3V0cHV0czogeyBjbGljazogKGV2ZW50KSA9PiB0aGlzLmhhbmRsZUNsaWNrKGV2ZW50KSB9XG4gKiAgICAgfSk7XG4gKiAgIH1cbiAqIH1cbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVuZGVyU2xvdDxUID0gYW55PihcbiAgdmlld0NvbnRhaW5lcjogVmlld0NvbnRhaW5lclJlZixcbiAgb3B0aW9uczogUmVuZGVyU2xvdE9wdGlvbnM8VD5cbik6IENvbXBvbmVudFJlZjxUPiB8IEVtYmVkZGVkVmlld1JlZjxUPiB8IG51bGwge1xuICBjb25zdCB7IHNsb3QsIGRlZmF1bHRDb21wb25lbnQsIHByb3BzLCBpbmplY3Rvciwgb3V0cHV0cyB9ID0gb3B0aW9ucztcbiAgXG4gIHZpZXdDb250YWluZXIuY2xlYXIoKTtcbiAgXG4gIGNvbnN0IGVmZmVjdGl2ZVNsb3QgPSBzbG90ID8/IGRlZmF1bHRDb21wb25lbnQ7XG4gIGNvbnN0IGVmZmVjdGl2ZUluamVjdG9yID0gaW5qZWN0b3IgPz8gdmlld0NvbnRhaW5lci5pbmplY3RvcjtcbiAgXG4gIGlmIChlZmZlY3RpdmVTbG90IGluc3RhbmNlb2YgVGVtcGxhdGVSZWYpIHtcbiAgICAvLyBUZW1wbGF0ZVJlZjogcmVuZGVyIHRlbXBsYXRlXG4gICAgcmV0dXJuIHZpZXdDb250YWluZXIuY3JlYXRlRW1iZWRkZWRWaWV3KGVmZmVjdGl2ZVNsb3QsIHtcbiAgICAgICRpbXBsaWNpdDogcHJvcHMgPz8ge30sXG4gICAgICBwcm9wczogcHJvcHMgPz8ge31cbiAgICB9IGFzIGFueSk7XG4gIH0gZWxzZSBpZiAoaXNDb21wb25lbnRUeXBlKGVmZmVjdGl2ZVNsb3QpKSB7XG4gICAgLy8gQ29tcG9uZW50IHR5cGUgLSB3cmFwIGluIHRyeS9jYXRjaCBmb3Igc2FmZXR5XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBjcmVhdGVDb21wb25lbnQoXG4gICAgICAgIHZpZXdDb250YWluZXIsXG4gICAgICAgIGVmZmVjdGl2ZVNsb3QgYXMgVHlwZTxUPixcbiAgICAgICAgcHJvcHMsXG4gICAgICAgIGVmZmVjdGl2ZUluamVjdG9yLFxuICAgICAgICBvdXRwdXRzXG4gICAgICApO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zb2xlLndhcm4oJ0ZhaWxlZCB0byBjcmVhdGUgY29tcG9uZW50OicsIGVmZmVjdGl2ZVNsb3QsIGVycm9yKTtcbiAgICAgIC8vIEZhbGwgdGhyb3VnaCB0byBkZWZhdWx0IGNvbXBvbmVudFxuICAgIH1cbiAgfVxuICBcbiAgLy8gRGVmYXVsdDogcmVuZGVyIGRlZmF1bHQgY29tcG9uZW50IGlmIHByb3ZpZGVkXG4gIHJldHVybiBkZWZhdWx0Q29tcG9uZW50ID8gY3JlYXRlQ29tcG9uZW50KFxuICAgIHZpZXdDb250YWluZXIsXG4gICAgZGVmYXVsdENvbXBvbmVudCxcbiAgICBwcm9wcyxcbiAgICBlZmZlY3RpdmVJbmplY3RvcixcbiAgICBvdXRwdXRzXG4gICkgOiBudWxsO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBjb21wb25lbnQgYW5kIGFwcGxpZXMgcHJvcGVydGllcy5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlQ29tcG9uZW50PFQ+KFxuICB2aWV3Q29udGFpbmVyOiBWaWV3Q29udGFpbmVyUmVmLFxuICBjb21wb25lbnQ6IFR5cGU8VD4sXG4gIHByb3BzPzogUGFydGlhbDxUPixcbiAgaW5qZWN0b3I/OiBJbmplY3RvcixcbiAgb3V0cHV0cz86IFJlY29yZDxzdHJpbmcsIChldmVudDogYW55KSA9PiB2b2lkPlxuKTogQ29tcG9uZW50UmVmPFQ+IHtcbiAgY29uc3QgY29tcG9uZW50UmVmID0gdmlld0NvbnRhaW5lci5jcmVhdGVDb21wb25lbnQoY29tcG9uZW50LCB7XG4gICAgaW5qZWN0b3JcbiAgfSk7XG4gIFxuICBpZiAocHJvcHMpIHtcbiAgICAvLyBBcHBseSBwcm9wcyB1c2luZyBzZXRJbnB1dFxuICAgIGZvciAoY29uc3Qga2V5IGluIHByb3BzKSB7XG4gICAgICBjb25zdCB2YWx1ZSA9IHByb3BzW2tleV07XG4gICAgICBjb21wb25lbnRSZWYuc2V0SW5wdXQoa2V5LCB2YWx1ZSk7XG4gICAgfVxuICB9XG4gIFxuICBpZiAob3V0cHV0cykge1xuICAgIC8vIFdpcmUgdXAgb3V0cHV0IGV2ZW50IGhhbmRsZXJzIHdpdGggcHJvcGVyIGNsZWFudXBcbiAgICBjb25zdCBpbnN0YW5jZSA9IGNvbXBvbmVudFJlZi5pbnN0YW5jZSBhcyBhbnk7XG4gICAgY29uc3Qgc3Vic2NyaXB0aW9uczogYW55W10gPSBbXTtcbiAgICBcbiAgICBmb3IgKGNvbnN0IFtldmVudE5hbWUsIGhhbmRsZXJdIG9mIE9iamVjdC5lbnRyaWVzKG91dHB1dHMpKSB7XG4gICAgICBpZiAoaW5zdGFuY2VbZXZlbnROYW1lXT8uc3Vic2NyaWJlKSB7XG4gICAgICAgIGNvbnN0IHN1YnNjcmlwdGlvbiA9IGluc3RhbmNlW2V2ZW50TmFtZV0uc3Vic2NyaWJlKGhhbmRsZXIpO1xuICAgICAgICBzdWJzY3JpcHRpb25zLnB1c2goc3Vic2NyaXB0aW9uKTtcbiAgICAgIH1cbiAgICB9XG4gICAgXG4gICAgLy8gUmVnaXN0ZXIgY2xlYW51cCBvbiBjb21wb25lbnQgZGVzdHJveVxuICAgIGNvbXBvbmVudFJlZi5vbkRlc3Ryb3koKCkgPT4ge1xuICAgICAgc3Vic2NyaXB0aW9ucy5mb3JFYWNoKHN1YiA9PiBzdWIudW5zdWJzY3JpYmUoKSk7XG4gICAgfSk7XG4gIH1cbiAgXG4gIC8vIFRyaWdnZXIgY2hhbmdlIGRldGVjdGlvblxuICBjb21wb25lbnRSZWYuY2hhbmdlRGV0ZWN0b3JSZWYuZGV0ZWN0Q2hhbmdlcygpO1xuICBcbiAgcmV0dXJuIGNvbXBvbmVudFJlZjtcbn1cblxuXG4vKipcbiAqIENoZWNrcyBpZiBhIHZhbHVlIGlzIGEgY29tcG9uZW50IHR5cGUuXG4gKiBTaW1wbGlmaWVkIGNoZWNrIC0gcmVseSBvbiB0cnkvY2F0Y2ggZm9yIGFjdHVhbCB2YWxpZGF0aW9uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNDb21wb25lbnRUeXBlKHZhbHVlOiBhbnkpOiBib29sZWFuIHtcbiAgLy8gQXJyb3cgZnVuY3Rpb25zIGFuZCByZWd1bGFyIGZ1bmN0aW9ucyB3aXRob3V0IGEgcHJvdG90eXBlIGFyZSBub3QgY29tcG9uZW50c1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nICYmICEhdmFsdWUucHJvdG90eXBlO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiBhIHZhbHVlIGlzIGEgdmFsaWQgc2xvdCB2YWx1ZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzU2xvdFZhbHVlKHZhbHVlOiBhbnkpOiB2YWx1ZSBpcyBTbG90VmFsdWUge1xuICByZXR1cm4gdmFsdWUgaW5zdGFuY2VvZiBUZW1wbGF0ZVJlZiB8fCBpc0NvbXBvbmVudFR5cGUodmFsdWUpO1xufVxuXG4vKipcbiAqIE5vcm1hbGl6ZXMgYSBzbG90IHZhbHVlIHRvIGEgY29uc2lzdGVudCBmb3JtYXQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemVTbG90VmFsdWU8VCA9IGFueT4oXG4gIHZhbHVlOiBTbG90VmFsdWU8VD4gfCB1bmRlZmluZWQsXG4gIGRlZmF1bHRDb21wb25lbnQ6IFR5cGU8VD4gfCB1bmRlZmluZWRcbik6IFNsb3RSZWdpc3RyeUVudHJ5PFQ+IHtcbiAgaWYgKCF2YWx1ZSkge1xuICAgIHJldHVybiB7IGNvbXBvbmVudDogZGVmYXVsdENvbXBvbmVudCB9O1xuICB9XG4gIFxuICBpZiAodmFsdWUgaW5zdGFuY2VvZiBUZW1wbGF0ZVJlZikge1xuICAgIHJldHVybiB7IHRlbXBsYXRlOiB2YWx1ZSB9O1xuICB9XG4gIFxuICBpZiAoaXNDb21wb25lbnRUeXBlKHZhbHVlKSkge1xuICAgIHJldHVybiB7IGNvbXBvbmVudDogdmFsdWUgYXMgVHlwZTxUPiB9O1xuICB9XG4gIFxuICByZXR1cm4geyBjb21wb25lbnQ6IGRlZmF1bHRDb21wb25lbnQgfTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgc2xvdCBjb25maWd1cmF0aW9uIG1hcCBmb3IgYSBjb21wb25lbnQuXG4gKiBcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBzbG90cyA9IGNyZWF0ZVNsb3RDb25maWcoe1xuICogICBzZW5kQnV0dG9uOiBDdXN0b21TZW5kQnV0dG9uLFxuICogICB0b29sYmFyOiAnY3VzdG9tLXRvb2xiYXItY2xhc3MnLFxuICogICBmb290ZXI6IGZvb3RlclRlbXBsYXRlXG4gKiB9LCB7XG4gKiAgIHNlbmRCdXR0b246IERlZmF1bHRTZW5kQnV0dG9uLFxuICogICB0b29sYmFyOiBEZWZhdWx0VG9vbGJhcixcbiAqICAgZm9vdGVyOiBEZWZhdWx0Rm9vdGVyXG4gKiB9KTtcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlU2xvdENvbmZpZzxUIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgVHlwZTxhbnk+Pj4oXG4gIG92ZXJyaWRlczogUGFydGlhbDxSZWNvcmQ8a2V5b2YgVCwgU2xvdFZhbHVlPj4sXG4gIGRlZmF1bHRzOiBUXG4pOiBNYXA8a2V5b2YgVCwgU2xvdFJlZ2lzdHJ5RW50cnk+IHtcbiAgY29uc3QgY29uZmlnID0gbmV3IE1hcDxrZXlvZiBULCBTbG90UmVnaXN0cnlFbnRyeT4oKTtcbiAgXG4gIGZvciAoY29uc3Qga2V5IGluIGRlZmF1bHRzKSB7XG4gICAgY29uc3Qgb3ZlcnJpZGUgPSBvdmVycmlkZXNba2V5XTtcbiAgICBjb25zdCBkZWZhdWx0Q29tcG9uZW50ID0gZGVmYXVsdHNba2V5XTtcbiAgICBjb25maWcuc2V0KGtleSwgbm9ybWFsaXplU2xvdFZhbHVlKG92ZXJyaWRlLCBkZWZhdWx0Q29tcG9uZW50KSk7XG4gIH1cbiAgXG4gIHJldHVybiBjb25maWc7XG59XG5cbi8qKlxuICogUHJvdmlkZXMgc2xvdCBjb25maWd1cmF0aW9uIHRvIGNoaWxkIGNvbXBvbmVudHMgdmlhIERJLlxuICogXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogQENvbXBvbmVudCh7XG4gKiAgIHByb3ZpZGVyczogW1xuICogICAgIHByb3ZpZGVTbG90cyh7XG4gKiAgICAgICBzZW5kQnV0dG9uOiBDdXN0b21TZW5kQnV0dG9uLFxuICogICAgICAgdG9vbGJhcjogQ3VzdG9tVG9vbGJhclxuICogICAgIH0pXG4gKiAgIF1cbiAqIH0pXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHByb3ZpZGVTbG90cyhzbG90czogUmVjb3JkPHN0cmluZywgVHlwZTxhbnk+Pikge1xuICBjb25zdCBzbG90TWFwID0gbmV3IE1hcDxzdHJpbmcsIFNsb3RSZWdpc3RyeUVudHJ5PigpO1xuICBcbiAgLy8gT25seSBhY2NlcHQgY29tcG9uZW50IHR5cGVzIGluIERJICh0ZW1wbGF0ZXMgbGFjayB2aWV3IGNvbnRleHQpXG4gIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKHNsb3RzKSkge1xuICAgIGlmIChpc0NvbXBvbmVudFR5cGUodmFsdWUpKSB7XG4gICAgICBzbG90TWFwLnNldChrZXksIHsgY29tcG9uZW50OiB2YWx1ZSBhcyBUeXBlPGFueT4gfSk7XG4gICAgfVxuICB9XG4gIFxuICByZXR1cm4ge1xuICAgIHByb3ZpZGU6IFNMT1RfQ09ORklHLFxuICAgIHVzZVZhbHVlOiBzbG90TWFwXG4gIH07XG59XG5cbi8qKlxuICogR2V0cyBzbG90IGNvbmZpZ3VyYXRpb24gZnJvbSBESS5cbiAqIE11c3QgYmUgY2FsbGVkIHdpdGhpbiBhbiBpbmplY3Rpb24gY29udGV4dC5cbiAqIFxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGV4cG9ydCBjbGFzcyBNeUNvbXBvbmVudCB7XG4gKiAgIHNsb3RzID0gZ2V0U2xvdENvbmZpZygpO1xuICogICBcbiAqICAgbmdPbkluaXQoKSB7XG4gKiAgICAgY29uc3Qgc2VuZEJ1dHRvbiA9IHRoaXMuc2xvdHM/LmdldCgnc2VuZEJ1dHRvbicpO1xuICogICB9XG4gKiB9XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFNsb3RDb25maWcoKTogUmVhZG9ubHlNYXA8c3RyaW5nLCBTbG90UmVnaXN0cnlFbnRyeT4gfCBudWxsIHtcbiAgcmV0dXJuIGluamVjdChTTE9UX0NPTkZJRywgeyBvcHRpb25hbDogdHJ1ZSB9KTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgcmVuZGVyIGZ1bmN0aW9uIGZvciBhIHNwZWNpZmljIHNsb3QuXG4gKiBVc2VmdWwgZm9yIGNyZWF0aW5nIHJldXNhYmxlIHNsb3QgcmVuZGVyZXJzLlxuICogXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgcmVuZGVyU2VuZEJ1dHRvbiA9IGNyZWF0ZVNsb3RSZW5kZXJlcihcbiAqICAgRGVmYXVsdFNlbmRCdXR0b24sXG4gKiAgICdzZW5kQnV0dG9uJ1xuICogKTtcbiAqIFxuICogLy8gTGF0ZXIgaW4gdGVtcGxhdGVcbiAqIHJlbmRlclNlbmRCdXR0b24odGhpcy52aWV3Q29udGFpbmVyLCB0aGlzLnNlbmRCdXR0b25PdmVycmlkZSk7XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVNsb3RSZW5kZXJlcjxUPihcbiAgZGVmYXVsdENvbXBvbmVudDogVHlwZTxUPixcbiAgc2xvdE5hbWU/OiBzdHJpbmdcbikge1xuICAvLyBHZXQgY29uZmlnIGluIHRoZSBpbmplY3Rpb24gY29udGV4dCB3aGVuIHRoZSByZW5kZXJlciBpcyBjcmVhdGVkXG4gIGNvbnN0IGNvbmZpZyA9IHNsb3ROYW1lID8gZ2V0U2xvdENvbmZpZygpIDogbnVsbDtcbiAgXG4gIHJldHVybiAoXG4gICAgdmlld0NvbnRhaW5lcjogVmlld0NvbnRhaW5lclJlZixcbiAgICBzbG90PzogU2xvdFZhbHVlPFQ+LFxuICAgIHByb3BzPzogUGFydGlhbDxUPixcbiAgICBvdXRwdXRzPzogUmVjb3JkPHN0cmluZywgKGV2ZW50OiBhbnkpID0+IHZvaWQ+XG4gICkgPT4ge1xuICAgIC8vIENoZWNrIERJIGZvciBvdmVycmlkZXMgaWYgc2xvdCBuYW1lIHByb3ZpZGVkXG4gICAgaWYgKHNsb3ROYW1lICYmICFzbG90ICYmIGNvbmZpZykge1xuICAgICAgY29uc3QgZW50cnkgPSBjb25maWcuZ2V0KHNsb3ROYW1lKTtcbiAgICAgIGlmIChlbnRyeSkge1xuICAgICAgICBpZiAoZW50cnkuY29tcG9uZW50KSBzbG90ID0gZW50cnkuY29tcG9uZW50O1xuICAgICAgICBlbHNlIGlmIChlbnRyeS50ZW1wbGF0ZSkgc2xvdCA9IGVudHJ5LnRlbXBsYXRlO1xuICAgICAgfVxuICAgIH1cbiAgICBcbiAgICByZXR1cm4gcmVuZGVyU2xvdCh2aWV3Q29udGFpbmVyLCB7XG4gICAgICBzbG90LFxuICAgICAgZGVmYXVsdENvbXBvbmVudCxcbiAgICAgIHByb3BzLFxuICAgICAgb3V0cHV0c1xuICAgIH0pO1xuICB9O1xufSJdfQ==
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { clsx } from 'clsx';
|
|
2
|
+
import { twMerge } from 'tailwind-merge';
|
|
3
|
+
/**
|
|
4
|
+
* Utility function to merge Tailwind CSS classes
|
|
5
|
+
* Combines clsx for conditional classes and tailwind-merge for proper Tailwind class merging
|
|
6
|
+
*/
|
|
7
|
+
export function cn(...inputs) {
|
|
8
|
+
return twMerge(clsx(inputs));
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL3V0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxJQUFJLEVBQW1CLE1BQU0sTUFBTSxDQUFDO0FBQzdDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUV6Qzs7O0dBR0c7QUFDSCxNQUFNLFVBQVUsRUFBRSxDQUFDLEdBQUcsTUFBb0I7SUFDeEMsT0FBTyxPQUFPLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7QUFDL0IsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGNsc3gsIHR5cGUgQ2xhc3NWYWx1ZSB9IGZyb20gJ2Nsc3gnO1xuaW1wb3J0IHsgdHdNZXJnZSB9IGZyb20gJ3RhaWx3aW5kLW1lcmdlJztcblxuLyoqXG4gKiBVdGlsaXR5IGZ1bmN0aW9uIHRvIG1lcmdlIFRhaWx3aW5kIENTUyBjbGFzc2VzXG4gKiBDb21iaW5lcyBjbHN4IGZvciBjb25kaXRpb25hbCBjbGFzc2VzIGFuZCB0YWlsd2luZC1tZXJnZSBmb3IgcHJvcGVyIFRhaWx3aW5kIGNsYXNzIG1lcmdpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNuKC4uLmlucHV0czogQ2xhc3NWYWx1ZVtdKSB7XG4gIHJldHVybiB0d01lcmdlKGNsc3goaW5wdXRzKSk7XG59Il19
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { Injectable, ElementRef } from '@angular/core';
|
|
2
|
+
import { Subject, BehaviorSubject } from 'rxjs';
|
|
3
|
+
import { debounceTime, takeUntil, distinctUntilChanged } from 'rxjs/operators';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
export class ResizeObserverService {
|
|
6
|
+
ngZone;
|
|
7
|
+
destroy$ = new Subject();
|
|
8
|
+
observers = new Map();
|
|
9
|
+
resizeStates = new Map();
|
|
10
|
+
resizeTimeouts = new Map();
|
|
11
|
+
constructor(ngZone) {
|
|
12
|
+
this.ngZone = ngZone;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Observe element resize with debouncing and resizing state
|
|
16
|
+
* @param element Element to observe
|
|
17
|
+
* @param debounceMs Debounce time (default 250ms)
|
|
18
|
+
* @param resizingDurationMs How long to show "isResizing" state (default 250ms)
|
|
19
|
+
*/
|
|
20
|
+
observeElement(element, debounceMs = 0, resizingDurationMs = 250) {
|
|
21
|
+
const el = element instanceof ElementRef ? element.nativeElement : element;
|
|
22
|
+
// Return existing observer if already observing
|
|
23
|
+
if (this.resizeStates.has(el)) {
|
|
24
|
+
return this.resizeStates.get(el).asObservable();
|
|
25
|
+
}
|
|
26
|
+
// Create new subject for this element
|
|
27
|
+
const resizeState$ = new BehaviorSubject({
|
|
28
|
+
width: el.offsetWidth,
|
|
29
|
+
height: el.offsetHeight,
|
|
30
|
+
isResizing: false
|
|
31
|
+
});
|
|
32
|
+
this.resizeStates.set(el, resizeState$);
|
|
33
|
+
// Create ResizeObserver
|
|
34
|
+
const resizeObserver = new ResizeObserver((entries) => {
|
|
35
|
+
if (entries.length === 0)
|
|
36
|
+
return;
|
|
37
|
+
const entry = entries[0];
|
|
38
|
+
if (!entry)
|
|
39
|
+
return;
|
|
40
|
+
const { width, height } = entry.contentRect;
|
|
41
|
+
this.ngZone.run(() => {
|
|
42
|
+
// Clear existing timeout
|
|
43
|
+
const existingTimeout = this.resizeTimeouts.get(el);
|
|
44
|
+
if (existingTimeout) {
|
|
45
|
+
clearTimeout(existingTimeout);
|
|
46
|
+
}
|
|
47
|
+
// Update state with isResizing = true
|
|
48
|
+
resizeState$.next({
|
|
49
|
+
width,
|
|
50
|
+
height,
|
|
51
|
+
isResizing: true
|
|
52
|
+
});
|
|
53
|
+
// Set timeout to clear isResizing flag
|
|
54
|
+
if (resizingDurationMs > 0) {
|
|
55
|
+
const timeout = window.setTimeout(() => {
|
|
56
|
+
resizeState$.next({
|
|
57
|
+
width,
|
|
58
|
+
height,
|
|
59
|
+
isResizing: false
|
|
60
|
+
});
|
|
61
|
+
this.resizeTimeouts.delete(el);
|
|
62
|
+
}, resizingDurationMs);
|
|
63
|
+
this.resizeTimeouts.set(el, timeout);
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
// If no duration, immediately set isResizing to false
|
|
67
|
+
resizeState$.next({
|
|
68
|
+
width,
|
|
69
|
+
height,
|
|
70
|
+
isResizing: false
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
// Start observing
|
|
76
|
+
resizeObserver.observe(el);
|
|
77
|
+
this.observers.set(el, resizeObserver);
|
|
78
|
+
// Return observable with debouncing if specified
|
|
79
|
+
const observable = resizeState$.asObservable().pipe(debounceMs > 0 ? debounceTime(debounceMs) : (source) => source, distinctUntilChanged((a, b) => a.width === b.width &&
|
|
80
|
+
a.height === b.height &&
|
|
81
|
+
a.isResizing === b.isResizing), takeUntil(this.destroy$));
|
|
82
|
+
return observable;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Stop observing an element
|
|
86
|
+
* @param element Element to stop observing
|
|
87
|
+
*/
|
|
88
|
+
unobserve(element) {
|
|
89
|
+
const el = element instanceof ElementRef ? element.nativeElement : element;
|
|
90
|
+
// Clear timeout if exists
|
|
91
|
+
const timeout = this.resizeTimeouts.get(el);
|
|
92
|
+
if (timeout) {
|
|
93
|
+
clearTimeout(timeout);
|
|
94
|
+
this.resizeTimeouts.delete(el);
|
|
95
|
+
}
|
|
96
|
+
// Disconnect observer
|
|
97
|
+
const observer = this.observers.get(el);
|
|
98
|
+
if (observer) {
|
|
99
|
+
observer.disconnect();
|
|
100
|
+
this.observers.delete(el);
|
|
101
|
+
}
|
|
102
|
+
// Complete and remove subject
|
|
103
|
+
const subject = this.resizeStates.get(el);
|
|
104
|
+
if (subject) {
|
|
105
|
+
subject.complete();
|
|
106
|
+
this.resizeStates.delete(el);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Get current size of element
|
|
111
|
+
* @param element Element to measure
|
|
112
|
+
*/
|
|
113
|
+
getCurrentSize(element) {
|
|
114
|
+
const el = element instanceof ElementRef ? element.nativeElement : element;
|
|
115
|
+
return {
|
|
116
|
+
width: el.offsetWidth,
|
|
117
|
+
height: el.offsetHeight
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Get current resize state of element
|
|
122
|
+
* @param element Element to check
|
|
123
|
+
*/
|
|
124
|
+
getCurrentState(element) {
|
|
125
|
+
const el = element instanceof ElementRef ? element.nativeElement : element;
|
|
126
|
+
const subject = this.resizeStates.get(el);
|
|
127
|
+
return subject ? subject.value : null;
|
|
128
|
+
}
|
|
129
|
+
ngOnDestroy() {
|
|
130
|
+
// Clear all timeouts
|
|
131
|
+
this.resizeTimeouts.forEach(timeout => clearTimeout(timeout));
|
|
132
|
+
this.resizeTimeouts.clear();
|
|
133
|
+
// Disconnect all observers
|
|
134
|
+
this.observers.forEach(observer => observer.disconnect());
|
|
135
|
+
this.observers.clear();
|
|
136
|
+
// Complete all subjects
|
|
137
|
+
this.resizeStates.forEach(subject => subject.complete());
|
|
138
|
+
this.resizeStates.clear();
|
|
139
|
+
// Complete destroy subject
|
|
140
|
+
this.destroy$.next();
|
|
141
|
+
this.destroy$.complete();
|
|
142
|
+
}
|
|
143
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ResizeObserverService, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
144
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ResizeObserverService, providedIn: 'root' });
|
|
145
|
+
}
|
|
146
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ResizeObserverService, decorators: [{
|
|
147
|
+
type: Injectable,
|
|
148
|
+
args: [{
|
|
149
|
+
providedIn: 'root'
|
|
150
|
+
}]
|
|
151
|
+
}], ctorParameters: () => [{ type: i0.NgZone }] });
|
|
152
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzaXplLW9ic2VydmVyLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvc2VydmljZXMvcmVzaXplLW9ic2VydmVyLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQXFCLE1BQU0sZUFBZSxDQUFDO0FBQzFFLE9BQU8sRUFBYyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzVELE9BQU8sRUFBRSxZQUFZLEVBQUUsU0FBUyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7O0FBVy9FLE1BQU0sT0FBTyxxQkFBcUI7SUFNWjtJQUxaLFFBQVEsR0FBRyxJQUFJLE9BQU8sRUFBUSxDQUFDO0lBQy9CLFNBQVMsR0FBRyxJQUFJLEdBQUcsRUFBK0IsQ0FBQztJQUNuRCxZQUFZLEdBQUcsSUFBSSxHQUFHLEVBQTZDLENBQUM7SUFDcEUsY0FBYyxHQUFHLElBQUksR0FBRyxFQUF1QixDQUFDO0lBRXhELFlBQW9CLE1BQWM7UUFBZCxXQUFNLEdBQU4sTUFBTSxDQUFRO0lBQUcsQ0FBQztJQUV0Qzs7Ozs7T0FLRztJQUNILGNBQWMsQ0FDWixPQUE4QyxFQUM5QyxhQUFxQixDQUFDLEVBQ3RCLHFCQUE2QixHQUFHO1FBRWhDLE1BQU0sRUFBRSxHQUFHLE9BQU8sWUFBWSxVQUFVLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQztRQUUzRSxnREFBZ0Q7UUFDaEQsSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO1lBQzlCLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFFLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDbkQsQ0FBQztRQUVELHNDQUFzQztRQUN0QyxNQUFNLFlBQVksR0FBRyxJQUFJ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RUFBRSxNQUFNO2lCQUNuQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUsIEVsZW1lbnRSZWYsIE5nWm9uZSwgT25EZXN0cm95IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBTdWJqZWN0LCBCZWhhdmlvclN1YmplY3QgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IGRlYm91bmNlVGltZSwgdGFrZVVudGlsLCBkaXN0aW5jdFVudGlsQ2hhbmdlZCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuZXhwb3J0IGludGVyZmFjZSBSZXNpemVTdGF0ZSB7XG4gIHdpZHRoOiBudW1iZXI7XG4gIGhlaWdodDogbnVtYmVyO1xuICBpc1Jlc2l6aW5nOiBib29sZWFuO1xufVxuXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290J1xufSlcbmV4cG9ydCBjbGFzcyBSZXNpemVPYnNlcnZlclNlcnZpY2UgaW1wbGVtZW50cyBPbkRlc3Ryb3kge1xuICBwcml2YXRlIGRlc3Ryb3kkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcbiAgcHJpdmF0ZSBvYnNlcnZlcnMgPSBuZXcgTWFwPEhUTUxFbGVtZW50LCBSZXNpemVPYnNlcnZlcj4oKTtcbiAgcHJpdmF0ZSByZXNpemVTdGF0ZXMgPSBuZXcgTWFwPEhUTUxFbGVtZW50LCBCZWhhdmlvclN1YmplY3Q8UmVzaXplU3RhdGU+PigpO1xuICBwcml2YXRlIHJlc2l6ZVRpbWVvdXRzID0gbmV3IE1hcDxIVE1MRWxlbWVudCwgbnVtYmVyPigpO1xuICBcbiAgY29uc3RydWN0b3IocHJpdmF0ZSBuZ1pvbmU6IE5nWm9uZSkge31cbiAgXG4gIC8qKlxuICAgKiBPYnNlcnZlIGVsZW1lbnQgcmVzaXplIHdpdGggZGVib3VuY2luZyBhbmQgcmVzaXppbmcgc3RhdGVcbiAgICogQHBhcmFtIGVsZW1lbnQgRWxlbWVudCB0byBvYnNlcnZlXG4gICAqIEBwYXJhbSBkZWJvdW5jZU1zIERlYm91bmNlIHRpbWUgKGRlZmF1bHQgMjUwbXMpXG4gICAqIEBwYXJhbSByZXNpemluZ0R1cmF0aW9uTXMgSG93IGxvbmcgdG8gc2hvdyBcImlzUmVzaXppbmdcIiBzdGF0ZSAoZGVmYXVsdCAyNTBtcylcbiAgICovXG4gIG9ic2VydmVFbGVtZW50KFxuICAgIGVsZW1lbnQ6IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+IHwgSFRNTEVsZW1lbnQsXG4gICAgZGVib3VuY2VNczogbnVtYmVyID0gMCxcbiAgICByZXNpemluZ0R1cmF0aW9uTXM6IG51bWJlciA9IDI1MFxuICApOiBPYnNlcnZhYmxlPFJlc2l6ZVN0YXRlPiB7XG4gICAgY29uc3QgZWwgPSBlbGVtZW50IGluc3RhbmNlb2YgRWxlbWVudFJlZiA/IGVsZW1lbnQubmF0aXZlRWxlbWVudCA6IGVsZW1lbnQ7XG4gICAgXG4gICAgLy8gUmV0dXJuIGV4aXN0aW5nIG9ic2VydmVyIGlmIGFscmVhZHkgb2JzZXJ2aW5nXG4gICAgaWYgKHRoaXMucmVzaXplU3RhdGVzLmhhcyhlbCkpIHtcbiAgICAgIHJldHVybiB0aGlzLnJlc2l6ZVN0YXRlcy5nZXQoZWwpIS5hc09ic2VydmFibGUoKTtcbiAgICB9XG4gICAgXG4gICAgLy8gQ3JlYXRlIG5ldyBzdWJqZWN0IGZvciB0aGlzIGVsZW1lbnRcbiAgICBjb25zdCByZXNpemVTdGF0ZSQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFJlc2l6ZVN0YXRlPih7XG4gICAgICB3aWR0aDogZWwub2Zmc2V0V2lkdGgsXG4gICAgICBoZWlnaHQ6IGVsLm9mZnNldEhlaWdodCxcbiAgICAgIGlzUmVzaXppbmc6IGZhbHNlXG4gICAgfSk7XG4gICAgXG4gICAgdGhpcy5yZXNpemVTdGF0ZXMuc2V0KGVsLCByZXNpemVTdGF0ZSQpO1xuICAgIFxuICAgIC8vIENyZWF0ZSBSZXNpemVPYnNlcnZlclxuICAgIGNvbnN0IHJlc2l6ZU9ic2VydmVyID0gbmV3IFJlc2l6ZU9ic2VydmVyKChlbnRyaWVzKSA9PiB7XG4gICAgICBpZiAoZW50cmllcy5sZW5ndGggPT09IDApIHJldHVybjtcbiAgICAgIFxuICAgICAgY29uc3QgZW50cnkgPSBlbnRyaWVzWzBdO1xuICAgICAgaWYgKCFlbnRyeSkgcmV0dXJuO1xuICAgICAgXG4gICAgICBjb25zdCB7IHdpZHRoLCBoZWlnaHQgfSA9IGVudHJ5LmNvbnRlbnRSZWN0O1xuICAgICAgXG4gICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4ge1xuICAgICAgICAvLyBDbGVhciBleGlzdGluZyB0aW1lb3V0XG4gICAgICAgIGNvbnN0IGV4aXN0aW5nVGltZW91dCA9IHRoaXMucmVzaXplVGltZW91dHMuZ2V0KGVsKTtcbiAgICAgICAgaWYgKGV4aXN0aW5nVGltZW91dCkge1xuICAgICAgICAgIGNsZWFyVGltZW91dChleGlzdGluZ1RpbWVvdXQpO1xuICAgICAgICB9XG4gICAgICAgIFxuICAgICAgICAvLyBVcGRhdGUgc3RhdGUgd2l0aCBpc1Jlc2l6aW5nID0gdHJ1ZVxuICAgICAgICByZXNpemVTdGF0ZSQubmV4dCh7XG4gICAgICAgICAgd2lkdGgsXG4gICAgICAgICAgaGVpZ2h0LFxuICAgICAgICAgIGlzUmVzaXppbmc6IHRydWVcbiAgICAgICAgfSk7XG4gICAgICAgIFxuICAgICAgICAvLyBTZXQgdGltZW91dCB0byBjbGVhciBpc1Jlc2l6aW5nIGZsYWdcbiAgICAgICAgaWYgKHJlc2l6aW5nRHVyYXRpb25NcyA+IDApIHtcbiAgICAgICAgICBjb25zdCB0aW1lb3V0ID0gd2luZG93LnNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgcmVzaXplU3RhdGUkLm5leHQoe1xuICAgICAgICAgICAgICB3aWR0aCxcbiAgICAgICAgICAgICAgaGVpZ2h0LFxuICAgICAgICAgICAgICBpc1Jlc2l6aW5nOiBmYWxzZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLnJlc2l6ZVRpbWVvdXRzLmRlbGV0ZShlbCk7XG4gICAgICAgICAgfSwgcmVzaXppbmdEdXJhdGlvbk1zKTtcbiAgICAgICAgICBcbiAgICAgICAgICB0aGlzLnJlc2l6ZVRpbWVvdXRzLnNldChlbCwgdGltZW91dCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gSWYgbm8gZHVyYXRpb24sIGltbWVkaWF0ZWx5IHNldCBpc1Jlc2l6aW5nIHRvIGZhbHNlXG4gICAgICAgICAgcmVzaXplU3RhdGUkLm5leHQoe1xuICAgICAgICAgICAgd2lkdGgsXG4gICAgICAgICAgICBoZWlnaHQsXG4gICAgICAgICAgICBpc1Jlc2l6aW5nOiBmYWxzZVxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcbiAgICBcbiAgICAvLyBTdGFydCBvYnNlcnZpbmdcbiAgICByZXNpemVPYnNlcnZlci5vYnNlcnZlKGVsKTtcbiAgICB0aGlzLm9ic2VydmVycy5zZXQoZWwsIHJlc2l6ZU9ic2VydmVyKTtcbiAgICBcbiAgICAvLyBSZXR1cm4gb2JzZXJ2YWJsZSB3aXRoIGRlYm91bmNpbmcgaWYgc3BlY2lmaWVkXG4gICAgY29uc3Qgb2JzZXJ2YWJsZSA9IHJlc2l6ZVN0YXRlJC5hc09ic2VydmFibGUoKS5waXBlKFxuICAgICAgZGVib3VuY2VNcyA+IDAgPyBkZWJvdW5jZVRpbWUoZGVib3VuY2VNcykgOiAoc291cmNlKSA9PiBzb3VyY2UsXG4gICAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgoYSwgYikgPT4gXG4gICAgICAgIGEud2lkdGggPT09IGIud2lkdGggJiYgXG4gICAgICAgIGEuaGVpZ2h0ID09PSBiLmhlaWdodCAmJiBcbiAgICAgICAgYS5pc1Jlc2l6aW5nID09PSBiLmlzUmVzaXppbmdcbiAgICAgICksXG4gICAgICB0YWtlVW50aWwodGhpcy5kZXN0cm95JClcbiAgICApO1xuICAgIFxuICAgIHJldHVybiBvYnNlcnZhYmxlO1xuICB9XG4gIFxuICAvKipcbiAgICogU3RvcCBvYnNlcnZpbmcgYW4gZWxlbWVudFxuICAgKiBAcGFyYW0gZWxlbWVudCBFbGVtZW50IHRvIHN0b3Agb2JzZXJ2aW5nXG4gICAqL1xuICB1bm9ic2VydmUoZWxlbWVudDogRWxlbWVudFJlZjxIVE1MRWxlbWVudD4gfCBIVE1MRWxlbWVudCk6IHZvaWQge1xuICAgIGNvbnN0IGVsID0gZWxlbWVudCBpbnN0YW5jZW9mIEVsZW1lbnRSZWYgPyBlbGVtZW50Lm5hdGl2ZUVsZW1lbnQgOiBlbGVtZW50O1xuICAgIFxuICAgIC8vIENsZWFyIHRpbWVvdXQgaWYgZXhpc3RzXG4gICAgY29uc3QgdGltZW91dCA9IHRoaXMucmVzaXplVGltZW91dHMuZ2V0KGVsKTtcbiAgICBpZiAodGltZW91dCkge1xuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuICAgICAgdGhpcy5yZXNpemVUaW1lb3V0cy5kZWxldGUoZWwpO1xuICAgIH1cbiAgICBcbiAgICAvLyBEaXNjb25uZWN0IG9ic2VydmVyXG4gICAgY29uc3Qgb2JzZXJ2ZXIgPSB0aGlzLm9ic2VydmVycy5nZXQoZWwpO1xuICAgIGlmIChvYnNlcnZlcikge1xuICAgICAgb2JzZXJ2ZXIuZGlzY29ubmVjdCgpO1xuICAgICAgdGhpcy5vYnNlcnZlcnMuZGVsZXRlKGVsKTtcbiAgICB9XG4gICAgXG4gICAgLy8gQ29tcGxldGUgYW5kIHJlbW92ZSBzdWJqZWN0XG4gICAgY29uc3Qgc3ViamVjdCA9IHRoaXMucmVzaXplU3RhdGVzLmdldChlbCk7XG4gICAgaWYgKHN1YmplY3QpIHtcbiAgICAgIHN1YmplY3QuY29tcGxldGUoKTtcbiAgICAgIHRoaXMucmVzaXplU3RhdGVzLmRlbGV0ZShlbCk7XG4gICAgfVxuICB9XG4gIFxuICAvKipcbiAgICogR2V0IGN1cnJlbnQgc2l6ZSBvZiBlbGVtZW50XG4gICAqIEBwYXJhbSBlbGVtZW50IEVsZW1lbnQgdG8gbWVhc3VyZVxuICAgKi9cbiAgZ2V0Q3VycmVudFNpemUoZWxlbWVudDogRWxlbWVudFJlZjxIVE1MRWxlbWVudD4gfCBIVE1MRWxlbWVudCk6IHsgd2lkdGg6IG51bWJlcjsgaGVpZ2h0OiBudW1iZXIgfSB7XG4gICAgY29uc3QgZWwgPSBlbGVtZW50IGluc3RhbmNlb2YgRWxlbWVudFJlZiA/IGVsZW1lbnQubmF0aXZlRWxlbWVudCA6IGVsZW1lbnQ7XG4gICAgcmV0dXJuIHtcbiAgICAgIHdpZHRoOiBlbC5vZmZzZXRXaWR0aCxcbiAgICAgIGhlaWdodDogZWwub2Zmc2V0SGVpZ2h0XG4gICAgfTtcbiAgfVxuICBcbiAgLyoqXG4gICAqIEdldCBjdXJyZW50IHJlc2l6ZSBzdGF0ZSBvZiBlbGVtZW50XG4gICAqIEBwYXJhbSBlbGVtZW50IEVsZW1lbnQgdG8gY2hlY2tcbiAgICovXG4gIGdldEN1cnJlbnRTdGF0ZShlbGVtZW50OiBFbGVtZW50UmVmPEhUTUxFbGVtZW50PiB8IEhUTUxFbGVtZW50KTogUmVzaXplU3RhdGUgfCBudWxsIHtcbiAgICBjb25zdCBlbCA9IGVsZW1lbnQgaW5zdGFuY2VvZiBFbGVtZW50UmVmID8gZWxlbWVudC5uYXRpdmVFbGVtZW50IDogZWxlbWVudDtcbiAgICBjb25zdCBzdWJqZWN0ID0gdGhpcy5yZXNpemVTdGF0ZXMuZ2V0KGVsKTtcbiAgICByZXR1cm4gc3ViamVjdCA/IHN1YmplY3QudmFsdWUgOiBudWxsO1xuICB9XG4gIFxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICAvLyBDbGVhciBhbGwgdGltZW91dHNcbiAgICB0aGlzLnJlc2l6ZVRpbWVvdXRzLmZvckVhY2godGltZW91dCA9PiBjbGVhclRpbWVvdXQodGltZW91dCkpO1xuICAgIHRoaXMucmVzaXplVGltZW91dHMuY2xlYXIoKTtcbiAgICBcbiAgICAvLyBEaXNjb25uZWN0IGFsbCBvYnNlcnZlcnNcbiAgICB0aGlzLm9ic2VydmVycy5mb3JFYWNoKG9ic2VydmVyID0+IG9ic2VydmVyLmRpc2Nvbm5lY3QoKSk7XG4gICAgdGhpcy5vYnNlcnZlcnMuY2xlYXIoKTtcbiAgICBcbiAgICAvLyBDb21wbGV0ZSBhbGwgc3ViamVjdHNcbiAgICB0aGlzLnJlc2l6ZVN0YXRlcy5mb3JFYWNoKHN1YmplY3QgPT4gc3ViamVjdC5jb21wbGV0ZSgpKTtcbiAgICB0aGlzLnJlc2l6ZVN0YXRlcy5jbGVhcigpO1xuICAgIFxuICAgIC8vIENvbXBsZXRlIGRlc3Ryb3kgc3ViamVjdFxuICAgIHRoaXMuZGVzdHJveSQubmV4dCgpO1xuICAgIHRoaXMuZGVzdHJveSQuY29tcGxldGUoKTtcbiAgfVxufSJdfQ==
|