valtech-components 4.0.218 → 4.0.220
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/esm2022/lib/components/molecules/chat-input/chat-input.component.mjs +157 -0
- package/esm2022/lib/components/molecules/chat-input/types.mjs +2 -0
- package/esm2022/lib/components/molecules/message-bubble/message-bubble.component.mjs +244 -0
- package/esm2022/lib/components/molecules/message-bubble/types.mjs +2 -0
- package/esm2022/lib/components/molecules/typing-indicator/typing-indicator.component.mjs +76 -0
- package/esm2022/lib/components/organisms/account-view/account-view.component.mjs +2 -2
- package/esm2022/lib/components/organisms/chat-window/chat-window.component.mjs +246 -0
- package/esm2022/lib/components/organisms/chat-window/types.mjs +2 -0
- package/esm2022/lib/components/organisms/thread-panel/thread-panel.component.mjs +211 -0
- package/esm2022/lib/services/chat/config.mjs +35 -0
- package/esm2022/lib/services/chat/conversation.service.mjs +274 -0
- package/esm2022/lib/services/chat/types.mjs +10 -0
- package/esm2022/lib/services/entity-feed/entity-feed.service.mjs +103 -0
- package/esm2022/lib/services/entity-feed/index.mjs +2 -0
- package/esm2022/lib/services/entity-feed/types.mjs +2 -0
- package/esm2022/lib/services/i18n/default-content.mjs +65 -1
- package/esm2022/public-api.mjs +16 -1
- package/fesm2022/valtech-components.mjs +1370 -3
- package/fesm2022/valtech-components.mjs.map +1 -1
- package/lib/components/atoms/glow/glow.component.d.ts +1 -1
- package/lib/components/atoms/rights-footer/rights-footer.component.d.ts +2 -2
- package/lib/components/atoms/text/text.component.d.ts +1 -1
- package/lib/components/atoms/user-avatar/user-avatar.component.d.ts +2 -2
- package/lib/components/molecules/article-card/article-card.component.d.ts +1 -1
- package/lib/components/molecules/chat-input/chat-input.component.d.ts +38 -0
- package/lib/components/molecules/chat-input/types.d.ts +20 -0
- package/lib/components/molecules/content-reaction/content-reaction.component.d.ts +2 -2
- package/lib/components/molecules/cta-card/cta-card.component.d.ts +1 -1
- package/lib/components/molecules/features-list/features-list.component.d.ts +4 -4
- package/lib/components/molecules/load-more/load-more.component.d.ts +1 -1
- package/lib/components/molecules/media-object/media-object.component.d.ts +1 -1
- package/lib/components/molecules/message-bubble/message-bubble.component.d.ts +40 -0
- package/lib/components/molecules/message-bubble/types.d.ts +64 -0
- package/lib/components/molecules/metric-card/metric-card.component.d.ts +1 -1
- package/lib/components/molecules/typing-indicator/typing-indicator.component.d.ts +19 -0
- package/lib/components/organisms/account-view/account-view.component.d.ts +1 -1
- package/lib/components/organisms/article/article.component.d.ts +6 -6
- package/lib/components/organisms/auth-cta/auth-cta.component.d.ts +1 -1
- package/lib/components/organisms/bottom-nav/bottom-nav.component.d.ts +1 -1
- package/lib/components/organisms/chat-window/chat-window.component.d.ts +63 -0
- package/lib/components/organisms/chat-window/types.d.ts +36 -0
- package/lib/components/organisms/landing-steps/landing-steps.component.d.ts +1 -1
- package/lib/components/organisms/login/login.component.d.ts +1 -1
- package/lib/components/organisms/member-import-modal/member-import-modal.component.d.ts +1 -1
- package/lib/components/organisms/notification-preferences-view/notification-preferences-view.component.d.ts +1 -1
- package/lib/components/organisms/organization-view/organization-view.component.d.ts +1 -1
- package/lib/components/organisms/thread-panel/thread-panel.component.d.ts +55 -0
- package/lib/components/templates/page-wrapper/page-wrapper.component.d.ts +2 -2
- package/lib/services/chat/config.d.ts +37 -0
- package/lib/services/chat/conversation.service.d.ts +147 -0
- package/lib/services/chat/types.d.ts +145 -0
- package/lib/services/entity-feed/entity-feed.service.d.ts +71 -0
- package/lib/services/entity-feed/index.d.ts +2 -0
- package/lib/services/entity-feed/types.d.ts +26 -0
- package/package.json +1 -1
- package/public-api.d.ts +13 -0
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { Component, Input, inject, signal, computed } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import { IonSpinner } from '@ionic/angular/standalone';
|
|
4
|
+
import { firstValueFrom } from 'rxjs';
|
|
5
|
+
import { I18nService } from '../../../services/i18n';
|
|
6
|
+
import { ConversationService } from '../../../services/chat/conversation.service';
|
|
7
|
+
import { VALTECH_CHAT_CONFIG } from '../../../services/chat/config';
|
|
8
|
+
import { AuthService } from '../../../services/auth/auth.service';
|
|
9
|
+
import { ChatWindowComponent } from '../chat-window/chat-window.component';
|
|
10
|
+
import * as i0 from "@angular/core";
|
|
11
|
+
const THREAD_PANEL_I18N = {
|
|
12
|
+
es: {
|
|
13
|
+
loading: 'Cargando conversacion...',
|
|
14
|
+
thread: 'Hilo',
|
|
15
|
+
},
|
|
16
|
+
en: {
|
|
17
|
+
loading: 'Loading conversation...',
|
|
18
|
+
thread: 'Thread',
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* val-thread-panel
|
|
23
|
+
*
|
|
24
|
+
* Panel de hilo de conversacion asociado a una entidad (post, request, etc.).
|
|
25
|
+
* Internamente usa ConversationService.getOrCreateForEntity() para inicializar
|
|
26
|
+
* la conversacion y luego watchMessages() para escuchar en tiempo real.
|
|
27
|
+
* Renderiza val-chat-window con los mensajes ya mapeados.
|
|
28
|
+
*
|
|
29
|
+
* Requiere provideValtechChat() y provideValtechFirebase() en main.ts.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* <val-thread-panel
|
|
33
|
+
* entityType="post"
|
|
34
|
+
* entityId="post-abc123"
|
|
35
|
+
* currentUserId="user-xyz"
|
|
36
|
+
* title="Comentarios"
|
|
37
|
+
* />
|
|
38
|
+
*/
|
|
39
|
+
export class ThreadPanelComponent {
|
|
40
|
+
constructor() {
|
|
41
|
+
this.i18n = inject(I18nService);
|
|
42
|
+
this.conversationSvc = inject(ConversationService, { optional: true });
|
|
43
|
+
this.chatConfig = inject(VALTECH_CHAT_CONFIG, { optional: true });
|
|
44
|
+
this.auth = inject(AuthService, { optional: true });
|
|
45
|
+
this.entityType = '';
|
|
46
|
+
this.entityId = '';
|
|
47
|
+
this.currentUserId = '';
|
|
48
|
+
this.loading = signal(true);
|
|
49
|
+
this.conv = signal(null);
|
|
50
|
+
this.messages = signal([]);
|
|
51
|
+
this.typingUsers = signal([]);
|
|
52
|
+
this.isConvOpen = computed(() => this.conv()?.status === 'open');
|
|
53
|
+
this.loadingText = computed(() => {
|
|
54
|
+
this.i18n.lang();
|
|
55
|
+
return this.i18n.t('loading', 'ThreadPanel');
|
|
56
|
+
});
|
|
57
|
+
this.bubbleMessages = computed(() => {
|
|
58
|
+
const uid = this.currentUserId || this.auth?.user()?.userId || '';
|
|
59
|
+
return this.messages().map(msg => ({
|
|
60
|
+
msgId: msg.id,
|
|
61
|
+
senderId: msg.senderId,
|
|
62
|
+
senderName: msg.senderName,
|
|
63
|
+
senderAvatar: msg.senderAvatar,
|
|
64
|
+
body: msg.body,
|
|
65
|
+
type: msg.type,
|
|
66
|
+
createdAt: msg.createdAt,
|
|
67
|
+
isMine: msg.senderId === uid,
|
|
68
|
+
isDeleted: msg.isDeleted,
|
|
69
|
+
isEdited: msg.isEdited,
|
|
70
|
+
replyTo: msg.replyTo,
|
|
71
|
+
attachments: msg.attachments,
|
|
72
|
+
reactions: msg.reactions,
|
|
73
|
+
status: msg.status,
|
|
74
|
+
}));
|
|
75
|
+
});
|
|
76
|
+
this.i18n.registerDefaults('ThreadPanel', THREAD_PANEL_I18N);
|
|
77
|
+
}
|
|
78
|
+
async ngOnInit() {
|
|
79
|
+
if (!this.conversationSvc || !this.entityType || !this.entityId) {
|
|
80
|
+
this.loading.set(false);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
try {
|
|
84
|
+
const conversation = await firstValueFrom(this.conversationSvc.getOrCreateForEntity(this.entityType, this.entityId));
|
|
85
|
+
this.conv.set(conversation);
|
|
86
|
+
const orgId = this.getOrgId();
|
|
87
|
+
const appId = this.chatConfig?.appId ?? '';
|
|
88
|
+
if (orgId && appId) {
|
|
89
|
+
this.msgSub = this.conversationSvc
|
|
90
|
+
.watchMessages(conversation.id, orgId, appId)
|
|
91
|
+
.subscribe(msgs => this.messages.set(msgs));
|
|
92
|
+
this.typingSub = this.conversationSvc
|
|
93
|
+
.watchTyping(conversation.id, orgId, appId)
|
|
94
|
+
.subscribe(users => this.typingUsers.set(users));
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
catch (err) {
|
|
98
|
+
console.error('[ThreadPanel] Error al inicializar conversacion:', err);
|
|
99
|
+
}
|
|
100
|
+
finally {
|
|
101
|
+
this.loading.set(false);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
ngOnDestroy() {
|
|
105
|
+
this.msgSub?.unsubscribe();
|
|
106
|
+
this.typingSub?.unsubscribe();
|
|
107
|
+
const conv = this.conv();
|
|
108
|
+
const orgId = this.getOrgId();
|
|
109
|
+
const appId = this.chatConfig?.appId ?? '';
|
|
110
|
+
if (conv && orgId && appId && this.conversationSvc) {
|
|
111
|
+
this.conversationSvc.stopTyping(conv.id, orgId, appId);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
onSend(body) {
|
|
115
|
+
const conv = this.conv();
|
|
116
|
+
if (!conv || !this.conversationSvc)
|
|
117
|
+
return;
|
|
118
|
+
this.conversationSvc.sendMessage(conv.id, body).subscribe();
|
|
119
|
+
}
|
|
120
|
+
onReactionClick(event) {
|
|
121
|
+
// Reacciones se implementan a nivel de app consumer
|
|
122
|
+
console.debug('[ThreadPanel] reactionClick', event);
|
|
123
|
+
}
|
|
124
|
+
onDeleteMessage(msgId) {
|
|
125
|
+
const conv = this.conv();
|
|
126
|
+
if (!conv || !this.conversationSvc)
|
|
127
|
+
return;
|
|
128
|
+
this.conversationSvc.deleteMessage(conv.id, msgId).subscribe();
|
|
129
|
+
}
|
|
130
|
+
onReplyTo(_msgId) {
|
|
131
|
+
// Implementacion futura: seleccionar mensaje de respuesta
|
|
132
|
+
}
|
|
133
|
+
getOrgId() {
|
|
134
|
+
return this.auth?.user()?.activeOrg ?? '';
|
|
135
|
+
}
|
|
136
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ThreadPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
137
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ThreadPanelComponent, isStandalone: true, selector: "val-thread-panel", inputs: { entityType: "entityType", entityId: "entityId", currentUserId: "currentUserId", title: "title" }, ngImport: i0, template: `
|
|
138
|
+
<div class="thread-panel">
|
|
139
|
+
@if (title) {
|
|
140
|
+
<div class="thread-header">
|
|
141
|
+
<p class="thread-title">{{ title }}</p>
|
|
142
|
+
</div>
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
@if (loading()) {
|
|
146
|
+
<div class="thread-loading">
|
|
147
|
+
<ion-spinner name="dots"></ion-spinner>
|
|
148
|
+
<span>{{ loadingText() }}</span>
|
|
149
|
+
</div>
|
|
150
|
+
} @else {
|
|
151
|
+
<div class="thread-chat">
|
|
152
|
+
<val-chat-window
|
|
153
|
+
[convId]="conv()?.id ?? ''"
|
|
154
|
+
[messages]="bubbleMessages()"
|
|
155
|
+
[currentUserId]="currentUserId"
|
|
156
|
+
[isOpen]="isConvOpen()"
|
|
157
|
+
[typingUsers]="typingUsers()"
|
|
158
|
+
[isLoading]="false"
|
|
159
|
+
(sendMessage)="onSend($event)"
|
|
160
|
+
(reactionClick)="onReactionClick($event)"
|
|
161
|
+
(deleteMessage)="onDeleteMessage($event)"
|
|
162
|
+
(replyTo)="onReplyTo($event)"
|
|
163
|
+
/>
|
|
164
|
+
</div>
|
|
165
|
+
}
|
|
166
|
+
</div>
|
|
167
|
+
`, isInline: true, styles: [".thread-panel{display:flex;flex-direction:column;height:100%;background:var(--ion-background-color, #f4f5f8)}.thread-header{padding:12px 16px;border-bottom:1px solid var(--ion-border-color, rgba(0, 0, 0, .1));background:var(--ion-card-background, var(--ion-background-color, #fff))}.thread-header .thread-title{font-size:1rem;font-weight:600;color:var(--ion-text-color, #000);margin:0}.thread-loading{display:flex;align-items:center;justify-content:center;flex:1;gap:10px;color:var(--ion-color-medium, #92949c);font-size:.875rem}.thread-chat{flex:1;overflow:hidden;display:flex;flex-direction:column}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: IonSpinner, selector: "ion-spinner", inputs: ["color", "duration", "name", "paused"] }, { kind: "component", type: ChatWindowComponent, selector: "val-chat-window", inputs: ["convId", "messages", "participants", "currentUserId", "isOpen", "typingUsers", "isLoading"], outputs: ["sendMessage", "loadMore", "reactionClick", "deleteMessage", "replyTo"] }] }); }
|
|
168
|
+
}
|
|
169
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ThreadPanelComponent, decorators: [{
|
|
170
|
+
type: Component,
|
|
171
|
+
args: [{ selector: 'val-thread-panel', standalone: true, imports: [CommonModule, IonSpinner, ChatWindowComponent], template: `
|
|
172
|
+
<div class="thread-panel">
|
|
173
|
+
@if (title) {
|
|
174
|
+
<div class="thread-header">
|
|
175
|
+
<p class="thread-title">{{ title }}</p>
|
|
176
|
+
</div>
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
@if (loading()) {
|
|
180
|
+
<div class="thread-loading">
|
|
181
|
+
<ion-spinner name="dots"></ion-spinner>
|
|
182
|
+
<span>{{ loadingText() }}</span>
|
|
183
|
+
</div>
|
|
184
|
+
} @else {
|
|
185
|
+
<div class="thread-chat">
|
|
186
|
+
<val-chat-window
|
|
187
|
+
[convId]="conv()?.id ?? ''"
|
|
188
|
+
[messages]="bubbleMessages()"
|
|
189
|
+
[currentUserId]="currentUserId"
|
|
190
|
+
[isOpen]="isConvOpen()"
|
|
191
|
+
[typingUsers]="typingUsers()"
|
|
192
|
+
[isLoading]="false"
|
|
193
|
+
(sendMessage)="onSend($event)"
|
|
194
|
+
(reactionClick)="onReactionClick($event)"
|
|
195
|
+
(deleteMessage)="onDeleteMessage($event)"
|
|
196
|
+
(replyTo)="onReplyTo($event)"
|
|
197
|
+
/>
|
|
198
|
+
</div>
|
|
199
|
+
}
|
|
200
|
+
</div>
|
|
201
|
+
`, styles: [".thread-panel{display:flex;flex-direction:column;height:100%;background:var(--ion-background-color, #f4f5f8)}.thread-header{padding:12px 16px;border-bottom:1px solid var(--ion-border-color, rgba(0, 0, 0, .1));background:var(--ion-card-background, var(--ion-background-color, #fff))}.thread-header .thread-title{font-size:1rem;font-weight:600;color:var(--ion-text-color, #000);margin:0}.thread-loading{display:flex;align-items:center;justify-content:center;flex:1;gap:10px;color:var(--ion-color-medium, #92949c);font-size:.875rem}.thread-chat{flex:1;overflow:hidden;display:flex;flex-direction:column}\n"] }]
|
|
202
|
+
}], ctorParameters: () => [], propDecorators: { entityType: [{
|
|
203
|
+
type: Input
|
|
204
|
+
}], entityId: [{
|
|
205
|
+
type: Input
|
|
206
|
+
}], currentUserId: [{
|
|
207
|
+
type: Input
|
|
208
|
+
}], title: [{
|
|
209
|
+
type: Input
|
|
210
|
+
}] } });
|
|
211
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGhyZWFkLXBhbmVsLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9saWIvY29tcG9uZW50cy9vcmdhbmlzbXMvdGhyZWFkLXBhbmVsL3RocmVhZC1wYW5lbC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQXFCLE1BQU0sRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzlGLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDdkQsT0FBTyxFQUFnQixjQUFjLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDcEQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ3JELE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLDZDQUE2QyxDQUFDO0FBQ2xGLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQ3BFLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQUdsRSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxzQ0FBc0MsQ0FBQzs7QUFFM0UsTUFBTSxpQkFBaUIsR0FBRztJQUN4QixFQUFFLEVBQUU7UUFDRixPQUFPLEVBQUUsMEJBQTBCO1FBQ25DLE1BQU0sRUFBRSxNQUFNO0tBQ2Y7SUFDRCxFQUFFLEVBQUU7UUFDRixPQUFPLEVBQUUseUJBQXlCO1FBQ2xDLE1BQU0sRUFBRSxRQUFRO0tBQ2pCO0NBQ0YsQ0FBQztBQUVGOzs7Ozs7Ozs7Ozs7Ozs7OztHQWlCRztBQXNDSCxNQUFNLE9BQU8sb0JBQW9CO0lBbUIvQjtRQWxCVSxTQUFJLEdBQUcsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQzdCLG9CQUFlLEdBQUcsTUFB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LElBQUksRUFBRSxDQUFDO0lBQzVDLENBQUM7K0dBcEhVLG9CQUFvQjttR0FBcEIsb0JBQW9CLHdMQWpDckI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQThCVCxtcUJBL0JTLFlBQVksK0JBQUUsVUFBVSx5R0FBRSxtQkFBbUI7OzRGQWtDNUMsb0JBQW9CO2tCQXJDaEMsU0FBUzsrQkFDRSxrQkFBa0IsY0FDaEIsSUFBSSxXQUNQLENBQUMsWUFBWSxFQUFFLFVBQVUsRUFBRSxtQkFBbUIsQ0FBQyxZQUM5Qzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBOEJUO3dEQVNRLFVBQVU7c0JBQWxCLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxhQUFhO3NCQUFyQixLQUFLO2dCQUNHLEtBQUs7c0JBQWIsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgSW5wdXQsIE9uSW5pdCwgT25EZXN0cm95LCBpbmplY3QsIHNpZ25hbCwgY29tcHV0ZWQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBJb25TcGlubmVyIH0gZnJvbSAnQGlvbmljL2FuZ3VsYXIvc3RhbmRhbG9uZSc7XG5pbXBvcnQgeyBTdWJzY3JpcHRpb24sIGZpcnN0VmFsdWVGcm9tIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBJMThuU2VydmljZSB9IGZyb20gJy4uLy4uLy4uL3NlcnZpY2VzL2kxOG4nO1xuaW1wb3J0IHsgQ29udmVyc2F0aW9uU2VydmljZSB9IGZyb20gJy4uLy4uLy4uL3NlcnZpY2VzL2NoYXQvY29udmVyc2F0aW9uLnNlcnZpY2UnO1xuaW1wb3J0IHsgVkFMVEVDSF9DSEFUX0NPTkZJRyB9IGZyb20gJy4uLy4uLy4uL3NlcnZpY2VzL2NoYXQvY29uZmlnJztcbmltcG9ydCB7IEF1dGhTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vLi4vc2VydmljZXMvYXV0aC9hdXRoLnNlcnZpY2UnO1xuaW1wb3J0IHsgQ29udmVyc2F0aW9uLCBNZXNzYWdlIH0gZnJvbSAnLi4vLi4vLi4vc2VydmljZXMvY2hhdC90eXBlcyc7XG5pbXBvcnQgeyBNZXNzYWdlQnViYmxlTWV0YWRhdGEgfSBmcm9tICcuLi8uLi9tb2xlY3VsZXMvbWVzc2FnZS1idWJibGUvdHlwZXMnO1xuaW1wb3J0IHsgQ2hhdFdpbmRvd0NvbXBvbmVudCB9IGZyb20gJy4uL2NoYXQtd2luZG93L2NoYXQtd2luZG93LmNvbXBvbmVudCc7XG5cbmNvbnN0IFRIUkVBRF9QQU5FTF9JMThOID0ge1xuICBlczoge1xuICAgIGxvYWRpbmc6ICdDYXJnYW5kbyBjb252ZXJzYWNpb24uLi4nLFxuICAgIHRocmVhZDogJ0hpbG8nLFxuICB9LFxuICBlbjoge1xuICAgIGxvYWRpbmc6ICdMb2FkaW5nIGNvbnZlcnNhdGlvbi4uLicsXG4gICAgdGhyZWFkOiAnVGhyZWFkJyxcbiAgfSxcbn07XG5cbi8qKlxuICogdmFsLXRocmVhZC1wYW5lbFxuICpcbiAqIFBhbmVsIGRlIGhpbG8gZGUgY29udmVyc2FjaW9uIGFzb2NpYWRvIGEgdW5hIGVudGlkYWQgKHBvc3QsIHJlcXVlc3QsIGV0Yy4pLlxuICogSW50ZXJuYW1lbnRlIHVzYSBDb252ZXJzYXRpb25TZXJ2aWNlLmdldE9yQ3JlYXRlRm9yRW50aXR5KCkgcGFyYSBpbmljaWFsaXphclxuICogbGEgY29udmVyc2FjaW9uIHkgbHVlZ28gd2F0Y2hNZXNzYWdlcygpIHBhcmEgZXNjdWNoYXIgZW4gdGllbXBvIHJlYWwuXG4gKiBSZW5kZXJpemEgdmFsLWNoYXQtd2luZG93IGNvbiBsb3MgbWVuc2FqZXMgeWEgbWFwZWFkb3MuXG4gKlxuICogUmVxdWllcmUgcHJvdmlkZVZhbHRlY2hDaGF0KCkgeSBwcm92aWRlVmFsdGVjaEZpcmViYXNlKCkgZW4gbWFpbi50cy5cbiAqXG4gKiBAZXhhbXBsZVxuICogPHZhbC10aHJlYWQtcGFuZWxcbiAqICAgZW50aXR5VHlwZT1cInBvc3RcIlxuICogICBlbnRpdHlJZD1cInBvc3QtYWJjMTIzXCJcbiAqICAgY3VycmVudFVzZXJJZD1cInVzZXIteHl6XCJcbiAqICAgdGl0bGU9XCJDb21lbnRhcmlvc1wiXG4gKiAvPlxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICd2YWwtdGhyZWFkLXBhbmVsJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW0NvbW1vbk1vZHVsZSwgSW9uU3Bpbm5lciwgQ2hhdFdpbmRvd0NvbXBvbmVudF0sXG4gIHRlbXBsYXRlOiBgXG4gICAgPGRpdiBjbGFzcz1cInRocmVhZC1wYW5lbFwiPlxuICAgICAgQGlmICh0aXRsZSkge1xuICAgICAgICA8ZGl2IGNsYXNzPVwidGhyZWFkLWhlYWRlclwiPlxuICAgICAgICAgIDxwIGNsYXNzPVwidGhyZWFkLXRpdGxlXCI+e3sgdGl0bGUgfX08L3A+XG4gICAgICAgIDwvZGl2PlxuICAgICAgfVxuXG4gICAgICBAaWYgKGxvYWRpbmcoKSkge1xuICAgICAgICA8ZGl2IGNsYXNzPVwidGhyZWFkLWxvYWRpbmdcIj5cbiAgICAgICAgICA8aW9uLXNwaW5uZXIgbmFtZT1cImRvdHNcIj48L2lvbi1zcGlubmVyPlxuICAgICAgICAgIDxzcGFuPnt7IGxvYWRpbmdUZXh0KCkgfX08L3NwYW4+XG4gICAgICAgIDwvZGl2PlxuICAgICAgfSBAZWxzZSB7XG4gICAgICAgIDxkaXYgY2xhc3M9XCJ0aHJlYWQtY2hhdFwiPlxuICAgICAgICAgIDx2YWwtY2hhdC13aW5kb3dcbiAgICAgICAgICAgIFtjb252SWRdPVwiY29udigpPy5pZCA/PyAnJ1wiXG4gICAgICAgICAgICBbbWVzc2FnZXNdPVwiYnViYmxlTWVzc2FnZXMoKVwiXG4gICAgICAgICAgICBbY3VycmVudFVzZXJJZF09XCJjdXJyZW50VXNlcklkXCJcbiAgICAgICAgICAgIFtpc09wZW5dPVwiaXNDb252T3BlbigpXCJcbiAgICAgICAgICAgIFt0eXBpbmdVc2Vyc109XCJ0eXBpbmdVc2VycygpXCJcbiAgICAgICAgICAgIFtpc0xvYWRpbmddPVwiZmFsc2VcIlxuICAgICAgICAgICAgKHNlbmRNZXNzYWdlKT1cIm9uU2VuZCgkZXZlbnQpXCJcbiAgICAgICAgICAgIChyZWFjdGlvbkNsaWNrKT1cIm9uUmVhY3Rpb25DbGljaygkZXZlbnQpXCJcbiAgICAgICAgICAgIChkZWxldGVNZXNzYWdlKT1cIm9uRGVsZXRlTWVzc2FnZSgkZXZlbnQpXCJcbiAgICAgICAgICAgIChyZXBseVRvKT1cIm9uUmVwbHlUbygkZXZlbnQpXCJcbiAgICAgICAgICAvPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIH1cbiAgICA8L2Rpdj5cbiAgYCxcbiAgc3R5bGVVcmxzOiBbJy4vdGhyZWFkLXBhbmVsLmNvbXBvbmVudC5zY3NzJ10sXG59KVxuZXhwb3J0IGNsYXNzIFRocmVhZFBhbmVsQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xuICBwcm90ZWN0ZWQgaTE4biA9IGluamVjdChJMThuU2VydmljZSk7XG4gIHByaXZhdGUgY29udmVyc2F0aW9uU3ZjID0gaW5qZWN0KENvbnZlcnNhdGlvblNlcnZpY2UsIHsgb3B0aW9uYWw6IHRydWUgfSk7XG4gIHByaXZhdGUgY2hhdENvbmZpZyA9IGluamVjdChWQUxURUNIX0NIQVRfQ09ORklHLCB7IG9wdGlvbmFsOiB0cnVlIH0pO1xuICBwcml2YXRlIGF1dGggPSBpbmplY3QoQXV0aFNlcnZpY2UsIHsgb3B0aW9uYWw6IHRydWUgfSk7XG5cbiAgQElucHV0KCkgZW50aXR5VHlwZTogc3RyaW5nID0gJyc7XG4gIEBJbnB1dCgpIGVudGl0eUlkOiBzdHJpbmcgPSAnJztcbiAgQElucHV0KCkgY3VycmVudFVzZXJJZDogc3RyaW5nID0gJyc7XG4gIEBJbnB1dCgpIHRpdGxlPzogc3RyaW5nO1xuXG4gIHByb3RlY3RlZCBsb2FkaW5nID0gc2lnbmFsKHRydWUpO1xuICBwcm90ZWN0ZWQgY29udiA9IHNpZ25hbDxDb252ZXJzYXRpb24gfCBudWxsPihudWxsKTtcbiAgcHJvdGVjdGVkIG1lc3NhZ2VzID0gc2lnbmFsPE1lc3NhZ2VbXT4oW10pO1xuICBwcm90ZWN0ZWQgdHlwaW5nVXNlcnMgPSBzaWduYWw8c3RyaW5nW10+KFtdKTtcblxuICBwcml2YXRlIG1zZ1N1Yj86IFN1YnNjcmlwdGlvbjtcbiAgcHJpdmF0ZSB0eXBpbmdTdWI/OiBTdWJzY3JpcHRpb247XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgdGhpcy5pMThuLnJlZ2lzdGVyRGVmYXVsdHMoJ1RocmVhZFBhbmVsJywgVEhSRUFEX1BBTkVMX0kxOE4pO1xuICB9XG5cbiAgYXN5bmMgbmdPbkluaXQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKCF0aGlzLmNvbnZlcnNhdGlvblN2YyB8fCAhdGhpcy5lbnRpdHlUeXBlIHx8ICF0aGlzLmVudGl0eUlkKSB7XG4gICAgICB0aGlzLmxvYWRpbmcuc2V0KGZhbHNlKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgY29udmVyc2F0aW9uID0gYXdhaXQgZmlyc3RWYWx1ZUZyb20oXG4gICAgICAgIHRoaXMuY29udmVyc2F0aW9uU3ZjLmdldE9yQ3JlYXRlRm9yRW50aXR5KHRoaXMuZW50aXR5VHlwZSwgdGhpcy5lbnRpdHlJZClcbiAgICAgICk7XG4gICAgICB0aGlzLmNvbnYuc2V0KGNvbnZlcnNhdGlvbik7XG5cbiAgICAgIGNvbnN0IG9yZ0lkID0gdGhpcy5nZXRPcmdJZCgpO1xuICAgICAgY29uc3QgYXBwSWQgPSB0aGlzLmNoYXRDb25maWc/LmFwcElkID8/ICcnO1xuXG4gICAgICBpZiAob3JnSWQgJiYgYXBwSWQpIHtcbiAgICAgICAgdGhpcy5tc2dTdWIgPSB0aGlzLmNvbnZlcnNhdGlvblN2Y1xuICAgICAgICAgIC53YXRjaE1lc3NhZ2VzKGNvbnZlcnNhdGlvbi5pZCwgb3JnSWQsIGFwcElkKVxuICAgICAgICAgIC5zdWJzY3JpYmUobXNncyA9PiB0aGlzLm1lc3NhZ2VzLnNldChtc2dzKSk7XG5cbiAgICAgICAgdGhpcy50eXBpbmdTdWIgPSB0aGlzLmNvbnZlcnNhdGlvblN2Y1xuICAgICAgICAgIC53YXRjaFR5cGluZyhjb252ZXJzYXRpb24uaWQsIG9yZ0lkLCBhcHBJZClcbiAgICAgICAgICAuc3Vic2NyaWJlKHVzZXJzID0+IHRoaXMudHlwaW5nVXNlcnMuc2V0KHVzZXJzKSk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdbVGhyZWFkUGFuZWxdIEVycm9yIGFsIGluaWNpYWxpemFyIGNvbnZlcnNhY2lvbjonLCBlcnIpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLmxvYWRpbmcuc2V0KGZhbHNlKTtcbiAgICB9XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLm1zZ1N1Yj8udW5zdWJzY3JpYmUoKTtcbiAgICB0aGlzLnR5cGluZ1N1Yj8udW5zdWJzY3JpYmUoKTtcblxuICAgIGNvbnN0IGNvbnYgPSB0aGlzLmNvbnYoKTtcbiAgICBjb25zdCBvcmdJZCA9IHRoaXMuZ2V0T3JnSWQoKTtcbiAgICBjb25zdCBhcHBJZCA9IHRoaXMuY2hhdENvbmZpZz8uYXBwSWQgPz8gJyc7XG4gICAgaWYgKGNvbnYgJiYgb3JnSWQgJiYgYXBwSWQgJiYgdGhpcy5jb252ZXJzYXRpb25TdmMpIHtcbiAgICAgIHRoaXMuY29udmVyc2F0aW9uU3ZjLnN0b3BUeXBpbmcoY29udi5pZCwgb3JnSWQsIGFwcElkKTtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgaXNDb252T3BlbiA9IGNvbXB1dGVkKCgpID0+IHRoaXMuY29udigpPy5zdGF0dXMgPT09ICdvcGVuJyk7XG5cbiAgcHJvdGVjdGVkIGxvYWRpbmdUZXh0ID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIHRoaXMuaTE4bi5sYW5nKCk7XG4gICAgcmV0dXJuIHRoaXMuaTE4bi50KCdsb2FkaW5nJywgJ1RocmVhZFBhbmVsJyk7XG4gIH0pO1xuXG4gIHByb3RlY3RlZCBidWJibGVNZXNzYWdlcyA9IGNvbXB1dGVkKCgpOiBNZXNzYWdlQnViYmxlTWV0YWRhdGFbXSA9PiB7XG4gICAgY29uc3QgdWlkID0gdGhpcy5jdXJyZW50VXNlcklkIHx8IHRoaXMuYXV0aD8udXNlcigpPy51c2VySWQgfHwgJyc7XG4gICAgcmV0dXJuIHRoaXMubWVzc2FnZXMoKS5tYXAobXNnID0+ICh7XG4gICAgICBtc2dJZDogbXNnLmlkLFxuICAgICAgc2VuZGVySWQ6IG1zZy5zZW5kZXJJZCxcbiAgICAgIHNlbmRlck5hbWU6IG1zZy5zZW5kZXJOYW1lLFxuICAgICAgc2VuZGVyQXZhdGFyOiBtc2cuc2VuZGVyQXZhdGFyLFxuICAgICAgYm9keTogbXNnLmJvZHksXG4gICAgICB0eXBlOiBtc2cudHlwZSxcbiAgICAgIGNyZWF0ZWRBdDogbXNnLmNyZWF0ZWRBdCxcbiAgICAgIGlzTWluZTogbXNnLnNlbmRlcklkID09PSB1aWQsXG4gICAgICBpc0RlbGV0ZWQ6IG1zZy5pc0RlbGV0ZWQsXG4gICAgICBpc0VkaXRlZDogbXNnLmlzRWRpdGVkLFxuICAgICAgcmVwbHlUbzogbXNnLnJlcGx5VG8sXG4gICAgICBhdHRhY2htZW50czogbXNnLmF0dGFjaG1lbnRzLFxuICAgICAgcmVhY3Rpb25zOiBtc2cucmVhY3Rpb25zLFxuICAgICAgc3RhdHVzOiBtc2cuc3RhdHVzLFxuICAgIH0pKTtcbiAgfSk7XG5cbiAgcHJvdGVjdGVkIG9uU2VuZChib2R5OiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBjb252ID0gdGhpcy5jb252KCk7XG4gICAgaWYgKCFjb252IHx8ICF0aGlzLmNvbnZlcnNhdGlvblN2YykgcmV0dXJuO1xuICAgIHRoaXMuY29udmVyc2F0aW9uU3ZjLnNlbmRNZXNzYWdlKGNvbnYuaWQsIGJvZHkpLnN1YnNjcmliZSgpO1xuICB9XG5cbiAgcHJvdGVjdGVkIG9uUmVhY3Rpb25DbGljayhldmVudDogeyBtc2dJZDogc3RyaW5nOyB0b2tlbjogc3RyaW5nIH0pOiB2b2lkIHtcbiAgICAvLyBSZWFjY2lvbmVzIHNlIGltcGxlbWVudGFuIGEgbml2ZWwgZGUgYXBwIGNvbnN1bWVyXG4gICAgY29uc29sZS5kZWJ1ZygnW1RocmVhZFBhbmVsXSByZWFjdGlvbkNsaWNrJywgZXZlbnQpO1xuICB9XG5cbiAgcHJvdGVjdGVkIG9uRGVsZXRlTWVzc2FnZShtc2dJZDogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgY29udiA9IHRoaXMuY29udigpO1xuICAgIGlmICghY29udiB8fCAhdGhpcy5jb252ZXJzYXRpb25TdmMpIHJldHVybjtcbiAgICB0aGlzLmNvbnZlcnNhdGlvblN2Yy5kZWxldGVNZXNzYWdlKGNvbnYuaWQsIG1zZ0lkKS5zdWJzY3JpYmUoKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBvblJlcGx5VG8oX21zZ0lkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICAvLyBJbXBsZW1lbnRhY2lvbiBmdXR1cmE6IHNlbGVjY2lvbmFyIG1lbnNhamUgZGUgcmVzcHVlc3RhXG4gIH1cblxuICBwcml2YXRlIGdldE9yZ0lkKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuYXV0aD8udXNlcigpPy5hY3RpdmVPcmcgPz8gJyc7XG4gIH1cbn1cbiJdfQ==
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { InjectionToken, makeEnvironmentProviders } from '@angular/core';
|
|
2
|
+
/**
|
|
3
|
+
* Token de inyeccion para la configuracion del Chat.
|
|
4
|
+
*/
|
|
5
|
+
export const VALTECH_CHAT_CONFIG = new InjectionToken('ValtechChatConfig');
|
|
6
|
+
/**
|
|
7
|
+
* Configuracion por defecto del Chat.
|
|
8
|
+
*/
|
|
9
|
+
export const DEFAULT_CHAT_CONFIG = {
|
|
10
|
+
chatPrefix: '/v2/chat',
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Provee el servicio de Chat a la aplicacion Angular.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* // main.ts
|
|
17
|
+
* import { provideValtechChat } from 'valtech-components';
|
|
18
|
+
*
|
|
19
|
+
* bootstrapApplication(AppComponent, {
|
|
20
|
+
* providers: [
|
|
21
|
+
* provideValtechChat({
|
|
22
|
+
* apiUrl: environment.apiUrl,
|
|
23
|
+
* appId: 'showcase',
|
|
24
|
+
* }),
|
|
25
|
+
* ],
|
|
26
|
+
* });
|
|
27
|
+
*/
|
|
28
|
+
export function provideValtechChat(config) {
|
|
29
|
+
const mergedConfig = {
|
|
30
|
+
...DEFAULT_CHAT_CONFIG,
|
|
31
|
+
...config,
|
|
32
|
+
};
|
|
33
|
+
return makeEnvironmentProviders([{ provide: VALTECH_CHAT_CONFIG, useValue: mergedConfig }]);
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9zZXJ2aWNlcy9jaGF0L2NvbmZpZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQXdCLGNBQWMsRUFBRSx3QkFBd0IsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQWMvRjs7R0FFRztBQUNILE1BQU0sQ0FBQyxNQUFNLG1CQUFtQixHQUFHLElBQUksY0FBYyxDQUFvQixtQkFBbUIsQ0FBQyxDQUFDO0FBRTlGOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sbUJBQW1CLEdBQStCO0lBQzdELFVBQVUsRUFBRSxVQUFVO0NBQ3ZCLENBQUM7QUFFRjs7Ozs7Ozs7Ozs7Ozs7O0dBZUc7QUFDSCxNQUFNLFVBQVUsa0JBQWtCLENBQUMsTUFBeUI7SUFDMUQsTUFBTSxZQUFZLEdBQXNCO1FBQ3RDLEdBQUcsbUJBQW1CO1FBQ3RCLEdBQUcsTUFBTTtLQUNWLENBQUM7SUFFRixPQUFPLHdCQUF3QixDQUFDLENBQUMsRUFBRSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsUUFBUSxFQUFFLFlBQVksRUFBRSxDQUFDLENBQUMsQ0FBQztBQUM5RixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRW52aXJvbm1lbnRQcm92aWRlcnMsIEluamVjdGlvblRva2VuLCBtYWtlRW52aXJvbm1lbnRQcm92aWRlcnMgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuLyoqXG4gKiBDb25maWd1cmFjaW9uIGRlbCBzZXJ2aWNpbyBkZSBDaGF0LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFZhbHRlY2hDaGF0Q29uZmlnIHtcbiAgLyoqIFVSTCBiYXNlIGRlIGxhIEFQSSBkZWwgYmFja2VuZCAoZWo6ICdodHRwczovL2FwaS5teXZhbHRlY2guY29tJykuICovXG4gIGFwaVVybDogc3RyaW5nO1xuICAvKiogSUQgZGUgbGEgYXBsaWNhY2lvbiAoZWo6ICdzaG93Y2FzZScpLiAqL1xuICBhcHBJZDogc3RyaW5nO1xuICAvKiogUHJlZmlqbyBkZWwgZW5kcG9pbnQgZGUgY2hhdCAoZGVmYXVsdDogJy92Mi9jaGF0JykuICovXG4gIGNoYXRQcmVmaXg/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogVG9rZW4gZGUgaW55ZWNjaW9uIHBhcmEgbGEgY29uZmlndXJhY2lvbiBkZWwgQ2hhdC5cbiAqL1xuZXhwb3J0IGNvbnN0IFZBTFRFQ0hfQ0hBVF9DT05GSUcgPSBuZXcgSW5qZWN0aW9uVG9rZW48VmFsdGVjaENoYXRDb25maWc+KCdWYWx0ZWNoQ2hhdENvbmZpZycpO1xuXG4vKipcbiAqIENvbmZpZ3VyYWNpb24gcG9yIGRlZmVjdG8gZGVsIENoYXQuXG4gKi9cbmV4cG9ydCBjb25zdCBERUZBVUxUX0NIQVRfQ09ORklHOiBQYXJ0aWFsPFZhbHRlY2hDaGF0Q29uZmlnPiA9IHtcbiAgY2hhdFByZWZpeDogJy92Mi9jaGF0Jyxcbn07XG5cbi8qKlxuICogUHJvdmVlIGVsIHNlcnZpY2lvIGRlIENoYXQgYSBsYSBhcGxpY2FjaW9uIEFuZ3VsYXIuXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIG1haW4udHNcbiAqIGltcG9ydCB7IHByb3ZpZGVWYWx0ZWNoQ2hhdCB9IGZyb20gJ3ZhbHRlY2gtY29tcG9uZW50cyc7XG4gKlxuICogYm9vdHN0cmFwQXBwbGljYXRpb24oQXBwQ29tcG9uZW50LCB7XG4gKiAgIHByb3ZpZGVyczogW1xuICogICAgIHByb3ZpZGVWYWx0ZWNoQ2hhdCh7XG4gKiAgICAgICBhcGlVcmw6IGVudmlyb25tZW50LmFwaVVybCxcbiAqICAgICAgIGFwcElkOiAnc2hvd2Nhc2UnLFxuICogICAgIH0pLFxuICogICBdLFxuICogfSk7XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwcm92aWRlVmFsdGVjaENoYXQoY29uZmlnOiBWYWx0ZWNoQ2hhdENvbmZpZyk6IEVudmlyb25tZW50UHJvdmlkZXJzIHtcbiAgY29uc3QgbWVyZ2VkQ29uZmlnOiBWYWx0ZWNoQ2hhdENvbmZpZyA9IHtcbiAgICAuLi5ERUZBVUxUX0NIQVRfQ09ORklHLFxuICAgIC4uLmNvbmZpZyxcbiAgfTtcblxuICByZXR1cm4gbWFrZUVudmlyb25tZW50UHJvdmlkZXJzKFt7IHByb3ZpZGU6IFZBTFRFQ0hfQ0hBVF9DT05GSUcsIHVzZVZhbHVlOiBtZXJnZWRDb25maWcgfV0pO1xufVxuIl19
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
import { Injectable, inject, isDevMode } from '@angular/core';
|
|
2
|
+
import { HttpClient } from '@angular/common/http';
|
|
3
|
+
import { map } from 'rxjs';
|
|
4
|
+
import { serverTimestamp, deleteDoc, doc, setDoc, updateDoc } from '@angular/fire/firestore';
|
|
5
|
+
import { Firestore } from '@angular/fire/firestore';
|
|
6
|
+
import { VALTECH_CHAT_CONFIG } from './config';
|
|
7
|
+
import { FirestoreService } from '../firebase/firestore.service';
|
|
8
|
+
import * as i0 from "@angular/core";
|
|
9
|
+
/**
|
|
10
|
+
* ConversationService
|
|
11
|
+
*
|
|
12
|
+
* Gestiona conversaciones y mensajes del chat.
|
|
13
|
+
*
|
|
14
|
+
* Dos capas:
|
|
15
|
+
* - HTTP (via backend /v2/chat/*): operaciones de escritura y consulta.
|
|
16
|
+
* - Firestore real-time (directa): escucha mensajes y estado de escritura.
|
|
17
|
+
*
|
|
18
|
+
* Paths Firestore:
|
|
19
|
+
* /apps/{appId}/orgs/{orgId}/conversations/{convId}/messages/{msgId}
|
|
20
|
+
* /apps/{appId}/orgs/{orgId}/conversations/{convId}/typing/{userId}
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* // Enviar y escuchar mensajes
|
|
24
|
+
* const svc = inject(ConversationService);
|
|
25
|
+
*
|
|
26
|
+
* // Enviar (HTTP)
|
|
27
|
+
* svc.sendMessage(convId, 'Hola!').subscribe();
|
|
28
|
+
*
|
|
29
|
+
* // Escuchar en tiempo real (Firestore)
|
|
30
|
+
* svc.watchMessages(convId, orgId, appId).subscribe(msgs => this.messages.set(msgs));
|
|
31
|
+
*/
|
|
32
|
+
export class ConversationService {
|
|
33
|
+
constructor() {
|
|
34
|
+
this.config = inject(VALTECH_CHAT_CONFIG, { optional: true });
|
|
35
|
+
this.http = inject(HttpClient);
|
|
36
|
+
this.firestoreService = inject(FirestoreService, { optional: true });
|
|
37
|
+
this.firestore = inject(Firestore, { optional: true });
|
|
38
|
+
if (!this.config && isDevMode()) {
|
|
39
|
+
console.warn('[valtech-components] ConversationService: provideValtechChat() no esta en main.ts. ' +
|
|
40
|
+
'El chat no funcionara.');
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
// ===========================================================================
|
|
44
|
+
// HTTP — operaciones de escritura y consulta al backend
|
|
45
|
+
// ===========================================================================
|
|
46
|
+
get baseUrl() {
|
|
47
|
+
return `${this.config?.apiUrl}${this.config?.chatPrefix ?? '/v2/chat'}`;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Crea una nueva conversacion.
|
|
51
|
+
*/
|
|
52
|
+
createConversation(req) {
|
|
53
|
+
return this.http.post(`${this.baseUrl}/conversations`, req);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Obtiene o crea una conversacion asociada a una entidad (post, request, etc.).
|
|
57
|
+
* Usa el patron upsert del backend: si ya existe una conversacion para esa entidad,
|
|
58
|
+
* la devuelve; si no, la crea.
|
|
59
|
+
*/
|
|
60
|
+
getOrCreateForEntity(entityType, entityId, type = 'entity') {
|
|
61
|
+
return this.http.post(`${this.baseUrl}/conversations/entity`, {
|
|
62
|
+
entityType,
|
|
63
|
+
entityId,
|
|
64
|
+
type,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Lista las conversaciones del usuario autenticado.
|
|
69
|
+
*/
|
|
70
|
+
listConversations(cursor) {
|
|
71
|
+
const params = {};
|
|
72
|
+
if (cursor)
|
|
73
|
+
params['cursor'] = cursor;
|
|
74
|
+
return this.http.get(`${this.baseUrl}/conversations`, { params });
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Obtiene una conversacion por ID.
|
|
78
|
+
*/
|
|
79
|
+
getConversation(convId) {
|
|
80
|
+
return this.http.get(`${this.baseUrl}/conversations/${convId}`);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Actualiza el titulo o estado de una conversacion.
|
|
84
|
+
*/
|
|
85
|
+
updateConversation(convId, req) {
|
|
86
|
+
return this.http.patch(`${this.baseUrl}/conversations/${convId}`, req);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Abre una conversacion cerrada.
|
|
90
|
+
*/
|
|
91
|
+
openConversation(convId) {
|
|
92
|
+
return this.http.post(`${this.baseUrl}/conversations/${convId}/open`, {});
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Cierra una conversacion.
|
|
96
|
+
*/
|
|
97
|
+
closeConversation(convId) {
|
|
98
|
+
return this.http.post(`${this.baseUrl}/conversations/${convId}/close`, {});
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Agrega un participante a la conversacion.
|
|
102
|
+
*/
|
|
103
|
+
addParticipant(convId, userId) {
|
|
104
|
+
return this.http.post(`${this.baseUrl}/conversations/${convId}/participants`, { userId });
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Elimina un participante de la conversacion.
|
|
108
|
+
*/
|
|
109
|
+
removeParticipant(convId, userId) {
|
|
110
|
+
return this.http.delete(`${this.baseUrl}/conversations/${convId}/participants/${userId}`);
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Envia un mensaje a una conversacion.
|
|
114
|
+
*/
|
|
115
|
+
sendMessage(convId, body) {
|
|
116
|
+
return this.http.post(`${this.baseUrl}/conversations/${convId}/messages`, { body });
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Elimina (marca como eliminado) un mensaje.
|
|
120
|
+
*/
|
|
121
|
+
deleteMessage(convId, msgId) {
|
|
122
|
+
return this.http.delete(`${this.baseUrl}/conversations/${convId}/messages/${msgId}`);
|
|
123
|
+
}
|
|
124
|
+
// ===========================================================================
|
|
125
|
+
// Firestore — escucha en tiempo real (sin pasar por el backend)
|
|
126
|
+
// ===========================================================================
|
|
127
|
+
/**
|
|
128
|
+
* Construye el path base para los datos de una conversacion.
|
|
129
|
+
* Nota: usamos el path completo con skipPrefix porque el path ya incluye
|
|
130
|
+
* apps/{appId}/orgs/{orgId} que el FirestoreService prefijaria de nuevo.
|
|
131
|
+
* En cambio armamos el path como sub-coleccion directamente.
|
|
132
|
+
*/
|
|
133
|
+
convMessagesPath(convId, orgId, appId) {
|
|
134
|
+
return `apps/${appId}/orgs/${orgId}/conversations/${convId}/messages`;
|
|
135
|
+
}
|
|
136
|
+
convTypingPath(convId, orgId, appId) {
|
|
137
|
+
return `apps/${appId}/orgs/${orgId}/conversations/${convId}/typing`;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Escucha los mensajes de una conversacion en tiempo real.
|
|
141
|
+
*
|
|
142
|
+
* @param convId - ID de la conversacion
|
|
143
|
+
* @param orgId - ID de la organizacion
|
|
144
|
+
* @param appId - ID de la aplicacion
|
|
145
|
+
* @param limit - Cantidad maxima de mensajes a cargar (default 50)
|
|
146
|
+
*/
|
|
147
|
+
watchMessages(convId, orgId, appId, limit = 50) {
|
|
148
|
+
if (!this.firestoreService) {
|
|
149
|
+
throw new Error('[ConversationService] FirestoreService no disponible. Asegurate de provideValtechFirebase().');
|
|
150
|
+
}
|
|
151
|
+
// Usamos ABS_PATH_SENTINEL para evitar que FirestoreService anteponga el prefijo
|
|
152
|
+
// porque el path ya contiene la ruta completa con appId/orgId.
|
|
153
|
+
const { ABS_PATH_SENTINEL } = this.getAbsPathSentinel();
|
|
154
|
+
const collectionPath = `${ABS_PATH_SENTINEL}${this.convMessagesPath(convId, orgId, appId)}`;
|
|
155
|
+
return this.firestoreService.collectionChanges(collectionPath, {
|
|
156
|
+
orderBy: [{ field: 'createdAt', direction: 'asc' }],
|
|
157
|
+
limit,
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Escucha los usuarios que estan escribiendo en una conversacion.
|
|
162
|
+
* Devuelve un array de displayNames.
|
|
163
|
+
*
|
|
164
|
+
* @param convId - ID de la conversacion
|
|
165
|
+
* @param orgId - ID de la organizacion
|
|
166
|
+
* @param appId - ID de la aplicacion
|
|
167
|
+
*/
|
|
168
|
+
watchTyping(convId, orgId, appId) {
|
|
169
|
+
if (!this.firestoreService) {
|
|
170
|
+
throw new Error('[ConversationService] FirestoreService no disponible. Asegurate de provideValtechFirebase().');
|
|
171
|
+
}
|
|
172
|
+
const { ABS_PATH_SENTINEL } = this.getAbsPathSentinel();
|
|
173
|
+
const collectionPath = `${ABS_PATH_SENTINEL}${this.convTypingPath(convId, orgId, appId)}`;
|
|
174
|
+
return this.firestoreService
|
|
175
|
+
.collectionChanges(collectionPath)
|
|
176
|
+
.pipe(map(docs => docs.map(d => d.displayName)));
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Registra que el usuario actual esta escribiendo.
|
|
180
|
+
* El documento se sobreescribe para actualizar el timestamp.
|
|
181
|
+
* Debe llamarse con un TTL/cleanup (ver stopTyping).
|
|
182
|
+
*
|
|
183
|
+
* @param convId - ID de la conversacion
|
|
184
|
+
* @param orgId - ID de la organizacion
|
|
185
|
+
* @param appId - ID de la aplicacion
|
|
186
|
+
* @param displayName - Nombre visible del usuario
|
|
187
|
+
*/
|
|
188
|
+
startTyping(convId, orgId, appId, displayName) {
|
|
189
|
+
if (!this.firestore)
|
|
190
|
+
return;
|
|
191
|
+
const userId = this.getCurrentUserId();
|
|
192
|
+
if (!userId)
|
|
193
|
+
return;
|
|
194
|
+
const path = `${this.convTypingPath(convId, orgId, appId)}/${userId}`;
|
|
195
|
+
const docRef = doc(this.firestore, path);
|
|
196
|
+
void setDoc(docRef, {
|
|
197
|
+
displayName,
|
|
198
|
+
updatedAt: serverTimestamp(),
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Elimina el documento de "escribiendo" del usuario actual.
|
|
203
|
+
*
|
|
204
|
+
* @param convId - ID de la conversacion
|
|
205
|
+
* @param orgId - ID de la organizacion
|
|
206
|
+
* @param appId - ID de la aplicacion
|
|
207
|
+
*/
|
|
208
|
+
stopTyping(convId, orgId, appId) {
|
|
209
|
+
if (!this.firestore)
|
|
210
|
+
return;
|
|
211
|
+
const userId = this.getCurrentUserId();
|
|
212
|
+
if (!userId)
|
|
213
|
+
return;
|
|
214
|
+
const path = `${this.convTypingPath(convId, orgId, appId)}/${userId}`;
|
|
215
|
+
const docRef = doc(this.firestore, path);
|
|
216
|
+
void deleteDoc(docRef);
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Marca un mensaje como leido por el usuario actual.
|
|
220
|
+
* Escribe directamente en Firestore sin pasar por el backend.
|
|
221
|
+
*
|
|
222
|
+
* @param convId - ID de la conversacion
|
|
223
|
+
* @param msgId - ID del ultimo mensaje leido
|
|
224
|
+
* @param orgId - ID de la organizacion
|
|
225
|
+
* @param appId - ID de la aplicacion
|
|
226
|
+
*/
|
|
227
|
+
markRead(convId, msgId, orgId, appId) {
|
|
228
|
+
if (!this.firestore)
|
|
229
|
+
return;
|
|
230
|
+
const userId = this.getCurrentUserId();
|
|
231
|
+
if (!userId)
|
|
232
|
+
return;
|
|
233
|
+
const convPath = `apps/${appId}/orgs/${orgId}/conversations/${convId}`;
|
|
234
|
+
const convRef = doc(this.firestore, convPath);
|
|
235
|
+
// Usa dot-notation de Firestore para actualizar solo el campo del usuario
|
|
236
|
+
const updateData = {
|
|
237
|
+
[`participants_readMap.${userId}`]: msgId,
|
|
238
|
+
updatedAt: serverTimestamp(),
|
|
239
|
+
};
|
|
240
|
+
void updateDoc(convRef, updateData);
|
|
241
|
+
}
|
|
242
|
+
// ===========================================================================
|
|
243
|
+
// Helpers privados
|
|
244
|
+
// ===========================================================================
|
|
245
|
+
/**
|
|
246
|
+
* Importa ABS_PATH_SENTINEL de forma lazy para evitar dependencias circulares.
|
|
247
|
+
*/
|
|
248
|
+
getAbsPathSentinel() {
|
|
249
|
+
// La sentinel se define en firestore.service.ts — replicamos el valor aqui
|
|
250
|
+
// para no crear una dependencia circular en el import estatico.
|
|
251
|
+
return { ABS_PATH_SENTINEL: '__abs__:' };
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Obtiene el userId del usuario actual desde sessionStorage / localStorage
|
|
255
|
+
* como fallback no-DI para el contexto de escritura de Firestore.
|
|
256
|
+
* En prod, el AuthService actualiza el userId en el contexto de la app.
|
|
257
|
+
*/
|
|
258
|
+
getCurrentUserId() {
|
|
259
|
+
// Intentar obtenerlo desde sessionStorage (el AuthService lo guarda ahi)
|
|
260
|
+
if (typeof sessionStorage !== 'undefined') {
|
|
261
|
+
const uid = sessionStorage.getItem('uid') ?? sessionStorage.getItem('userId');
|
|
262
|
+
if (uid)
|
|
263
|
+
return uid;
|
|
264
|
+
}
|
|
265
|
+
return null;
|
|
266
|
+
}
|
|
267
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ConversationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
268
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ConversationService, providedIn: 'root' }); }
|
|
269
|
+
}
|
|
270
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ConversationService, decorators: [{
|
|
271
|
+
type: Injectable,
|
|
272
|
+
args: [{ providedIn: 'root' }]
|
|
273
|
+
}], ctorParameters: () => [] });
|
|
274
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udmVyc2F0aW9uLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL3NlcnZpY2VzL2NoYXQvY29udmVyc2F0aW9uLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzlELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNsRCxPQUFPLEVBQWMsR0FBRyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ3ZDLE9BQU8sRUFBRSxlQUFlLEVBQUUsU0FBUyxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDN0YsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBRXBELE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLFVBQVUsQ0FBQztBQVUvQyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQzs7QUFFakU7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FzQkc7QUFFSCxNQUFNLE9BQU8sbUJBQW1CO0lBTTlCO1FBTFEsV0FBTSxHQUFHLE1BQU0sQ0FBQyxtQkFBbUIsRUFBRSxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQ3pELFNBQUksR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDMUIscUJBQWdCLEdBQUcsTUFBTSxDQUFDLGdCQUFnQixFQUFFLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7UUFDaEUsY0FBUyxHQUFHLE1BQU0sQ0FBQyxTQUFTLEVBQUUsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUd4RCxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sSUFBSSxTQUFTLEVBQUUsRUFBRSxDQUFDO1lB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QWUsRUFBRTtTQUM3QixDQUFDO1FBRUYsS0FBSyxTQUFTLENBQUMsT0FBTyxFQUFFLFVBQVUsQ0FBQyxDQUFDO0lBQ3RDLENBQUM7SUFFRCw4RUFBOEU7SUFDOUUsbUJBQW1CO0lBQ25CLDhFQUE4RTtJQUU5RTs7T0FFRztJQUNLLGtCQUFrQjtRQUN4QiwyRUFBMkU7UUFDM0UsZ0VBQWdFO1FBQ2hFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxVQUFVLEVBQUUsQ0FBQztJQUMzQyxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNLLGdCQUFnQjtRQUN0Qix5RUFBeUU7UUFDekUsSUFBSSxPQUFPLGNBQWMsS0FBSyxXQUFXLEVBQUUsQ0FBQztZQUMxQyxNQUFNLEdBQUcsR0FBRyxjQUFjLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxJQUFJLGNBQWMsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDOUUsSUFBSSxHQUFHO2dCQUFFLE9BQU8sR0FBRyxDQUFDO1FBQ3RCLENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7K0dBeFJVLG1CQUFtQjttSEFBbkIsbUJBQW1CLGNBRE4sTUFBTTs7NEZBQ25CLG1CQUFtQjtrQkFEL0IsVUFBVTttQkFBQyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlLCBpbmplY3QsIGlzRGV2TW9kZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgSHR0cENsaWVudCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcbmltcG9ydCB7IE9ic2VydmFibGUsIG1hcCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgc2VydmVyVGltZXN0YW1wLCBkZWxldGVEb2MsIGRvYywgc2V0RG9jLCB1cGRhdGVEb2MgfSBmcm9tICdAYW5ndWxhci9maXJlL2ZpcmVzdG9yZSc7XG5pbXBvcnQgeyBGaXJlc3RvcmUgfSBmcm9tICdAYW5ndWxhci9maXJlL2ZpcmVzdG9yZSc7XG5cbmltcG9ydCB7IFZBTFRFQ0hfQ0hBVF9DT05GSUcgfSBmcm9tICcuL2NvbmZpZyc7XG5pbXBvcnQge1xuICBDb252ZXJzYXRpb24sXG4gIENvbnZlcnNhdGlvblR5cGUsXG4gIENyZWF0ZUNvbnZlcnNhdGlvblJlcXVlc3QsXG4gIExpc3RDb252ZXJzYXRpb25zUmVzcG9uc2UsXG4gIE1lc3NhZ2UsXG4gIFVwZGF0ZUNvbnZlcnNhdGlvblJlcXVlc3QsXG4gIFR5cGluZ0RvY3VtZW50LFxufSBmcm9tICcuL3R5cGVzJztcbmltcG9ydCB7IEZpcmVzdG9yZVNlcnZpY2UgfSBmcm9tICcuLi9maXJlYmFzZS9maXJlc3RvcmUuc2VydmljZSc7XG5cbi8qKlxuICogQ29udmVyc2F0aW9uU2VydmljZVxuICpcbiAqIEdlc3Rpb25hIGNvbnZlcnNhY2lvbmVzIHkgbWVuc2FqZXMgZGVsIGNoYXQuXG4gKlxuICogRG9zIGNhcGFzOlxuICogICAtIEhUVFAgKHZpYSBiYWNrZW5kIC92Mi9jaGF0LyopOiBvcGVyYWNpb25lcyBkZSBlc2NyaXR1cmEgeSBjb25zdWx0YS5cbiAqICAgLSBGaXJlc3RvcmUgcmVhbC10aW1lIChkaXJlY3RhKTogZXNjdWNoYSBtZW5zYWplcyB5IGVzdGFkbyBkZSBlc2NyaXR1cmEuXG4gKlxuICogUGF0aHMgRmlyZXN0b3JlOlxuICogICAvYXBwcy97YXBwSWR9L29yZ3Mve29yZ0lkfS9jb252ZXJzYXRpb25zL3tjb252SWR9L21lc3NhZ2VzL3ttc2dJZH1cbiAqICAgL2FwcHMve2FwcElkfS9vcmdzL3tvcmdJZH0vY29udmVyc2F0aW9ucy97Y29udklkfS90eXBpbmcve3VzZXJJZH1cbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gRW52aWFyIHkgZXNjdWNoYXIgbWVuc2FqZXNcbiAqIGNvbnN0IHN2YyA9IGluamVjdChDb252ZXJzYXRpb25TZXJ2aWNlKTtcbiAqXG4gKiAvLyBFbnZpYXIgKEhUVFApXG4gKiBzdmMuc2VuZE1lc3NhZ2UoY29udklkLCAnSG9sYSEnKS5zdWJzY3JpYmUoKTtcbiAqXG4gKiAvLyBFc2N1Y2hhciBlbiB0aWVtcG8gcmVhbCAoRmlyZXN0b3JlKVxuICogc3ZjLndhdGNoTWVzc2FnZXMoY29udklkLCBvcmdJZCwgYXBwSWQpLnN1YnNjcmliZShtc2dzID0+IHRoaXMubWVzc2FnZXMuc2V0KG1zZ3MpKTtcbiAqL1xuQEluamVjdGFibGUoeyBwcm92aWRlZEluOiAncm9vdCcgfSlcbmV4cG9ydCBjbGFzcyBDb252ZXJzYXRpb25TZXJ2aWNlIHtcbiAgcHJpdmF0ZSBjb25maWcgPSBpbmplY3QoVkFMVEVDSF9DSEFUX0NPTkZJRywgeyBvcHRpb25hbDogdHJ1ZSB9KTtcbiAgcHJpdmF0ZSBodHRwID0gaW5qZWN0KEh0dHBDbGllbnQpO1xuICBwcml2YXRlIGZpcmVzdG9yZVNlcnZpY2UgPSBpbmplY3QoRmlyZXN0b3JlU2VydmljZSwgeyBvcHRpb25hbDogdHJ1ZSB9KTtcbiAgcHJpdmF0ZSBmaXJlc3RvcmUgPSBpbmplY3QoRmlyZXN0b3JlLCB7IG9wdGlvbmFsOiB0cnVlIH0pO1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIGlmICghdGhpcy5jb25maWcgJiYgaXNEZXZNb2RlKCkpIHtcbiAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgJ1t2YWx0ZWNoLWNvbXBvbmVudHNdIENvbnZlcnNhdGlvblNlcnZpY2U6IHByb3ZpZGVWYWx0ZWNoQ2hhdCgpIG5vIGVzdGEgZW4gbWFpbi50cy4gJyArXG4gICAgICAgICAgJ0VsIGNoYXQgbm8gZnVuY2lvbmFyYS4nXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAvLyBIVFRQIOKAlCBvcGVyYWNpb25lcyBkZSBlc2NyaXR1cmEgeSBjb25zdWx0YSBhbCBiYWNrZW5kXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gIHByaXZhdGUgZ2V0IGJhc2VVcmwoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gYCR7dGhpcy5jb25maWc/LmFwaVVybH0ke3RoaXMuY29uZmlnPy5jaGF0UHJlZml4ID8/ICcvdjIvY2hhdCd9YDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhIHVuYSBudWV2YSBjb252ZXJzYWNpb24uXG4gICAqL1xuICBjcmVhdGVDb252ZXJzYXRpb24ocmVxOiBDcmVhdGVDb252ZXJzYXRpb25SZXF1ZXN0KTogT2JzZXJ2YWJsZTxDb252ZXJzYXRpb24+IHtcbiAgICByZXR1cm4gdGhpcy5odHRwLnBvc3Q8Q29udmVyc2F0aW9uPihgJHt0aGlzLmJhc2VVcmx9L2NvbnZlcnNhdGlvbnNgLCByZXEpO1xuICB9XG5cbiAgLyoqXG4gICAqIE9idGllbmUgbyBjcmVhIHVuYSBjb252ZXJzYWNpb24gYXNvY2lhZGEgYSB1bmEgZW50aWRhZCAocG9zdCwgcmVxdWVzdCwgZXRjLikuXG4gICAqIFVzYSBlbCBwYXRyb24gdXBzZXJ0IGRlbCBiYWNrZW5kOiBzaSB5YSBleGlzdGUgdW5hIGNvbnZlcnNhY2lvbiBwYXJhIGVzYSBlbnRpZGFkLFxuICAgKiBsYSBkZXZ1ZWx2ZTsgc2kgbm8sIGxhIGNyZWEuXG4gICAqL1xuICBnZXRPckNyZWF0ZUZvckVudGl0eShcbiAgICBlbnRpdHlUeXBlOiBzdHJpbmcsXG4gICAgZW50aXR5SWQ6IHN0cmluZyxcbiAgICB0eXBlOiBDb252ZXJzYXRpb25UeXBlID0gJ2VudGl0eSdcbiAgKTogT2JzZXJ2YWJsZTxDb252ZXJzYXRpb24+IHtcbiAgICByZXR1cm4gdGhpcy5odHRwLnBvc3Q8Q29udmVyc2F0aW9uPihgJHt0aGlzLmJhc2VVcmx9L2NvbnZlcnNhdGlvbnMvZW50aXR5YCwge1xuICAgICAgZW50aXR5VHlwZSxcbiAgICAgIGVudGl0eUlkLFxuICAgICAgdHlwZSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMaXN0YSBsYXMgY29udmVyc2FjaW9uZXMgZGVsIHVzdWFyaW8gYXV0ZW50aWNhZG8uXG4gICAqL1xuICBsaXN0Q29udmVyc2F0aW9ucyhjdXJzb3I/OiBzdHJpbmcpOiBPYnNlcnZhYmxlPExpc3RDb252ZXJzYXRpb25zUmVzcG9uc2U+IHtcbiAgICBjb25zdCBwYXJhbXM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcbiAgICBpZiAoY3Vyc29yKSBwYXJhbXNbJ2N1cnNvciddID0gY3Vyc29yO1xuICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0PExpc3RDb252ZXJzYXRpb25zUmVzcG9uc2U+KGAke3RoaXMuYmFzZVVybH0vY29udmVyc2F0aW9uc2AsIHsgcGFyYW1zIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIE9idGllbmUgdW5hIGNvbnZlcnNhY2lvbiBwb3IgSUQuXG4gICAqL1xuICBnZXRDb252ZXJzYXRpb24oY29udklkOiBzdHJpbmcpOiBPYnNlcnZhYmxlPENvbnZlcnNhdGlvbj4ge1xuICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0PENvbnZlcnNhdGlvbj4oYCR7dGhpcy5iYXNlVXJsfS9jb252ZXJzYXRpb25zLyR7Y29udklkfWApO1xuICB9XG5cbiAgLyoqXG4gICAqIEFjdHVhbGl6YSBlbCB0aXR1bG8gbyBlc3RhZG8gZGUgdW5hIGNvbnZlcnNhY2lvbi5cbiAgICovXG4gIHVwZGF0ZUNvbnZlcnNhdGlvbihjb252SWQ6IHN0cmluZywgcmVxOiBVcGRhdGVDb252ZXJzYXRpb25SZXF1ZXN0KTogT2JzZXJ2YWJsZTxDb252ZXJzYXRpb24+IHtcbiAgICByZXR1cm4gdGhpcy5odHRwLnBhdGNoPENvbnZlcnNhdGlvbj4oYCR7dGhpcy5iYXNlVXJsfS9jb252ZXJzYXRpb25zLyR7Y29udklkfWAsIHJlcSk7XG4gIH1cblxuICAvKipcbiAgICogQWJyZSB1bmEgY29udmVyc2FjaW9uIGNlcnJhZGEuXG4gICAqL1xuICBvcGVuQ29udmVyc2F0aW9uKGNvbnZJZDogc3RyaW5nKTogT2JzZXJ2YWJsZTx2b2lkPiB7XG4gICAgcmV0dXJuIHRoaXMuaHR0cC5wb3N0PHZvaWQ+KGAke3RoaXMuYmFzZVVybH0vY29udmVyc2F0aW9ucy8ke2NvbnZJZH0vb3BlbmAsIHt9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaWVycmEgdW5hIGNvbnZlcnNhY2lvbi5cbiAgICovXG4gIGNsb3NlQ29udmVyc2F0aW9uKGNvbnZJZDogc3RyaW5nKTogT2JzZXJ2YWJsZTx2b2lkPiB7XG4gICAgcmV0dXJuIHRoaXMuaHR0cC5wb3N0PHZvaWQ+KGAke3RoaXMuYmFzZVVybH0vY29udmVyc2F0aW9ucy8ke2NvbnZJZH0vY2xvc2VgLCB7fSk7XG4gIH1cblxuICAvKipcbiAgICogQWdyZWdhIHVuIHBhcnRpY2lwYW50ZSBhIGxhIGNvbnZlcnNhY2lvbi5cbiAgICovXG4gIGFkZFBhcnRpY2lwYW50KGNvbnZJZDogc3RyaW5nLCB1c2VySWQ6IHN0cmluZyk6IE9ic2VydmFibGU8dm9pZD4ge1xuICAgIHJldHVybiB0aGlzLmh0dHAucG9zdDx2b2lkPihgJHt0aGlzLmJhc2VVcmx9L2NvbnZlcnNhdGlvbnMvJHtjb252SWR9L3BhcnRpY2lwYW50c2AsIHsgdXNlcklkIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEVsaW1pbmEgdW4gcGFydGljaXBhbnRlIGRlIGxhIGNvbnZlcnNhY2lvbi5cbiAgICovXG4gIHJlbW92ZVBhcnRpY2lwYW50KGNvbnZJZDogc3RyaW5nLCB1c2VySWQ6IHN0cmluZyk6IE9ic2VydmFibGU8dm9pZD4ge1xuICAgIHJldHVybiB0aGlzLmh0dHAuZGVsZXRlPHZvaWQ+KGAke3RoaXMuYmFzZVVybH0vY29udmVyc2F0aW9ucy8ke2NvbnZJZH0vcGFydGljaXBhbnRzLyR7dXNlcklkfWApO1xuICB9XG5cbiAgLyoqXG4gICAqIEVudmlhIHVuIG1lbnNhamUgYSB1bmEgY29udmVyc2FjaW9uLlxuICAgKi9cbiAgc2VuZE1lc3NhZ2UoY29udklkOiBzdHJpbmcsIGJvZHk6IHN0cmluZyk6IE9ic2VydmFibGU8TWVzc2FnZT4ge1xuICAgIHJldHVybiB0aGlzLmh0dHAucG9zdDxNZXNzYWdlPihgJHt0aGlzLmJhc2VVcmx9L2NvbnZlcnNhdGlvbnMvJHtjb252SWR9L21lc3NhZ2VzYCwgeyBib2R5IH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEVsaW1pbmEgKG1hcmNhIGNvbW8gZWxpbWluYWRvKSB1biBtZW5zYWplLlxuICAgKi9cbiAgZGVsZXRlTWVzc2FnZShjb252SWQ6IHN0cmluZywgbXNnSWQ6IHN0cmluZyk6IE9ic2VydmFibGU8dm9pZD4ge1xuICAgIHJldHVybiB0aGlzLmh0dHAuZGVsZXRlPHZvaWQ+KGAke3RoaXMuYmFzZVVybH0vY29udmVyc2F0aW9ucy8ke2NvbnZJZH0vbWVzc2FnZXMvJHttc2dJZH1gKTtcbiAgfVxuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAvLyBGaXJlc3RvcmUg4oCUIGVzY3VjaGEgZW4gdGllbXBvIHJlYWwgKHNpbiBwYXNhciBwb3IgZWwgYmFja2VuZClcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgLyoqXG4gICAqIENvbnN0cnV5ZSBlbCBwYXRoIGJhc2UgcGFyYSBsb3MgZGF0b3MgZGUgdW5hIGNvbnZlcnNhY2lvbi5cbiAgICogTm90YTogdXNhbW9zIGVsIHBhdGggY29tcGxldG8gY29uIHNraXBQcmVmaXggcG9ycXVlIGVsIHBhdGggeWEgaW5jbHV5ZVxuICAgKiBhcHBzL3thcHBJZH0vb3Jncy97b3JnSWR9IHF1ZSBlbCBGaXJlc3RvcmVTZXJ2aWNlIHByZWZpamFyaWEgZGUgbnVldm8uXG4gICAqIEVuIGNhbWJpbyBhcm1hbW9zIGVsIHBhdGggY29tbyBzdWItY29sZWNjaW9uIGRpcmVjdGFtZW50ZS5cbiAgICovXG4gIHByaXZhdGUgY29udk1lc3NhZ2VzUGF0aChjb252SWQ6IHN0cmluZywgb3JnSWQ6IHN0cmluZywgYXBwSWQ6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGBhcHBzLyR7YXBwSWR9L29yZ3MvJHtvcmdJZH0vY29udmVyc2F0aW9ucy8ke2NvbnZJZH0vbWVzc2FnZXNgO1xuICB9XG5cbiAgcHJpdmF0ZSBjb252VHlwaW5nUGF0aChjb252SWQ6IHN0cmluZywgb3JnSWQ6IHN0cmluZywgYXBwSWQ6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGBhcHBzLyR7YXBwSWR9L29yZ3MvJHtvcmdJZH0vY29udmVyc2F0aW9ucy8ke2NvbnZJZH0vdHlwaW5nYDtcbiAgfVxuXG4gIC8qKlxuICAgKiBFc2N1Y2hhIGxvcyBtZW5zYWplcyBkZSB1bmEgY29udmVyc2FjaW9uIGVuIHRpZW1wbyByZWFsLlxuICAgKlxuICAgKiBAcGFyYW0gY29udklkIC0gSUQgZGUgbGEgY29udmVyc2FjaW9uXG4gICAqIEBwYXJhbSBvcmdJZCAtIElEIGRlIGxhIG9yZ2FuaXphY2lvblxuICAgKiBAcGFyYW0gYXBwSWQgLSBJRCBkZSBsYSBhcGxpY2FjaW9uXG4gICAqIEBwYXJhbSBsaW1pdCAtIENhbnRpZGFkIG1heGltYSBkZSBtZW5zYWplcyBhIGNhcmdhciAoZGVmYXVsdCA1MClcbiAgICovXG4gIHdhdGNoTWVzc2FnZXMoXG4gICAgY29udklkOiBzdHJpbmcsXG4gICAgb3JnSWQ6IHN0cmluZyxcbiAgICBhcHBJZDogc3RyaW5nLFxuICAgIGxpbWl0OiBudW1iZXIgPSA1MFxuICApOiBPYnNlcnZhYmxlPE1lc3NhZ2VbXT4ge1xuICAgIGlmICghdGhpcy5maXJlc3RvcmVTZXJ2aWNlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICdbQ29udmVyc2F0aW9uU2VydmljZV0gRmlyZXN0b3JlU2VydmljZSBubyBkaXNwb25pYmxlLiBBc2VndXJhdGUgZGUgcHJvdmlkZVZhbHRlY2hGaXJlYmFzZSgpLidcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gVXNhbW9zIEFCU19QQVRIX1NFTlRJTkVMIHBhcmEgZXZpdGFyIHF1ZSBGaXJlc3RvcmVTZXJ2aWNlIGFudGVwb25nYSBlbCBwcmVmaWpvXG4gICAgLy8gcG9ycXVlIGVsIHBhdGggeWEgY29udGllbmUgbGEgcnV0YSBjb21wbGV0YSBjb24gYXBwSWQvb3JnSWQuXG4gICAgY29uc3QgeyBBQlNfUEFUSF9TRU5USU5FTCB9ID0gdGhpcy5nZXRBYnNQYXRoU2VudGluZWwoKTtcbiAgICBjb25zdCBjb2xsZWN0aW9uUGF0aCA9IGAke0FCU19QQVRIX1NFTlRJTkVMfSR7dGhpcy5jb252TWVzc2FnZXNQYXRoKGNvbnZJZCwgb3JnSWQsIGFwcElkKX1gO1xuXG4gICAgcmV0dXJuIHRoaXMuZmlyZXN0b3JlU2VydmljZS5jb2xsZWN0aW9uQ2hhbmdlczxNZXNzYWdlPihjb2xsZWN0aW9uUGF0aCwge1xuICAgICAgb3JkZXJCeTogW3sgZmllbGQ6ICdjcmVhdGVkQXQnLCBkaXJlY3Rpb246ICdhc2MnIH1dLFxuICAgICAgbGltaXQsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogRXNjdWNoYSBsb3MgdXN1YXJpb3MgcXVlIGVzdGFuIGVzY3JpYmllbmRvIGVuIHVuYSBjb252ZXJzYWNpb24uXG4gICAqIERldnVlbHZlIHVuIGFycmF5IGRlIGRpc3BsYXlOYW1lcy5cbiAgICpcbiAgICogQHBhcmFtIGNvbnZJZCAtIElEIGRlIGxhIGNvbnZlcnNhY2lvblxuICAgKiBAcGFyYW0gb3JnSWQgLSBJRCBkZSBsYSBvcmdhbml6YWNpb25cbiAgICogQHBhcmFtIGFwcElkIC0gSUQgZGUgbGEgYXBsaWNhY2lvblxuICAgKi9cbiAgd2F0Y2hUeXBpbmcoY29udklkOiBzdHJpbmcsIG9yZ0lkOiBzdHJpbmcsIGFwcElkOiBzdHJpbmcpOiBPYnNlcnZhYmxlPHN0cmluZ1tdPiB7XG4gICAgaWYgKCF0aGlzLmZpcmVzdG9yZVNlcnZpY2UpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgJ1tDb252ZXJzYXRpb25TZXJ2aWNlXSBGaXJlc3RvcmVTZXJ2aWNlIG5vIGRpc3BvbmlibGUuIEFzZWd1cmF0ZSBkZSBwcm92aWRlVmFsdGVjaEZpcmViYXNlKCkuJ1xuICAgICAgKTtcbiAgICB9XG5cbiAgICBjb25zdCB7IEFCU19QQVRIX1NFTlRJTkVMIH0gPSB0aGlzLmdldEFic1BhdGhTZW50aW5lbCgpO1xuICAgIGNvbnN0IGNvbGxlY3Rpb25QYXRoID0gYCR7QUJTX1BBVEhfU0VOVElORUx9JHt0aGlzLmNvbnZUeXBpbmdQYXRoKGNvbnZJZCwgb3JnSWQsIGFwcElkKX1gO1xuXG4gICAgcmV0dXJuIHRoaXMuZmlyZXN0b3JlU2VydmljZVxuICAgICAgLmNvbGxlY3Rpb25DaGFuZ2VzPFR5cGluZ0RvY3VtZW50Pihjb2xsZWN0aW9uUGF0aClcbiAgICAgIC5waXBlKG1hcChkb2NzID0+IGRvY3MubWFwKGQgPT4gZC5kaXNwbGF5TmFtZSkpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWdpc3RyYSBxdWUgZWwgdXN1YXJpbyBhY3R1YWwgZXN0YSBlc2NyaWJpZW5kby5cbiAgICogRWwgZG9jdW1lbnRvIHNlIHNvYnJlZXNjcmliZSBwYXJhIGFjdHVhbGl6YXIgZWwgdGltZXN0YW1wLlxuICAgKiBEZWJlIGxsYW1hcnNlIGNvbiB1biBUVEwvY2xlYW51cCAodmVyIHN0b3BUeXBpbmcpLlxuICAgKlxuICAgKiBAcGFyYW0gY29udklkIC0gSUQgZGUgbGEgY29udmVyc2FjaW9uXG4gICAqIEBwYXJhbSBvcmdJZCAtIElEIGRlIGxhIG9yZ2FuaXphY2lvblxuICAgKiBAcGFyYW0gYXBwSWQgLSBJRCBkZSBsYSBhcGxpY2FjaW9uXG4gICAqIEBwYXJhbSBkaXNwbGF5TmFtZSAtIE5vbWJyZSB2aXNpYmxlIGRlbCB1c3VhcmlvXG4gICAqL1xuICBzdGFydFR5cGluZyhjb252SWQ6IHN0cmluZywgb3JnSWQ6IHN0cmluZywgYXBwSWQ6IHN0cmluZywgZGlzcGxheU5hbWU6IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICghdGhpcy5maXJlc3RvcmUpIHJldHVybjtcblxuICAgIGNvbnN0IHVzZXJJZCA9IHRoaXMuZ2V0Q3VycmVudFVzZXJJZCgpO1xuICAgIGlmICghdXNlcklkKSByZXR1cm47XG5cbiAgICBjb25zdCBwYXRoID0gYCR7dGhpcy5jb252VHlwaW5nUGF0aChjb252SWQsIG9yZ0lkLCBhcHBJZCl9LyR7dXNlcklkfWA7XG4gICAgY29uc3QgZG9jUmVmID0gZG9jKHRoaXMuZmlyZXN0b3JlLCBwYXRoKTtcblxuICAgIHZvaWQgc2V0RG9jKGRvY1JlZiwge1xuICAgICAgZGlzcGxheU5hbWUsXG4gICAgICB1cGRhdGVkQXQ6IHNlcnZlclRpbWVzdGFtcCgpLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEVsaW1pbmEgZWwgZG9jdW1lbnRvIGRlIFwiZXNjcmliaWVuZG9cIiBkZWwgdXN1YXJpbyBhY3R1YWwuXG4gICAqXG4gICAqIEBwYXJhbSBjb252SWQgLSBJRCBkZSBsYSBjb252ZXJzYWNpb25cbiAgICogQHBhcmFtIG9yZ0lkIC0gSUQgZGUgbGEgb3JnYW5pemFjaW9uXG4gICAqIEBwYXJhbSBhcHBJZCAtIElEIGRlIGxhIGFwbGljYWNpb25cbiAgICovXG4gIHN0b3BUeXBpbmcoY29udklkOiBzdHJpbmcsIG9yZ0lkOiBzdHJpbmcsIGFwcElkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuZmlyZXN0b3JlKSByZXR1cm47XG5cbiAgICBjb25zdCB1c2VySWQgPSB0aGlzLmdldEN1cnJlbnRVc2VySWQoKTtcbiAgICBpZiAoIXVzZXJJZCkgcmV0dXJuO1xuXG4gICAgY29uc3QgcGF0aCA9IGAke3RoaXMuY29udlR5cGluZ1BhdGgoY29udklkLCBvcmdJZCwgYXBwSWQpfS8ke3VzZXJJZH1gO1xuICAgIGNvbnN0IGRvY1JlZiA9IGRvYyh0aGlzLmZpcmVzdG9yZSwgcGF0aCk7XG5cbiAgICB2b2lkIGRlbGV0ZURvYyhkb2NSZWYpO1xuICB9XG5cbiAgLyoqXG4gICAqIE1hcmNhIHVuIG1lbnNhamUgY29tbyBsZWlkbyBwb3IgZWwgdXN1YXJpbyBhY3R1YWwuXG4gICAqIEVzY3JpYmUgZGlyZWN0YW1lbnRlIGVuIEZpcmVzdG9yZSBzaW4gcGFzYXIgcG9yIGVsIGJhY2tlbmQuXG4gICAqXG4gICAqIEBwYXJhbSBjb252SWQgLSBJRCBkZSBsYSBjb252ZXJzYWNpb25cbiAgICogQHBhcmFtIG1zZ0lkIC0gSUQgZGVsIHVsdGltbyBtZW5zYWplIGxlaWRvXG4gICAqIEBwYXJhbSBvcmdJZCAtIElEIGRlIGxhIG9yZ2FuaXphY2lvblxuICAgKiBAcGFyYW0gYXBwSWQgLSBJRCBkZSBsYSBhcGxpY2FjaW9uXG4gICAqL1xuICBtYXJrUmVhZChjb252SWQ6IHN0cmluZywgbXNnSWQ6IHN0cmluZywgb3JnSWQ6IHN0cmluZywgYXBwSWQ6IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICghdGhpcy5maXJlc3RvcmUpIHJldHVybjtcblxuICAgIGNvbnN0IHVzZXJJZCA9IHRoaXMuZ2V0Q3VycmVudFVzZXJJZCgpO1xuICAgIGlmICghdXNlcklkKSByZXR1cm47XG5cbiAgICBjb25zdCBjb252UGF0aCA9IGBhcHBzLyR7YXBwSWR9L29yZ3MvJHtvcmdJZH0vY29udmVyc2F0aW9ucy8ke2NvbnZJZH1gO1xuICAgIGNvbnN0IGNvbnZSZWYgPSBkb2ModGhpcy5maXJlc3RvcmUsIGNvbnZQYXRoKTtcblxuICAgIC8vIFVzYSBkb3Qtbm90YXRpb24gZGUgRmlyZXN0b3JlIHBhcmEgYWN0dWFsaXphciBzb2xvIGVsIGNhbXBvIGRlbCB1c3VhcmlvXG4gICAgY29uc3QgdXBkYXRlRGF0YTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7XG4gICAgICBbYHBhcnRpY2lwYW50c19yZWFkTWFwLiR7dXNlcklkfWBdOiBtc2dJZCxcbiAgICAgIHVwZGF0ZWRBdDogc2VydmVyVGltZXN0YW1wKCksXG4gICAgfTtcblxuICAgIHZvaWQgdXBkYXRlRG9jKGNvbnZSZWYsIHVwZGF0ZURhdGEpO1xuICB9XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIC8vIEhlbHBlcnMgcHJpdmFkb3NcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgLyoqXG4gICAqIEltcG9ydGEgQUJTX1BBVEhfU0VOVElORUwgZGUgZm9ybWEgbGF6eSBwYXJhIGV2aXRhciBkZXBlbmRlbmNpYXMgY2lyY3VsYXJlcy5cbiAgICovXG4gIHByaXZhdGUgZ2V0QWJzUGF0aFNlbnRpbmVsKCk6IHsgQUJTX1BBVEhfU0VOVElORUw6IHN0cmluZyB9IHtcbiAgICAvLyBMYSBzZW50aW5lbCBzZSBkZWZpbmUgZW4gZmlyZXN0b3JlLnNlcnZpY2UudHMg4oCUIHJlcGxpY2Ftb3MgZWwgdmFsb3IgYXF1aVxuICAgIC8vIHBhcmEgbm8gY3JlYXIgdW5hIGRlcGVuZGVuY2lhIGNpcmN1bGFyIGVuIGVsIGltcG9ydCBlc3RhdGljby5cbiAgICByZXR1cm4geyBBQlNfUEFUSF9TRU5USU5FTDogJ19fYWJzX186JyB9O1xuICB9XG5cbiAgLyoqXG4gICAqIE9idGllbmUgZWwgdXNlcklkIGRlbCB1c3VhcmlvIGFjdHVhbCBkZXNkZSBzZXNzaW9uU3RvcmFnZSAvIGxvY2FsU3RvcmFnZVxuICAgKiBjb21vIGZhbGxiYWNrIG5vLURJIHBhcmEgZWwgY29udGV4dG8gZGUgZXNjcml0dXJhIGRlIEZpcmVzdG9yZS5cbiAgICogRW4gcHJvZCwgZWwgQXV0aFNlcnZpY2UgYWN0dWFsaXphIGVsIHVzZXJJZCBlbiBlbCBjb250ZXh0byBkZSBsYSBhcHAuXG4gICAqL1xuICBwcml2YXRlIGdldEN1cnJlbnRVc2VySWQoKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgLy8gSW50ZW50YXIgb2J0ZW5lcmxvIGRlc2RlIHNlc3Npb25TdG9yYWdlIChlbCBBdXRoU2VydmljZSBsbyBndWFyZGEgYWhpKVxuICAgIGlmICh0eXBlb2Ygc2Vzc2lvblN0b3JhZ2UgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBjb25zdCB1aWQgPSBzZXNzaW9uU3RvcmFnZS5nZXRJdGVtKCd1aWQnKSA/PyBzZXNzaW9uU3RvcmFnZS5nZXRJdGVtKCd1c2VySWQnKTtcbiAgICAgIGlmICh1aWQpIHJldHVybiB1aWQ7XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG59XG4iXX0=
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chat Service Types
|
|
3
|
+
*
|
|
4
|
+
* Tipos compartidos para el sistema de chat en tiempo real.
|
|
5
|
+
* Firestore paths:
|
|
6
|
+
* /apps/{appId}/orgs/{orgId}/conversations/{convId}/messages/{msgId}
|
|
7
|
+
* /apps/{appId}/orgs/{orgId}/conversations/{convId}/typing/{userId}
|
|
8
|
+
*/
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL3NlcnZpY2VzL2NoYXQvdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7R0FPRyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQ2hhdCBTZXJ2aWNlIFR5cGVzXG4gKlxuICogVGlwb3MgY29tcGFydGlkb3MgcGFyYSBlbCBzaXN0ZW1hIGRlIGNoYXQgZW4gdGllbXBvIHJlYWwuXG4gKiBGaXJlc3RvcmUgcGF0aHM6XG4gKiAgIC9hcHBzL3thcHBJZH0vb3Jncy97b3JnSWR9L2NvbnZlcnNhdGlvbnMve2NvbnZJZH0vbWVzc2FnZXMve21zZ0lkfVxuICogICAvYXBwcy97YXBwSWR9L29yZ3Mve29yZ0lkfS9jb252ZXJzYXRpb25zL3tjb252SWR9L3R5cGluZy97dXNlcklkfVxuICovXG5cbmltcG9ydCB7IEZpcmVzdG9yZURvY3VtZW50IH0gZnJvbSAnLi4vZmlyZWJhc2UvdHlwZXMnO1xuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIENvbnZlcnNhdGlvblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbi8qKiBUaXBvIGRlIGNvbnZlcnNhY2lvbi4gKi9cbmV4cG9ydCB0eXBlIENvbnZlcnNhdGlvblR5cGUgPSAnZGlyZWN0JyB8ICdncm91cCcgfCAnZW50aXR5JztcblxuLyoqIEVzdGFkbyBkZSB1bmEgY29udmVyc2FjaW9uLiAqL1xuZXhwb3J0IHR5cGUgQ29udmVyc2F0aW9uU3RhdHVzID0gJ29wZW4nIHwgJ2Nsb3NlZCc7XG5cbi8qKiBQYXJ0aWNpcGFudGUgZGUgdW5hIGNvbnZlcnNhY2lvbi4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ29udmVyc2F0aW9uUGFydGljaXBhbnQge1xuICAvKiogSUQgZGVsIHVzdWFyaW8uICovXG4gIHVzZXJJZDogc3RyaW5nO1xuICAvKiogTm9tYnJlIHZpc2libGUgZGVsIHVzdWFyaW8uICovXG4gIGRpc3BsYXlOYW1lOiBzdHJpbmc7XG4gIC8qKiBVUkwgZGVsIGF2YXRhciBkZWwgdXN1YXJpbyAob3BjaW9uYWwpLiAqL1xuICBhdmF0YXJVcmw/OiBzdHJpbmc7XG4gIC8qKiBGZWNoYSBlbiBxdWUgc2UgdW5pbyBhIGxhIGNvbnZlcnNhY2lvbi4gKi9cbiAgam9pbmVkQXQ6IERhdGU7XG4gIC8qKiBVbHRpbW8gbWVuc2FqZSBsZWlkbyBwb3IgZXN0ZSBwYXJ0aWNpcGFudGUuICovXG4gIGxhc3RSZWFkTXNnSWQ/OiBzdHJpbmc7XG59XG5cbi8qKiBEb2N1bWVudG8gZGUgY29udmVyc2FjaW9uIGVuIEZpcmVzdG9yZS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ29udmVyc2F0aW9uIGV4dGVuZHMgRmlyZXN0b3JlRG9jdW1lbnQge1xuICAvKiogVGlwbyBkZSBjb252ZXJzYWNpb24uICovXG4gIHR5cGU6IENvbnZlcnNhdGlvblR5cGU7XG4gIC8qKiBFc3RhZG8gZGUgbGEgY29udmVyc2FjaW9uLiAqL1xuICBzdGF0dXM6IENvbnZlcnNhdGlvblN0YXR1cztcbiAgLyoqIFBhcnRpY2lwYW50ZXMuICovXG4gIHBhcnRpY2lwYW50czogQ29udmVyc2F0aW9uUGFydGljaXBhbnRbXTtcbiAgLyoqIFRpcG8gZGUgZW50aWRhZCBhc29jaWFkYSAocGFyYSB0aXBvIGVudGl0eSkuICovXG4gIGVudGl0eVR5cGU/OiBzdHJpbmc7XG4gIC8qKiBJRCBkZSBsYSBlbnRpZGFkIGFzb2NpYWRhLiAqL1xuICBlbnRpdHlJZD86IHN0cmluZztcbiAgLyoqIFRpdHVsbyBkZSBsYSBjb252ZXJzYWNpb24gKHBhcmEgZ3J1cG9zKS4gKi9cbiAgdGl0bGU/OiBzdHJpbmc7XG4gIC8qKiBJRCBkZWwgdWx0aW1vIG1lbnNhamUuICovXG4gIGxhc3RNc2dJZD86IHN0cmluZztcbiAgLyoqIFRleHRvIGRlbCB1bHRpbW8gbWVuc2FqZSAocHJldmlldykuICovXG4gIGxhc3RNc2dCb2R5Pzogc3RyaW5nO1xuICAvKiogRmVjaGEgZGVsIHVsdGltbyBtZW5zYWplLiAqL1xuICBsYXN0TXNnQXQ/OiBEYXRlO1xuICAvKiogQ29udGVvIGRlIG1lbnNhamVzIG5vIGxlaWRvcyBwb3IgdXNlcklkLiAqL1xuICB1bnJlYWRDb3VudD86IFJlY29yZDxzdHJpbmcsIG51bWJlcj47XG59XG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gTWVzc2FnZVxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbi8qKiBUaXBvIGRlIG1lbnNhamUuICovXG5leHBvcnQgdHlwZSBNZXNzYWdlVHlwZSA9ICd0ZXh0JyB8ICdpbWFnZScgfCAnZmlsZScgfCAnc3lzdGVtJztcblxuLyoqIEVzdGFkbyBkZSBlbnZpbyBkZWwgbWVuc2FqZS4gKi9cbmV4cG9ydCB0eXBlIE1lc3NhZ2VTdGF0dXMgPSAnc2VuZGluZycgfCAnc2VudCcgfCAnZmFpbGVkJztcblxuLyoqIEFyY2hpdm8gYWRqdW50byBlbiB1biBtZW5zYWplLiAqL1xuZXhwb3J0IGludGVyZmFjZSBNZXNzYWdlQXR0YWNobWVudCB7XG4gIC8qKiBOb21icmUgZGVsIGFyY2hpdm8uICovXG4gIG5hbWU6IHN0cmluZztcbiAgLyoqIFVSTCBkZSBkZXNjYXJnYS4gKi9cbiAgdXJsOiBzdHJpbmc7XG4gIC8qKiBUaXBvIE1JTUUuICovXG4gIG1pbWVUeXBlOiBzdHJpbmc7XG4gIC8qKiBUYW1hbm8gZW4gYnl0ZXMuICovXG4gIHNpemU/OiBudW1iZXI7XG59XG5cbi8qKiBSZWFjY2lvbiBhIHVuIG1lbnNhamUuICovXG5leHBvcnQgaW50ZXJmYWNlIE1lc3NhZ2VSZWFjdGlvbiB7XG4gIC8qKiBUb2tlbiBkZWwgZW1vamkgKGVqOiAnbGlrZScsICdoZWFydCcpLiAqL1xuICB0b2tlbjogc3RyaW5nO1xuICAvKiogQ2FudGlkYWQgZGUgdXN1YXJpb3MgcXVlIHJlYWNjaW9uYXJvbiBjb24gZXN0ZSBlbW9qaS4gKi9cbiAgY291bnQ6IG51bWJlcjtcbiAgLyoqIFNpIGVsIHVzdWFyaW8gYWN0dWFsIHRpZW5lIGFjdGl2YSBlc3RhIHJlYWNjaW9uLiAqL1xuICBhY3RpdmU6IGJvb2xlYW47XG59XG5cbi8qKiBSZWZlcmVuY2lhIGFsIG1lbnNhamUgYWwgcXVlIHNlIHJlc3BvbmRlLiAqL1xuZXhwb3J0IGludGVyZmFjZSBNZXNzYWdlUmVwbHlUbyB7XG4gIC8qKiBJRCBkZWwgbWVuc2FqZSBvcmlnaW5hbC4gKi9cbiAgbXNnSWQ6IHN0cmluZztcbiAgLyoqIE5vbWJyZSBkZWwgZW1pc29yIGRlbCBtZW5zYWplIG9yaWdpbmFsLiAqL1xuICBzZW5kZXJOYW1lOiBzdHJpbmc7XG4gIC8qKiBUZXh0byBkZWwgbWVuc2FqZSBvcmlnaW5hbCAocHJldmlldykuICovXG4gIGJvZHk6IHN0cmluZztcbn1cblxuLyoqIERvY3VtZW50byBkZSBtZW5zYWplIGVuIEZpcmVzdG9yZS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTWVzc2FnZSBleHRlbmRzIEZpcmVzdG9yZURvY3VtZW50IHtcbiAgLyoqIElEIGRlbCBlbWlzb3IuICovXG4gIHNlbmRlcklkOiBzdHJpbmc7XG4gIC8qKiBOb21icmUgdmlzaWJsZSBkZWwgZW1pc29yLiAqL1xuICBzZW5kZXJOYW1lOiBzdHJpbmc7XG4gIC8qKiBVUkwgZGVsIGF2YXRhciBkZWwgZW1pc29yIChvcGNpb25hbCkuICovXG4gIHNlbmRlckF2YXRhcj86IHN0cmluZztcbiAgLyoqIEN1ZXJwbyBkZWwgbWVuc2FqZS4gKi9cbiAgYm9keTogc3RyaW5nO1xuICAvKiogVGlwbyBkZSBtZW5zYWplLiAqL1xuICB0eXBlOiBNZXNzYWdlVHlwZTtcbiAgLyoqIEZlY2hhIGRlIGNyZWFjaW9uIGRlbCBtZW5zYWplLiAqL1xuICBjcmVhdGVkQXQ6IERhdGU7XG4gIC8qKiBTaSBlbCBtZW5zYWplIGZ1ZSBlbGltaW5hZG8uICovXG4gIGlzRGVsZXRlZD86IGJvb2xlYW47XG4gIC8qKiBTaSBlbCBtZW5zYWplIGZ1ZSBlZGl0YWRvLiAqL1xuICBpc0VkaXRlZD86IGJvb2xlYW47XG4gIC8qKiBNZW5zYWplIGFsIHF1ZSBzZSByZXNwb25kZS4gKi9cbiAgcmVwbHlUbz86IE1lc3NhZ2VSZXBseVRvO1xuICAvKiogQXJjaGl2b3MgYWRqdW50b3MuICovXG4gIGF0dGFjaG1lbnRzPzogTWVzc2FnZUF0dGFjaG1lbnRbXTtcbiAgLyoqIFJlYWNjaW9uZXMgZGVsIG1lbnNhamUuICovXG4gIHJlYWN0aW9ucz86IE1lc3NhZ2VSZWFjdGlvbltdO1xuICAvKiogRXN0YWRvIGRlIGVudmlvIChwYXJhIG1lbnNhamVzIG9wdGltaXN0YXMgZGVsIGxhZG8gZGVsIGNsaWVudGUpLiAqL1xuICBzdGF0dXM/OiBNZXNzYWdlU3RhdHVzO1xufVxuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFR5cGluZyBpbmRpY2F0b3Jcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4vKiogRG9jdW1lbnRvIGRlIFwiZXNjcmliaWVuZG9cIiBlbiBGaXJlc3RvcmUuICovXG5leHBvcnQgaW50ZXJmYWNlIFR5cGluZ0RvY3VtZW50IGV4dGVuZHMgRmlyZXN0b3JlRG9jdW1lbnQge1xuICAvKiogTm9tYnJlIHZpc2libGUgZGVsIHVzdWFyaW8gcXVlIGVzdGEgZXNjcmliaWVuZG8uICovXG4gIGRpc3BsYXlOYW1lOiBzdHJpbmc7XG4gIC8qKiBUaW1lc3RhbXAgZGUgbGEgdWx0aW1hIGFjdHVhbGl6YWNpb24uICovXG4gIHVwZGF0ZWRBdDogRGF0ZTtcbn1cblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBIVFRQIFJlcXVlc3QgLyBSZXNwb25zZSB0eXBlc1xuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbi8qKiBSZXF1ZXN0IHBhcmEgY3JlYXIgdW5hIGNvbnZlcnNhY2lvbi4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ3JlYXRlQ29udmVyc2F0aW9uUmVxdWVzdCB7XG4gIC8qKiBUaXBvIGRlIGNvbnZlcnNhY2lvbi4gKi9cbiAgdHlwZTogQ29udmVyc2F0aW9uVHlwZTtcbiAgLyoqIElEcyBkZSBsb3MgcGFydGljaXBhbnRlcyBpbmljaWFsZXMuICovXG4gIHBhcnRpY2lwYW50SWRzPzogc3RyaW5nW107XG4gIC8qKiBQYXJhIHRpcG8gZW50aXR5OiB0aXBvIGRlIGxhIGVudGlkYWQuICovXG4gIGVudGl0eVR5cGU/OiBzdHJpbmc7XG4gIC8qKiBQYXJhIHRpcG8gZW50aXR5OiBJRCBkZSBsYSBlbnRpZGFkLiAqL1xuICBlbnRpdHlJZD86IHN0cmluZztcbiAgLyoqIFRpdHVsbyAocGFyYSBncnVwb3MpLiAqL1xuICB0aXRsZT86IHN0cmluZztcbn1cblxuLyoqIFJlcXVlc3QgcGFyYSBhY3R1YWxpemFyIHVuYSBjb252ZXJzYWNpb24uICovXG5leHBvcnQgaW50ZXJmYWNlIFVwZGF0ZUNvbnZlcnNhdGlvblJlcXVlc3Qge1xuICAvKiogTnVldm8gdGl0dWxvIChvcGNpb25hbCkuICovXG4gIHRpdGxlPzogc3RyaW5nO1xuICAvKiogTnVldm8gZXN0YWRvIChvcGNpb25hbCkuICovXG4gIHN0YXR1cz86IENvbnZlcnNhdGlvblN0YXR1cztcbn1cblxuLyoqIFJlc3BvbnNlIGRlIGxpc3RhZG8gZGUgY29udmVyc2FjaW9uZXMuICovXG5leHBvcnQgaW50ZXJmYWNlIExpc3RDb252ZXJzYXRpb25zUmVzcG9uc2Uge1xuICAvKiogTGlzdGEgZGUgY29udmVyc2FjaW9uZXMuICovXG4gIGNvbnZlcnNhdGlvbnM6IENvbnZlcnNhdGlvbltdO1xuICAvKiogQ3Vyc29yIHBhcmEgcGFnaW5hY2lvbi4gKi9cbiAgbmV4dEN1cnNvcj86IHN0cmluZztcbiAgLyoqIFNpIGhheSBtYXMgcGFnaW5hcy4gKi9cbiAgaGFzTW9yZTogYm9vbGVhbjtcbn1cbiJdfQ==
|