@seniorsistemas/data-seniorx-core 2.3.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/core/constants/autocomplete.const.d.ts +4 -0
- package/core/constants/context-selector.const.d.ts +1 -0
- package/core/constants/gantt.const.d.ts +7 -0
- package/core/constants/hyperlink.const.d.ts +1 -0
- package/core/constants/inline-edit.const.d.ts +4 -0
- package/core/constants/kanban.const.d.ts +2 -0
- package/core/constants/pin-code-field.const.d.ts +5 -0
- package/core/constants/rating-scale.const.d.ts +1 -0
- package/core/constants/spotlight.const.d.ts +8 -0
- package/core/constants/star-rating.const.d.ts +4 -0
- package/core/constants/stepper.const.d.ts +1 -0
- package/core/constants/tiered-menu.const.d.ts +3 -0
- package/core/types/autocomplete.type.d.ts +9 -0
- package/core/types/chat.type.d.ts +12 -0
- package/core/types/checkbox-list.type.d.ts +12 -0
- package/core/types/gantt.type.d.ts +22 -0
- package/core/types/grid-menu.type.d.ts +13 -0
- package/core/types/hyperlink.type.d.ts +1 -0
- package/core/types/image-cropper.type.d.ts +20 -0
- package/core/types/inline-edit.type.d.ts +26 -0
- package/core/types/kanban.type.d.ts +36 -0
- package/core/types/panel.type.d.ts +16 -0
- package/core/types/profile-picture-picker.type.d.ts +9 -0
- package/core/types/rating-scale.type.d.ts +5 -0
- package/core/types/select-button.type.d.ts +1 -0
- package/core/types/spotlight.type.d.ts +34 -0
- package/core/types/star-rating.type.d.ts +1 -0
- package/core/types/stepper.type.d.ts +20 -0
- package/core/types/table-column.type.d.ts +3 -1
- package/core/types/table-options.type.d.ts +8 -2
- package/core/types/table.type.d.ts +1 -1
- package/core/types/tiered-menu.type.d.ts +16 -0
- package/core/types/tree.type.d.ts +25 -0
- package/core/types/workspace-switch.type.d.ts +6 -0
- package/core/utils/body-scroll.util.d.ts +2 -0
- package/core/utils/roving-focus.util.d.ts +2 -0
- package/core/utils/selection.util.d.ts +3 -0
- package/core/utils/tree.util.d.ts +4 -0
- package/esm2022/core/constants/autocomplete.const.mjs +5 -0
- package/esm2022/core/constants/context-selector.const.mjs +2 -0
- package/esm2022/core/constants/gantt.const.mjs +7 -0
- package/esm2022/core/constants/hyperlink.const.mjs +2 -1
- package/esm2022/core/constants/inline-edit.const.mjs +5 -0
- package/esm2022/core/constants/kanban.const.mjs +3 -0
- package/esm2022/core/constants/pin-code-field.const.mjs +6 -0
- package/esm2022/core/constants/rating-scale.const.mjs +2 -0
- package/esm2022/core/constants/spotlight.const.mjs +9 -0
- package/esm2022/core/constants/star-rating.const.mjs +5 -0
- package/esm2022/core/constants/stepper.const.mjs +2 -0
- package/esm2022/core/constants/table.const.mjs +2 -2
- package/esm2022/core/constants/tiered-menu.const.mjs +4 -0
- package/esm2022/core/types/autocomplete.type.mjs +2 -0
- package/esm2022/core/types/chat.type.mjs +2 -0
- package/esm2022/core/types/checkbox-list.type.mjs +2 -0
- package/esm2022/core/types/gantt.type.mjs +2 -0
- package/esm2022/core/types/grid-menu.type.mjs +2 -0
- package/esm2022/core/types/hyperlink.type.mjs +1 -1
- package/esm2022/core/types/image-cropper.type.mjs +2 -0
- package/esm2022/core/types/inline-edit.type.mjs +2 -0
- package/esm2022/core/types/kanban.type.mjs +2 -0
- package/esm2022/core/types/panel.type.mjs +9 -0
- package/esm2022/core/types/profile-picture-picker.type.mjs +2 -0
- package/esm2022/core/types/rating-scale.type.mjs +2 -0
- package/esm2022/core/types/select-button.type.mjs +1 -1
- package/esm2022/core/types/spotlight.type.mjs +2 -0
- package/esm2022/core/types/star-rating.type.mjs +2 -0
- package/esm2022/core/types/stepper.type.mjs +7 -0
- package/esm2022/core/types/table-column.type.mjs +1 -1
- package/esm2022/core/types/table-options.type.mjs +1 -1
- package/esm2022/core/types/table.type.mjs +1 -1
- package/esm2022/core/types/tiered-menu.type.mjs +2 -0
- package/esm2022/core/types/tree.type.mjs +2 -0
- package/esm2022/core/types/workspace-switch.type.mjs +2 -0
- package/esm2022/core/utils/body-scroll.util.mjs +19 -0
- package/esm2022/core/utils/combobox.util.mjs +3 -2
- package/esm2022/core/utils/roving-focus.util.mjs +20 -0
- package/esm2022/core/utils/selection.util.mjs +13 -0
- package/esm2022/core/utils/string.util.mjs +8 -3
- package/esm2022/core/utils/tree.util.mjs +23 -0
- package/esm2022/features/accordion/accordion.component.mjs +2 -2
- package/esm2022/features/accordion/{accordion-item.component.mjs → components/accordion-item/accordion-item.component.mjs} +7 -7
- package/esm2022/features/autocomplete/autocomplete.component.mjs +501 -0
- package/esm2022/features/autocomplete/components/autocomplete-chip/autocomplete-chip.component.mjs +30 -0
- package/esm2022/features/breadcrumb/breadcrumb.component.mjs +2 -2
- package/esm2022/features/card-list/card/card.component.mjs +63 -99
- package/esm2022/features/chat/chat.component.mjs +126 -0
- package/esm2022/features/checkbox-list/checkbox-list.component.mjs +125 -0
- package/esm2022/features/combobox/combobox.component.mjs +20 -8
- package/esm2022/features/context-selector/context-selector.component.mjs +198 -0
- package/esm2022/features/filters/filters.component.mjs +1 -1
- package/esm2022/features/gantt/components/gantt-side-table/gantt-side-table.component.mjs +17 -0
- package/esm2022/features/gantt/gantt-date.utils.mjs +97 -0
- package/esm2022/features/gantt/gantt.component.mjs +89 -0
- package/esm2022/features/gantt/gantt.engine.mjs +662 -0
- package/esm2022/features/grid-menu/grid-menu.component.mjs +104 -0
- package/esm2022/features/hyperlink/hyperlink.component.mjs +7 -4
- package/esm2022/features/icon-picker/icon-picker.component.mjs +3 -3
- package/esm2022/features/image-cropper/image-cropper.component.mjs +218 -0
- package/esm2022/features/image-cropper/services/image-cropper.service.mjs +50 -0
- package/esm2022/features/infinite-scroll/infinite-scroll.directive.mjs +89 -0
- package/esm2022/features/info-sign/info-sign.component.mjs +3 -3
- package/esm2022/features/inline-edit/components/fields/inline-edit-number/inline-edit-number.component.mjs +38 -0
- package/esm2022/features/inline-edit/components/fields/inline-edit-text/inline-edit-text.component.mjs +29 -0
- package/esm2022/features/inline-edit/components/fields/inline-edit-textarea/inline-edit-textarea.component.mjs +29 -0
- package/esm2022/features/inline-edit/components/inline-edit-item/inline-edit-item.component.mjs +131 -0
- package/esm2022/features/inline-edit/fields/inline-edit-field.mjs +17 -0
- package/esm2022/features/inline-edit/fields/inline-edit-number-field.mjs +15 -0
- package/esm2022/features/inline-edit/fields/inline-edit-text-field.mjs +11 -0
- package/esm2022/features/inline-edit/fields/inline-edit-textarea-field.mjs +15 -0
- package/esm2022/features/inline-edit/inline-edit.component.mjs +27 -0
- package/esm2022/features/interactive-content/interactive-content.directive.mjs +140 -0
- package/esm2022/features/kanban/components/kanban-column/kanban-column.component.mjs +88 -0
- package/esm2022/features/kanban/components/kanban-item/kanban-item.component.mjs +72 -0
- package/esm2022/features/kanban/components/kanban-item-dragging/kanban-item-dragging.component.mjs +19 -0
- package/esm2022/features/kanban/directives/kanban-template.directive.mjs +22 -0
- package/esm2022/features/kanban/kanban.component.mjs +198 -0
- package/esm2022/features/kanban/services/kanban-event.service.mjs +27 -0
- package/esm2022/features/loading-state/loading-state.component.mjs +3 -62
- package/esm2022/features/mouse-events/directives/double-click.directive.mjs +34 -0
- package/esm2022/features/mouse-events/directives/long-press.directive.mjs +61 -0
- package/esm2022/features/paginator/paginator.component.mjs +8 -3
- package/esm2022/features/panel/panel.component.mjs +43 -11
- package/esm2022/features/pin-code-field/pin-code-field.component.mjs +234 -0
- package/esm2022/features/profile-picture-picker/profile-picture-picker.component.mjs +330 -0
- package/esm2022/features/rating-scale/rating-scale.component.mjs +86 -0
- package/esm2022/features/row-card-list/row-card/row-card.component.mjs +3 -3
- package/esm2022/features/scaffold/scaffold.component.mjs +4 -6
- package/esm2022/features/select-button/select-button.component.mjs +7 -4
- package/esm2022/features/speech-recognition/services/speech-recognition.service.mjs +148 -0
- package/esm2022/features/speech-recognition/services/text-to-speech.service.mjs +88 -0
- package/esm2022/features/speech-recognition/speech-recognition.component.mjs +243 -0
- package/esm2022/features/spotlight/components/spotlight-overlay/spotlight-overlay.component.mjs +521 -0
- package/esm2022/features/spotlight/directives/spotlight-step.directive.mjs +38 -0
- package/esm2022/features/spotlight/services/spotlight-tour.service.mjs +179 -0
- package/esm2022/features/spotlight/spotlight.component.mjs +160 -0
- package/esm2022/features/star-rating/star-rating.component.mjs +95 -0
- package/esm2022/features/stepper/stepper.component.mjs +86 -0
- package/esm2022/features/switch/switch.component.mjs +12 -8
- package/esm2022/features/tab/{tab-item.component.mjs → components/tab-item/tab-item.component.mjs} +1 -1
- package/esm2022/features/tab/tab.component.mjs +4 -4
- package/esm2022/features/table/components/table-cell-content.component.mjs +14 -5
- package/esm2022/features/table/table.component.mjs +220 -29
- package/esm2022/features/table/utils/table-data.util.mjs +71 -8
- package/esm2022/features/table/utils/table-layout.util.mjs +21 -1
- package/esm2022/features/tiered-menu/components/tiered-menu/tiered-menu.component.mjs +367 -0
- package/esm2022/features/tiered-menu/components/tiered-menu-divider/tiered-menu-divider.component.mjs +11 -0
- package/esm2022/features/tiered-menu/components/tiered-menu-item/tiered-menu-item.component.mjs +97 -0
- package/esm2022/features/tiered-menu/components/tiered-menu-nested/tiered-menu-nested.component.mjs +181 -0
- package/esm2022/features/tiered-menu/directives/tiered-menu.directive.mjs +246 -0
- package/esm2022/features/tiered-menu/services/tiered-menu.event.service.mjs +16 -0
- package/esm2022/features/tiered-menu/services/tiered-menu.global.service.mjs +12 -0
- package/esm2022/features/tiered-menu/services/tiered-menu.service.mjs +49 -0
- package/esm2022/features/tree/components/tree-node-item/tree-node-item.component.mjs +169 -0
- package/esm2022/features/tree/tree.component.mjs +211 -0
- package/esm2022/features/visual-sql-editor/components/visual-sql-editor-field-modal/visual-sql-editor-field-modal.component.mjs +41 -0
- package/esm2022/features/visual-sql-editor/components/visual-sql-editor-filter-modal/visual-sql-editor-filter-modal.component.mjs +38 -0
- package/esm2022/features/visual-sql-editor/components/visual-sql-editor-join-modal/visual-sql-editor-join-modal.component.mjs +29 -0
- package/esm2022/features/visual-sql-editor/components/visual-sql-editor-sort-modal/visual-sql-editor-sort-modal.component.mjs +29 -0
- package/esm2022/features/visual-sql-editor/components/visual-sql-editor-source-modal/visual-sql-editor-source-modal.component.mjs +35 -0
- package/esm2022/features/visual-sql-editor/services/visual-sql-editor-flow.service.mjs +106 -0
- package/esm2022/features/visual-sql-editor/services/visual-sql-editor-state.service.mjs +230 -0
- package/esm2022/features/visual-sql-editor/types/visual-sql-editor.types.mjs +2 -0
- package/esm2022/features/visual-sql-editor/utils/visual-sql-editor-sanitize.util.mjs +72 -0
- package/esm2022/features/visual-sql-editor/utils/visual-sql-editor-sql.util.mjs +281 -0
- package/esm2022/features/visual-sql-editor/utils/visual-sql-editor-text.util.mjs +37 -0
- package/esm2022/features/visual-sql-editor/utils/visual-sql-editor.constants.mjs +89 -0
- package/esm2022/features/visual-sql-editor/visual-sql-editor.component.mjs +172 -630
- package/esm2022/locales/en.json +351 -3
- package/esm2022/locales/es-CO.json +351 -3
- package/esm2022/locales/pt.json +351 -3
- package/esm2022/providers/features.provider.mjs +40 -4
- package/esm2022/public-api.mjs +56 -3
- package/features/accordion/accordion.component.d.ts +1 -1
- package/features/accordion/{accordion-item.component.d.ts → components/accordion-item/accordion-item.component.d.ts} +1 -1
- package/features/autocomplete/autocomplete.component.d.ts +102 -0
- package/features/autocomplete/components/autocomplete-chip/autocomplete-chip.component.d.ts +11 -0
- package/features/card-list/card/card.component.d.ts +14 -34
- package/features/chat/chat.component.d.ts +31 -0
- package/features/checkbox-list/checkbox-list.component.d.ts +26 -0
- package/features/combobox/combobox.component.d.ts +2 -1
- package/features/context-selector/context-selector.component.d.ts +37 -0
- package/features/gantt/components/gantt-side-table/gantt-side-table.component.d.ts +8 -0
- package/features/gantt/gantt-date.utils.d.ts +36 -0
- package/features/gantt/gantt.component.d.ts +24 -0
- package/features/gantt/gantt.engine.d.ts +52 -0
- package/features/grid-menu/grid-menu.component.d.ts +29 -0
- package/features/hyperlink/hyperlink.component.d.ts +2 -1
- package/features/image-cropper/image-cropper.component.d.ts +43 -0
- package/features/image-cropper/services/image-cropper.service.d.ts +13 -0
- package/features/infinite-scroll/infinite-scroll.directive.d.ts +25 -0
- package/features/inline-edit/components/fields/inline-edit-number/inline-edit-number.component.d.ts +13 -0
- package/features/inline-edit/components/fields/inline-edit-text/inline-edit-text.component.d.ts +13 -0
- package/features/inline-edit/components/fields/inline-edit-textarea/inline-edit-textarea.component.d.ts +13 -0
- package/features/inline-edit/components/inline-edit-item/inline-edit-item.component.d.ts +37 -0
- package/features/inline-edit/fields/inline-edit-field.d.ts +12 -0
- package/features/inline-edit/fields/inline-edit-number-field.d.ts +9 -0
- package/features/inline-edit/fields/inline-edit-text-field.d.ts +7 -0
- package/features/inline-edit/fields/inline-edit-textarea-field.d.ts +9 -0
- package/features/inline-edit/inline-edit.component.d.ts +13 -0
- package/features/interactive-content/interactive-content.directive.d.ts +31 -0
- package/features/kanban/components/kanban-column/kanban-column.component.d.ts +22 -0
- package/features/kanban/components/kanban-item/kanban-item.component.d.ts +23 -0
- package/features/kanban/components/kanban-item-dragging/kanban-item-dragging.component.d.ts +8 -0
- package/features/kanban/directives/kanban-template.directive.d.ts +10 -0
- package/features/kanban/kanban.component.d.ts +32 -0
- package/features/kanban/services/kanban-event.service.d.ts +15 -0
- package/features/loading-state/loading-state.component.d.ts +0 -2
- package/features/mouse-events/directives/double-click.directive.d.ts +11 -0
- package/features/mouse-events/directives/long-press.directive.d.ts +14 -0
- package/features/panel/panel.component.d.ts +12 -3
- package/features/pin-code-field/pin-code-field.component.d.ts +44 -0
- package/features/profile-picture-picker/profile-picture-picker.component.d.ts +77 -0
- package/features/rating-scale/rating-scale.component.d.ts +24 -0
- package/features/select-button/select-button.component.d.ts +2 -1
- package/features/speech-recognition/services/speech-recognition.service.d.ts +29 -0
- package/features/speech-recognition/services/text-to-speech.service.d.ts +24 -0
- package/features/speech-recognition/speech-recognition.component.d.ts +50 -0
- package/features/spotlight/components/spotlight-overlay/spotlight-overlay.component.d.ts +59 -0
- package/features/spotlight/directives/spotlight-step.directive.d.ts +13 -0
- package/features/spotlight/services/spotlight-tour.service.d.ts +46 -0
- package/features/spotlight/spotlight.component.d.ts +59 -0
- package/features/star-rating/star-rating.component.d.ts +26 -0
- package/features/stepper/stepper.component.d.ts +23 -0
- package/features/switch/switch.component.d.ts +2 -1
- package/features/tab/tab.component.d.ts +1 -1
- package/features/table/components/table-cell-content.component.d.ts +4 -3
- package/features/table/table.component.d.ts +40 -5
- package/features/table/utils/table-data.util.d.ts +1 -0
- package/features/table/utils/table-layout.util.d.ts +1 -0
- package/features/tiered-menu/components/tiered-menu/tiered-menu.component.d.ts +49 -0
- package/features/tiered-menu/components/tiered-menu-divider/tiered-menu-divider.component.d.ts +5 -0
- package/features/tiered-menu/components/tiered-menu-item/tiered-menu-item.component.d.ts +19 -0
- package/features/tiered-menu/components/tiered-menu-nested/tiered-menu-nested.component.d.ts +26 -0
- package/features/tiered-menu/directives/tiered-menu.directive.d.ts +44 -0
- package/features/tiered-menu/services/tiered-menu.event.service.d.ts +13 -0
- package/features/tiered-menu/services/tiered-menu.global.service.d.ts +7 -0
- package/features/tiered-menu/services/tiered-menu.service.d.ts +14 -0
- package/features/tree/components/tree-node-item/tree-node-item.component.d.ts +37 -0
- package/features/tree/tree.component.d.ts +37 -0
- package/features/visual-sql-editor/components/visual-sql-editor-field-modal/visual-sql-editor-field-modal.component.d.ts +18 -0
- package/features/visual-sql-editor/components/visual-sql-editor-filter-modal/visual-sql-editor-filter-modal.component.d.ts +17 -0
- package/features/visual-sql-editor/components/visual-sql-editor-join-modal/visual-sql-editor-join-modal.component.d.ts +13 -0
- package/features/visual-sql-editor/components/visual-sql-editor-sort-modal/visual-sql-editor-sort-modal.component.d.ts +13 -0
- package/features/visual-sql-editor/components/visual-sql-editor-source-modal/visual-sql-editor-source-modal.component.d.ts +15 -0
- package/features/visual-sql-editor/services/visual-sql-editor-flow.service.d.ts +26 -0
- package/features/visual-sql-editor/services/visual-sql-editor-state.service.d.ts +72 -0
- package/features/visual-sql-editor/types/visual-sql-editor.types.d.ts +182 -0
- package/features/visual-sql-editor/utils/visual-sql-editor-sanitize.util.d.ts +14 -0
- package/features/visual-sql-editor/utils/visual-sql-editor-sql.util.d.ts +81 -0
- package/features/visual-sql-editor/utils/visual-sql-editor-text.util.d.ts +15 -0
- package/features/visual-sql-editor/utils/visual-sql-editor.constants.d.ts +36 -0
- package/features/visual-sql-editor/visual-sql-editor.component.d.ts +37 -199
- package/fesm2022/seniorsistemas-data-seniorx-core.mjs +14883 -6353
- package/fesm2022/seniorsistemas-data-seniorx-core.mjs.map +1 -1
- package/package.json +8 -8
- package/public-api.d.ts +72 -2
- package/src/locales/en.json +353 -15
- package/src/locales/es-CO.json +352 -14
- package/src/locales/pt.json +352 -14
- package/styles/sdc-global-variables.scss +1 -1
- package/styles.css +1 -1
- /package/features/tab/{tab-item.component.d.ts → components/tab-item/tab-item.component.d.ts} +0 -0
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { Injectable } from '@angular/core';
|
|
2
|
+
import { BehaviorSubject, Subject } from 'rxjs';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
export class SpeechRecognitionService {
|
|
5
|
+
recognition = null;
|
|
6
|
+
silenceHandle = null;
|
|
7
|
+
transcriptSubject = new Subject();
|
|
8
|
+
errorSubject = new Subject();
|
|
9
|
+
permissionDeniedSubject = new Subject();
|
|
10
|
+
listeningSubject = new BehaviorSubject(false);
|
|
11
|
+
transcript$ = this.transcriptSubject.asObservable();
|
|
12
|
+
error$ = this.errorSubject.asObservable();
|
|
13
|
+
permissionDenied$ = this.permissionDeniedSubject.asObservable();
|
|
14
|
+
listening$ = this.listeningSubject.asObservable();
|
|
15
|
+
get supported() {
|
|
16
|
+
return !!this.getSpeechRecognitionConstructor();
|
|
17
|
+
}
|
|
18
|
+
start(options) {
|
|
19
|
+
const SpeechRecognitionConstructor = this.getSpeechRecognitionConstructor();
|
|
20
|
+
if (!SpeechRecognitionConstructor) {
|
|
21
|
+
this.errorSubject.next('unsupported');
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
this.disposeActiveRecognition();
|
|
25
|
+
const recognition = new SpeechRecognitionConstructor();
|
|
26
|
+
recognition.continuous = true;
|
|
27
|
+
recognition.interimResults = true;
|
|
28
|
+
recognition.lang = options.lang;
|
|
29
|
+
recognition.onstart = () => {
|
|
30
|
+
this.listeningSubject.next(true);
|
|
31
|
+
this.resetSilenceTimer(options.silenceTimeoutMs);
|
|
32
|
+
};
|
|
33
|
+
recognition.onresult = (event) => {
|
|
34
|
+
const transcript = this.extractTranscript(event);
|
|
35
|
+
if (!transcript) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
this.transcriptSubject.next(transcript);
|
|
39
|
+
this.resetSilenceTimer(options.silenceTimeoutMs);
|
|
40
|
+
};
|
|
41
|
+
recognition.onerror = (event) => {
|
|
42
|
+
if (event.error === 'not-allowed' || event.error === 'service-not-allowed') {
|
|
43
|
+
this.permissionDeniedSubject.next();
|
|
44
|
+
}
|
|
45
|
+
this.errorSubject.next(event.error);
|
|
46
|
+
this.listeningSubject.next(false);
|
|
47
|
+
this.clearSilenceTimer();
|
|
48
|
+
};
|
|
49
|
+
recognition.onend = () => {
|
|
50
|
+
this.clearSilenceTimer();
|
|
51
|
+
this.listeningSubject.next(false);
|
|
52
|
+
this.clearRecognitionHandlers(recognition);
|
|
53
|
+
};
|
|
54
|
+
this.recognition = recognition;
|
|
55
|
+
try {
|
|
56
|
+
recognition.start();
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
this.errorSubject.next('start-failed');
|
|
61
|
+
this.listeningSubject.next(false);
|
|
62
|
+
this.clearRecognitionHandlers(recognition);
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
stop() {
|
|
67
|
+
this.clearSilenceTimer();
|
|
68
|
+
if (!this.recognition) {
|
|
69
|
+
this.listeningSubject.next(false);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
try {
|
|
73
|
+
this.recognition.stop();
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
this.listeningSubject.next(false);
|
|
77
|
+
this.clearRecognitionHandlers(this.recognition);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
abort() {
|
|
81
|
+
this.clearSilenceTimer();
|
|
82
|
+
if (!this.recognition) {
|
|
83
|
+
this.listeningSubject.next(false);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
const activeRecognition = this.recognition;
|
|
87
|
+
this.clearRecognitionHandlers(activeRecognition);
|
|
88
|
+
try {
|
|
89
|
+
activeRecognition.abort();
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
this.listeningSubject.next(false);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
disposeActiveRecognition() {
|
|
96
|
+
if (!this.recognition) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
const activeRecognition = this.recognition;
|
|
100
|
+
this.clearRecognitionHandlers(activeRecognition);
|
|
101
|
+
try {
|
|
102
|
+
activeRecognition.abort();
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
this.listeningSubject.next(false);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
extractTranscript(event) {
|
|
109
|
+
const parts = Array.from({ length: event.results.length }, (_value, index) => {
|
|
110
|
+
return event.results[index]?.[0]?.transcript?.trim() ?? '';
|
|
111
|
+
}).filter(Boolean);
|
|
112
|
+
return parts.join(' ').replace(/\s+/g, ' ').trim();
|
|
113
|
+
}
|
|
114
|
+
resetSilenceTimer(timeoutMs) {
|
|
115
|
+
this.clearSilenceTimer();
|
|
116
|
+
if (timeoutMs <= 0) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
this.silenceHandle = setTimeout(() => this.stop(), timeoutMs);
|
|
120
|
+
}
|
|
121
|
+
clearSilenceTimer() {
|
|
122
|
+
if (!this.silenceHandle) {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
clearTimeout(this.silenceHandle);
|
|
126
|
+
this.silenceHandle = null;
|
|
127
|
+
}
|
|
128
|
+
clearRecognitionHandlers(recognition) {
|
|
129
|
+
recognition.onstart = null;
|
|
130
|
+
recognition.onresult = null;
|
|
131
|
+
recognition.onerror = null;
|
|
132
|
+
recognition.onend = null;
|
|
133
|
+
if (this.recognition === recognition) {
|
|
134
|
+
this.recognition = null;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
getSpeechRecognitionConstructor() {
|
|
138
|
+
const speechGlobal = globalThis;
|
|
139
|
+
return speechGlobal.SpeechRecognition ?? speechGlobal.webkitSpeechRecognition ?? null;
|
|
140
|
+
}
|
|
141
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SpeechRecognitionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
142
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SpeechRecognitionService, providedIn: 'root' });
|
|
143
|
+
}
|
|
144
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SpeechRecognitionService, decorators: [{
|
|
145
|
+
type: Injectable,
|
|
146
|
+
args: [{ providedIn: 'root' }]
|
|
147
|
+
}] });
|
|
148
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BlZWNoLXJlY29nbml0aW9uLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9saWIvc3JjL2ZlYXR1cmVzL3NwZWVjaC1yZWNvZ25pdGlvbi9zZXJ2aWNlcy9zcGVlY2gtcmVjb2duaXRpb24uc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxlQUFlLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDOztBQTBDaEQsTUFBTSxPQUFPLHdCQUF3QjtJQUMzQixXQUFXLEdBQW9DLElBQUksQ0FBQztJQUNwRCxhQUFhLEdBQXlDLElBQUksQ0FBQztJQUVsRCxpQkFBaUIsR0FBRyxJQUFJLE9BQU8sRUFBVSxDQUFDO0lBQzFDLFlBQVksR0FBRyxJQUFJLE9BQU8sRUFBVSxDQUFDO0lBQ3JDLHVCQUF1QixHQUFHLElBQUksT0FBTyxFQUFRLENBQUM7SUFDOUMsZ0JBQWdCLEdBQUcsSUFBSSxlQUFlLENBQUMsS0FBSyxDQUFDLENBQUM7SUFFdEQsV0FBVyxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUNwRCxNQUFNLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUMxQyxpQkFBaUIsR0FBRyxJQUFJLENBQUMsdUJBQXVCLENBQUMsWUFBWSxFQUFFLENBQUM7SUFDaEUsVUFBVSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUUzRCxJQUFJLFNBQVM7UUFDWCxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsK0JBQStCLEVBQUUsQ0FBQztJQUNsRCxDQUFDO0lBRUQsS0FBSyxDQUFDLE9BQXNDO1FBQzFDLE1BQU0sNEJBQTRCLEdBQUcsSUFBSSxDQUFDLCtCQUErQixFQUFFLENBQUM7UUFFNUUsSUFBSSxDQUFD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V0FBVyxFQUFFLENBQUM7WUFDckMsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUM7UUFDMUIsQ0FBQztJQUNILENBQUM7SUFFTywrQkFBK0I7UUFDckMsTUFBTSxZQUFZLEdBQUcsVUFBcUMsQ0FBQztRQUMzRCxPQUFPLFlBQVksQ0FBQyxpQkFBaUIsSUFBSSxZQUFZLENBQUMsdUJBQXVCLElBQUksSUFBSSxDQUFDO0lBQ3hGLENBQUM7d0dBcEtVLHdCQUF3Qjs0R0FBeEIsd0JBQXdCLGNBRFgsTUFBTTs7NEZBQ25CLHdCQUF3QjtrQkFEcEMsVUFBVTttQkFBQyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBCZWhhdmlvclN1YmplY3QsIFN1YmplY3QgfSBmcm9tICdyeGpzJztcblxudHlwZSBCcm93c2VyU3BlZWNoUmVjb2duaXRpb25Db25zdHJ1Y3RvciA9IG5ldyAoKSA9PiBCcm93c2VyU3BlZWNoUmVjb2duaXRpb247XG5cbnR5cGUgQnJvd3NlclNwZWVjaFJlY29nbml0aW9uID0ge1xuICBjb250aW51b3VzOiBib29sZWFuO1xuICBpbnRlcmltUmVzdWx0czogYm9vbGVhbjtcbiAgbGFuZzogc3RyaW5nO1xuICBvbmVuZDogKCgpID0+IHZvaWQpIHwgbnVsbDtcbiAgb25lcnJvcjogKChldmVudDogQnJvd3NlclNwZWVjaFJlY29nbml0aW9uRXJyb3JFdmVudCkgPT4gdm9pZCkgfCBudWxsO1xuICBvbnJlc3VsdDogKChldmVudDogQnJvd3NlclNwZWVjaFJlY29nbml0aW9uRXZlbnQpID0+IHZvaWQpIHwgbnVsbDtcbiAgb25zdGFydDogKCgpID0+IHZvaWQpIHwgbnVsbDtcbiAgYWJvcnQoKTogdm9pZDtcbiAgc3RhcnQoKTogdm9pZDtcbiAgc3RvcCgpOiB2b2lkO1xufTtcblxudHlwZSBCcm93c2VyU3BlZWNoUmVjb2duaXRpb25BbHRlcm5hdGl2ZSA9IHtcbiAgdHJhbnNjcmlwdDogc3RyaW5nO1xufTtcblxudHlwZSBCcm93c2VyU3BlZWNoUmVjb2duaXRpb25SZXN1bHQgPSBBcnJheUxpa2U8QnJvd3NlclNwZWVjaFJlY29nbml0aW9uQWx0ZXJuYXRpdmU+O1xuXG50eXBlIEJyb3dzZXJTcGVlY2hSZWNvZ25pdGlvbkV2ZW50ID0ge1xuICByZXN1bHRzOiBBcnJheUxpa2U8QnJvd3NlclNwZWVjaFJlY29nbml0aW9uUmVzdWx0Pjtcbn07XG5cbnR5cGUgQnJvd3NlclNwZWVjaFJlY29nbml0aW9uRXJyb3JFdmVudCA9IHtcbiAgZXJyb3I6IHN0cmluZztcbn07XG5cbnR5cGUgU3BlZWNoUmVjb2duaXRpb25HbG9iYWwgPSB0eXBlb2YgZ2xvYmFsVGhpcyAmIHtcbiAgU3BlZWNoUmVjb2duaXRpb24/OiBCcm93c2VyU3BlZWNoUmVjb2duaXRpb25Db25zdHJ1Y3RvcjtcbiAgd2Via2l0U3BlZWNoUmVjb2duaXRpb24/OiBCcm93c2VyU3BlZWNoUmVjb2duaXRpb25Db25zdHJ1Y3Rvcjtcbn07XG5cbmV4cG9ydCB0eXBlIFNwZWVjaFJlY29nbml0aW9uU3RhcnRPcHRpb25zID0ge1xuICBsYW5nOiBzdHJpbmc7XG4gIHNpbGVuY2VUaW1lb3V0TXM6IG51bWJlcjtcbn07XG5cbkBJbmplY3RhYmxlKHsgcHJvdmlkZWRJbjogJ3Jvb3QnIH0pXG5leHBvcnQgY2xhc3MgU3BlZWNoUmVjb2duaXRpb25TZXJ2aWNlIHtcbiAgcHJpdmF0ZSByZWNvZ25pdGlvbjogQnJvd3NlclNwZWVjaFJlY29nbml0aW9uIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgc2lsZW5jZUhhbmRsZTogUmV0dXJuVHlwZTx0eXBlb2Ygc2V0VGltZW91dD4gfCBudWxsID0gbnVsbDtcblxuICBwcml2YXRlIHJlYWRvbmx5IHRyYW5zY3JpcHRTdWJqZWN0ID0gbmV3IFN1YmplY3Q8c3RyaW5nPigpO1xuICBwcml2YXRlIHJlYWRvbmx5IGVycm9yU3ViamVjdCA9IG5ldyBTdWJqZWN0PHN0cmluZz4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSBwZXJtaXNzaW9uRGVuaWVkU3ViamVjdCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgbGlzdGVuaW5nU3ViamVjdCA9IG5ldyBCZWhhdmlvclN1YmplY3QoZmFsc2UpO1xuXG4gIHJlYWRvbmx5IHRyYW5zY3JpcHQkID0gdGhpcy50cmFuc2NyaXB0U3ViamVjdC5hc09ic2VydmFibGUoKTtcbiAgcmVhZG9ubHkgZXJyb3IkID0gdGhpcy5lcnJvclN1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG4gIHJlYWRvbmx5IHBlcm1pc3Npb25EZW5pZWQkID0gdGhpcy5wZXJtaXNzaW9uRGVuaWVkU3ViamVjdC5hc09ic2VydmFibGUoKTtcbiAgcmVhZG9ubHkgbGlzdGVuaW5nJCA9IHRoaXMubGlzdGVuaW5nU3ViamVjdC5hc09ic2VydmFibGUoKTtcblxuICBnZXQgc3VwcG9ydGVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhIXRoaXMuZ2V0U3BlZWNoUmVjb2duaXRpb25Db25zdHJ1Y3RvcigpO1xuICB9XG5cbiAgc3RhcnQob3B0aW9uczogU3BlZWNoUmVjb2duaXRpb25TdGFydE9wdGlvbnMpOiBib29sZWFuIHtcbiAgICBjb25zdCBTcGVlY2hSZWNvZ25pdGlvbkNvbnN0cnVjdG9yID0gdGhpcy5nZXRTcGVlY2hSZWNvZ25pdGlvbkNvbnN0cnVjdG9yKCk7XG5cbiAgICBpZiAoIVNwZWVjaFJlY29nbml0aW9uQ29uc3RydWN0b3IpIHtcbiAgICAgIHRoaXMuZXJyb3JTdWJqZWN0Lm5leHQoJ3Vuc3VwcG9ydGVkJyk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgdGhpcy5kaXNwb3NlQWN0aXZlUmVjb2duaXRpb24oKTtcblxuICAgIGNvbnN0IHJlY29nbml0aW9uID0gbmV3IFNwZWVjaFJlY29nbml0aW9uQ29uc3RydWN0b3IoKTtcbiAgICByZWNvZ25pdGlvbi5jb250aW51b3VzID0gdHJ1ZTtcbiAgICByZWNvZ25pdGlvbi5pbnRlcmltUmVzdWx0cyA9IHRydWU7XG4gICAgcmVjb2duaXRpb24ubGFuZyA9IG9wdGlvbnMubGFuZztcbiAgICByZWNvZ25pdGlvbi5vbnN0YXJ0ID0gKCkgPT4ge1xuICAgICAgdGhpcy5saXN0ZW5pbmdTdWJqZWN0Lm5leHQodHJ1ZSk7XG4gICAgICB0aGlzLnJlc2V0U2lsZW5jZVRpbWVyKG9wdGlvbnMuc2lsZW5jZVRpbWVvdXRNcyk7XG4gICAgfTtcbiAgICByZWNvZ25pdGlvbi5vbnJlc3VsdCA9IChldmVudCkgPT4ge1xuICAgICAgY29uc3QgdHJhbnNjcmlwdCA9IHRoaXMuZXh0cmFjdFRyYW5zY3JpcHQoZXZlbnQpO1xuXG4gICAgICBpZiAoIXRyYW5zY3JpcHQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB0aGlzLnRyYW5zY3JpcHRTdWJqZWN0Lm5leHQodHJhbnNjcmlwdCk7XG4gICAgICB0aGlzLnJlc2V0U2lsZW5jZVRpbWVyKG9wdGlvbnMuc2lsZW5jZVRpbWVvdXRNcyk7XG4gICAgfTtcbiAgICByZWNvZ25pdGlvbi5vbmVycm9yID0gKGV2ZW50KSA9PiB7XG4gICAgICBpZiAoZXZlbnQuZXJyb3IgPT09ICdub3QtYWxsb3dlZCcgfHwgZXZlbnQuZXJyb3IgPT09ICdzZXJ2aWNlLW5vdC1hbGxvd2VkJykge1xuICAgICAgICB0aGlzLnBlcm1pc3Npb25EZW5pZWRTdWJqZWN0Lm5leHQoKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5lcnJvclN1YmplY3QubmV4dChldmVudC5lcnJvcik7XG4gICAgICB0aGlzLmxpc3RlbmluZ1N1YmplY3QubmV4dChmYWxzZSk7XG4gICAgICB0aGlzLmNsZWFyU2lsZW5jZVRpbWVyKCk7XG4gICAgfTtcbiAgICByZWNvZ25pdGlvbi5vbmVuZCA9ICgpID0+IHtcbiAgICAgIHRoaXMuY2xlYXJTaWxlbmNlVGltZXIoKTtcbiAgICAgIHRoaXMubGlzdGVuaW5nU3ViamVjdC5uZXh0KGZhbHNlKTtcbiAgICAgIHRoaXMuY2xlYXJSZWNvZ25pdGlvbkhhbmRsZXJzKHJlY29nbml0aW9uKTtcbiAgICB9O1xuXG4gICAgdGhpcy5yZWNvZ25pdGlvbiA9IHJlY29nbml0aW9uO1xuXG4gICAgdHJ5IHtcbiAgICAgIHJlY29nbml0aW9uLnN0YXJ0KCk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHRoaXMuZXJyb3JTdWJqZWN0Lm5leHQoJ3N0YXJ0LWZhaWxlZCcpO1xuICAgICAgdGhpcy5saXN0ZW5pbmdTdWJqZWN0Lm5leHQoZmFsc2UpO1xuICAgICAgdGhpcy5jbGVhclJlY29nbml0aW9uSGFuZGxlcnMocmVjb2duaXRpb24pO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHN0b3AoKTogdm9pZCB7XG4gICAgdGhpcy5jbGVhclNpbGVuY2VUaW1lcigpO1xuXG4gICAgaWYgKCF0aGlzLnJlY29nbml0aW9uKSB7XG4gICAgICB0aGlzLmxpc3RlbmluZ1N1YmplY3QubmV4dChmYWxzZSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIHRoaXMucmVjb2duaXRpb24uc3RvcCgpO1xuICAgIH0gY2F0Y2gge1xuICAgICAgdGhpcy5saXN0ZW5pbmdTdWJqZWN0Lm5leHQoZmFsc2UpO1xuICAgICAgdGhpcy5jbGVhclJlY29nbml0aW9uSGFuZGxlcnModGhpcy5yZWNvZ25pdGlvbik7XG4gICAgfVxuICB9XG5cbiAgYWJvcnQoKTogdm9pZCB7XG4gICAgdGhpcy5jbGVhclNpbGVuY2VUaW1lcigpO1xuXG4gICAgaWYgKCF0aGlzLnJlY29nbml0aW9uKSB7XG4gICAgICB0aGlzLmxpc3RlbmluZ1N1YmplY3QubmV4dChmYWxzZSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgYWN0aXZlUmVjb2duaXRpb24gPSB0aGlzLnJlY29nbml0aW9uO1xuICAgIHRoaXMuY2xlYXJSZWNvZ25pdGlvbkhhbmRsZXJzKGFjdGl2ZVJlY29nbml0aW9uKTtcblxuICAgIHRyeSB7XG4gICAgICBhY3RpdmVSZWNvZ25pdGlvbi5hYm9ydCgpO1xuICAgIH0gY2F0Y2gge1xuICAgICAgdGhpcy5saXN0ZW5pbmdTdWJqZWN0Lm5leHQoZmFsc2UpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZGlzcG9zZUFjdGl2ZVJlY29nbml0aW9uKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5yZWNvZ25pdGlvbikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGFjdGl2ZVJlY29nbml0aW9uID0gdGhpcy5yZWNvZ25pdGlvbjtcbiAgICB0aGlzLmNsZWFyUmVjb2duaXRpb25IYW5kbGVycyhhY3RpdmVSZWNvZ25pdGlvbik7XG5cbiAgICB0cnkge1xuICAgICAgYWN0aXZlUmVjb2duaXRpb24uYWJvcnQoKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHRoaXMubGlzdGVuaW5nU3ViamVjdC5uZXh0KGZhbHNlKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGV4dHJhY3RUcmFuc2NyaXB0KGV2ZW50OiBCcm93c2VyU3BlZWNoUmVjb2duaXRpb25FdmVudCk6IHN0cmluZyB7XG4gICAgY29uc3QgcGFydHMgPSBBcnJheS5mcm9tKHsgbGVuZ3RoOiBldmVudC5yZXN1bHRzLmxlbmd0aCB9LCAoX3ZhbHVlLCBpbmRleCkgPT4ge1xuICAgICAgcmV0dXJuIGV2ZW50LnJlc3VsdHNbaW5kZXhdPy5bMF0/LnRyYW5zY3JpcHQ/LnRyaW0oKSA/PyAnJztcbiAgICB9KS5maWx0ZXIoQm9vbGVhbik7XG5cbiAgICByZXR1cm4gcGFydHMuam9pbignICcpLnJlcGxhY2UoL1xccysvZywgJyAnKS50cmltKCk7XG4gIH1cblxuICBwcml2YXRlIHJlc2V0U2lsZW5jZVRpbWVyKHRpbWVvdXRNczogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5jbGVhclNpbGVuY2VUaW1lcigpO1xuXG4gICAgaWYgKHRpbWVvdXRNcyA8PSAwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5zaWxlbmNlSGFuZGxlID0gc2V0VGltZW91dCgoKSA9PiB0aGlzLnN0b3AoKSwgdGltZW91dE1zKTtcbiAgfVxuXG4gIHByaXZhdGUgY2xlYXJTaWxlbmNlVGltZXIoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnNpbGVuY2VIYW5kbGUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjbGVhclRpbWVvdXQodGhpcy5zaWxlbmNlSGFuZGxlKTtcbiAgICB0aGlzLnNpbGVuY2VIYW5kbGUgPSBudWxsO1xuICB9XG5cbiAgcHJpdmF0ZSBjbGVhclJlY29nbml0aW9uSGFuZGxlcnMocmVjb2duaXRpb246IEJyb3dzZXJTcGVlY2hSZWNvZ25pdGlvbik6IHZvaWQge1xuICAgIHJlY29nbml0aW9uLm9uc3RhcnQgPSBudWxsO1xuICAgIHJlY29nbml0aW9uLm9ucmVzdWx0ID0gbnVsbDtcbiAgICByZWNvZ25pdGlvbi5vbmVycm9yID0gbnVsbDtcbiAgICByZWNvZ25pdGlvbi5vbmVuZCA9IG51bGw7XG5cbiAgICBpZiAodGhpcy5yZWNvZ25pdGlvbiA9PT0gcmVjb2duaXRpb24pIHtcbiAgICAgIHRoaXMucmVjb2duaXRpb24gPSBudWxsO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZ2V0U3BlZWNoUmVjb2duaXRpb25Db25zdHJ1Y3RvcigpOiBCcm93c2VyU3BlZWNoUmVjb2duaXRpb25Db25zdHJ1Y3RvciB8IG51bGwge1xuICAgIGNvbnN0IHNwZWVjaEdsb2JhbCA9IGdsb2JhbFRoaXMgYXMgU3BlZWNoUmVjb2duaXRpb25HbG9iYWw7XG4gICAgcmV0dXJuIHNwZWVjaEdsb2JhbC5TcGVlY2hSZWNvZ25pdGlvbiA/PyBzcGVlY2hHbG9iYWwud2Via2l0U3BlZWNoUmVjb2duaXRpb24gPz8gbnVsbDtcbiAgfVxufVxuIl19
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { Injectable } from '@angular/core';
|
|
2
|
+
import { BehaviorSubject } from 'rxjs';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
export class TextToSpeechService {
|
|
5
|
+
utterance = null;
|
|
6
|
+
lastText = '';
|
|
7
|
+
lastOptions = { lang: 'pt-BR', rate: 1 };
|
|
8
|
+
speakingSubject = new BehaviorSubject(false);
|
|
9
|
+
pausedSubject = new BehaviorSubject(false);
|
|
10
|
+
speaking$ = this.speakingSubject.asObservable();
|
|
11
|
+
paused$ = this.pausedSubject.asObservable();
|
|
12
|
+
get supported() {
|
|
13
|
+
const speechGlobal = globalThis;
|
|
14
|
+
return !!speechGlobal.speechSynthesis && !!speechGlobal.SpeechSynthesisUtterance;
|
|
15
|
+
}
|
|
16
|
+
get hasSpokenText() {
|
|
17
|
+
return this.lastText.trim().length > 0;
|
|
18
|
+
}
|
|
19
|
+
speak(text, options) {
|
|
20
|
+
const normalizedText = text.trim();
|
|
21
|
+
if (!this.supported || !normalizedText) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
this.cancel();
|
|
25
|
+
const speechGlobal = globalThis;
|
|
26
|
+
const UtteranceConstructor = speechGlobal.SpeechSynthesisUtterance;
|
|
27
|
+
const speechSynthesisApi = speechGlobal.speechSynthesis;
|
|
28
|
+
if (!UtteranceConstructor || !speechSynthesisApi) {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
const utterance = new UtteranceConstructor(normalizedText);
|
|
32
|
+
utterance.lang = options.lang;
|
|
33
|
+
utterance.rate = options.rate;
|
|
34
|
+
utterance.onend = () => this.resetState();
|
|
35
|
+
utterance.onerror = () => this.resetState();
|
|
36
|
+
utterance.onpause = () => {
|
|
37
|
+
this.pausedSubject.next(true);
|
|
38
|
+
};
|
|
39
|
+
utterance.onresume = () => {
|
|
40
|
+
this.pausedSubject.next(false);
|
|
41
|
+
this.speakingSubject.next(true);
|
|
42
|
+
};
|
|
43
|
+
this.utterance = utterance;
|
|
44
|
+
this.lastText = normalizedText;
|
|
45
|
+
this.lastOptions = options;
|
|
46
|
+
this.speakingSubject.next(true);
|
|
47
|
+
this.pausedSubject.next(false);
|
|
48
|
+
speechSynthesisApi.speak(utterance);
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
pause() {
|
|
52
|
+
if (!this.supported || !this.speakingSubject.value) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
globalThis.speechSynthesis?.pause();
|
|
56
|
+
this.pausedSubject.next(true);
|
|
57
|
+
}
|
|
58
|
+
resume() {
|
|
59
|
+
if (!this.supported || !this.pausedSubject.value) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
globalThis.speechSynthesis?.resume();
|
|
63
|
+
this.pausedSubject.next(false);
|
|
64
|
+
this.speakingSubject.next(true);
|
|
65
|
+
}
|
|
66
|
+
restart(text = this.lastText, options = this.lastOptions) {
|
|
67
|
+
return this.speak(text, options);
|
|
68
|
+
}
|
|
69
|
+
cancel() {
|
|
70
|
+
if (!this.supported) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
globalThis.speechSynthesis?.cancel();
|
|
74
|
+
this.resetState();
|
|
75
|
+
}
|
|
76
|
+
resetState() {
|
|
77
|
+
this.utterance = null;
|
|
78
|
+
this.speakingSubject.next(false);
|
|
79
|
+
this.pausedSubject.next(false);
|
|
80
|
+
}
|
|
81
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TextToSpeechService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
82
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TextToSpeechService, providedIn: 'root' });
|
|
83
|
+
}
|
|
84
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TextToSpeechService, decorators: [{
|
|
85
|
+
type: Injectable,
|
|
86
|
+
args: [{ providedIn: 'root' }]
|
|
87
|
+
}] });
|
|
88
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGV4dC10by1zcGVlY2guc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL2xpYi9zcmMvZmVhdHVyZXMvc3BlZWNoLXJlY29nbml0aW9uL3NlcnZpY2VzL3RleHQtdG8tc3BlZWNoLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sTUFBTSxDQUFDOztBQWlCdkMsTUFBTSxPQUFPLG1CQUFtQjtJQUN0QixTQUFTLEdBQTJDLElBQUksQ0FBQztJQUN6RCxRQUFRLEdBQUcsRUFBRSxDQUFDO0lBQ2QsV0FBVyxHQUE2QixFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDO0lBRTFELGVBQWUsR0FBRyxJQUFJLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUM3QyxhQUFhLEdBQUcsSUFBSSxlQUFlLENBQUMsS0FBSyxDQUFDLENBQUM7SUFFbkQsU0FBUyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsWUFBWSxFQUFFLENBQUM7SUFDaEQsT0FBTyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsWUFBWSxFQUFFLENBQUM7SUFFckQsSUFBSSxTQUFTO1FBQ1gsTUFBTSxZQUFZLEdBQUcsVUFBbUMsQ0FBQztRQUN6RCxPQUFPLENBQUMsQ0FBQyxZQUFZLENBQUMsZUFBZSxJQUFJLENBQUMsQ0FBQyxZQUFZLENBQUMsd0JBQXdCLENBQUM7SUFDbkYsQ0FBQztJQUVELElBQUksYUFBYTtRQUNmLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBQ3pDLENBQUM7SUFFRCxLQUFLLENBQUMsSUFBWSxFQUFFLE9BQWlDO1FBQ25ELE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQyxJQUFJLEVB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QixPQUFPO1FBQ1QsQ0FBQztRQUVBLFVBQW9DLENBQUMsZUFBZSxFQUFFLE1BQU0sRUFBRSxDQUFDO1FBQ2hFLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztJQUNwQixDQUFDO0lBRU8sVUFBVTtRQUNoQixJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztRQUN0QixJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNqQyxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNqQyxDQUFDO3dHQWhHVSxtQkFBbUI7NEdBQW5CLG1CQUFtQixjQUROLE1BQU07OzRGQUNuQixtQkFBbUI7a0JBRC9CLFVBQVU7bUJBQUMsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5cbnR5cGUgQnJvd3NlclNwZWVjaFN5bnRoZXNpc1V0dGVyYW5jZSA9IFNwZWVjaFN5bnRoZXNpc1V0dGVyYW5jZTtcbnR5cGUgQnJvd3NlclNwZWVjaFN5bnRoZXNpcyA9IFNwZWVjaFN5bnRoZXNpcztcbnR5cGUgQnJvd3NlclNwZWVjaFN5bnRoZXNpc1V0dGVyYW5jZUNvbnN0cnVjdG9yID0gdHlwZW9mIFNwZWVjaFN5bnRoZXNpc1V0dGVyYW5jZTtcblxudHlwZSBTcGVlY2hTeW50aGVzaXNHbG9iYWwgPSB0eXBlb2YgZ2xvYmFsVGhpcyAmIHtcbiAgU3BlZWNoU3ludGhlc2lzVXR0ZXJhbmNlPzogQnJvd3NlclNwZWVjaFN5bnRoZXNpc1V0dGVyYW5jZUNvbnN0cnVjdG9yO1xuICBzcGVlY2hTeW50aGVzaXM/OiBCcm93c2VyU3BlZWNoU3ludGhlc2lzO1xufTtcblxuZXhwb3J0IHR5cGUgVGV4dFRvU3BlZWNoU3BlYWtPcHRpb25zID0ge1xuICBsYW5nOiBzdHJpbmc7XG4gIHJhdGU6IG51bWJlcjtcbn07XG5cbkBJbmplY3RhYmxlKHsgcHJvdmlkZWRJbjogJ3Jvb3QnIH0pXG5leHBvcnQgY2xhc3MgVGV4dFRvU3BlZWNoU2VydmljZSB7XG4gIHByaXZhdGUgdXR0ZXJhbmNlOiBCcm93c2VyU3BlZWNoU3ludGhlc2lzVXR0ZXJhbmNlIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgbGFzdFRleHQgPSAnJztcbiAgcHJpdmF0ZSBsYXN0T3B0aW9uczogVGV4dFRvU3BlZWNoU3BlYWtPcHRpb25zID0geyBsYW5nOiAncHQtQlInLCByYXRlOiAxIH07XG5cbiAgcHJpdmF0ZSByZWFkb25seSBzcGVha2luZ1N1YmplY3QgPSBuZXcgQmVoYXZpb3JTdWJqZWN0KGZhbHNlKTtcbiAgcHJpdmF0ZSByZWFkb25seSBwYXVzZWRTdWJqZWN0ID0gbmV3IEJlaGF2aW9yU3ViamVjdChmYWxzZSk7XG5cbiAgcmVhZG9ubHkgc3BlYWtpbmckID0gdGhpcy5zcGVha2luZ1N1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG4gIHJlYWRvbmx5IHBhdXNlZCQgPSB0aGlzLnBhdXNlZFN1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG5cbiAgZ2V0IHN1cHBvcnRlZCgpOiBib29sZWFuIHtcbiAgICBjb25zdCBzcGVlY2hHbG9iYWwgPSBnbG9iYWxUaGlzIGFzIFNwZWVjaFN5bnRoZXNpc0dsb2JhbDtcbiAgICByZXR1cm4gISFzcGVlY2hHbG9iYWwuc3BlZWNoU3ludGhlc2lzICYmICEhc3BlZWNoR2xvYmFsLlNwZWVjaFN5bnRoZXNpc1V0dGVyYW5jZTtcbiAgfVxuXG4gIGdldCBoYXNTcG9rZW5UZXh0KCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmxhc3RUZXh0LnRyaW0oKS5sZW5ndGggPiAwO1xuICB9XG5cbiAgc3BlYWsodGV4dDogc3RyaW5nLCBvcHRpb25zOiBUZXh0VG9TcGVlY2hTcGVha09wdGlvbnMpOiBib29sZWFuIHtcbiAgICBjb25zdCBub3JtYWxpemVkVGV4dCA9IHRleHQudHJpbSgpO1xuXG4gICAgaWYgKCF0aGlzLnN1cHBvcnRlZCB8fCAhbm9ybWFsaXplZFRleHQpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICB0aGlzLmNhbmNlbCgpO1xuXG4gICAgY29uc3Qgc3BlZWNoR2xvYmFsID0gZ2xvYmFsVGhpcyBhcyBTcGVlY2hTeW50aGVzaXNHbG9iYWw7XG4gICAgY29uc3QgVXR0ZXJhbmNlQ29uc3RydWN0b3IgPSBzcGVlY2hHbG9iYWwuU3BlZWNoU3ludGhlc2lzVXR0ZXJhbmNlO1xuICAgIGNvbnN0IHNwZWVjaFN5bnRoZXNpc0FwaSA9IHNwZWVjaEdsb2JhbC5zcGVlY2hTeW50aGVzaXM7XG5cbiAgICBpZiAoIVV0dGVyYW5jZUNvbnN0cnVjdG9yIHx8ICFzcGVlY2hTeW50aGVzaXNBcGkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBjb25zdCB1dHRlcmFuY2UgPSBuZXcgVXR0ZXJhbmNlQ29uc3RydWN0b3Iobm9ybWFsaXplZFRleHQpO1xuICAgIHV0dGVyYW5jZS5sYW5nID0gb3B0aW9ucy5sYW5nO1xuICAgIHV0dGVyYW5jZS5yYXRlID0gb3B0aW9ucy5yYXRlO1xuICAgIHV0dGVyYW5jZS5vbmVuZCA9ICgpID0+IHRoaXMucmVzZXRTdGF0ZSgpO1xuICAgIHV0dGVyYW5jZS5vbmVycm9yID0gKCkgPT4gdGhpcy5yZXNldFN0YXRlKCk7XG4gICAgdXR0ZXJhbmNlLm9ucGF1c2UgPSAoKSA9PiB7XG4gICAgICB0aGlzLnBhdXNlZFN1YmplY3QubmV4dCh0cnVlKTtcbiAgICB9O1xuICAgIHV0dGVyYW5jZS5vbnJlc3VtZSA9ICgpID0+IHtcbiAgICAgIHRoaXMucGF1c2VkU3ViamVjdC5uZXh0KGZhbHNlKTtcbiAgICAgIHRoaXMuc3BlYWtpbmdTdWJqZWN0Lm5leHQodHJ1ZSk7XG4gICAgfTtcblxuICAgIHRoaXMudXR0ZXJhbmNlID0gdXR0ZXJhbmNlO1xuICAgIHRoaXMubGFzdFRleHQgPSBub3JtYWxpemVkVGV4dDtcbiAgICB0aGlzLmxhc3RPcHRpb25zID0gb3B0aW9ucztcbiAgICB0aGlzLnNwZWFraW5nU3ViamVjdC5uZXh0KHRydWUpO1xuICAgIHRoaXMucGF1c2VkU3ViamVjdC5uZXh0KGZhbHNlKTtcbiAgICBzcGVlY2hTeW50aGVzaXNBcGkuc3BlYWsodXR0ZXJhbmNlKTtcblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcGF1c2UoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnN1cHBvcnRlZCB8fCAhdGhpcy5zcGVha2luZ1N1YmplY3QudmFsdWUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAoZ2xvYmFsVGhpcyBhcyBTcGVlY2hTeW50aGVzaXNHbG9iYWwpLnNwZWVjaFN5bnRoZXNpcz8ucGF1c2UoKTtcbiAgICB0aGlzLnBhdXNlZFN1YmplY3QubmV4dCh0cnVlKTtcbiAgfVxuXG4gIHJlc3VtZSgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuc3VwcG9ydGVkIHx8ICF0aGlzLnBhdXNlZFN1YmplY3QudmFsdWUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAoZ2xvYmFsVGhpcyBhcyBTcGVlY2hTeW50aGVzaXNHbG9iYWwpLnNwZWVjaFN5bnRoZXNpcz8ucmVzdW1lKCk7XG4gICAgdGhpcy5wYXVzZWRTdWJqZWN0Lm5leHQoZmFsc2UpO1xuICAgIHRoaXMuc3BlYWtpbmdTdWJqZWN0Lm5leHQodHJ1ZSk7XG4gIH1cblxuICByZXN0YXJ0KHRleHQgPSB0aGlzLmxhc3RUZXh0LCBvcHRpb25zID0gdGhpcy5sYXN0T3B0aW9ucyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnNwZWFrKHRleHQsIG9wdGlvbnMpO1xuICB9XG5cbiAgY2FuY2VsKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5zdXBwb3J0ZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAoZ2xvYmFsVGhpcyBhcyBTcGVlY2hTeW50aGVzaXNHbG9iYWwpLnNwZWVjaFN5bnRoZXNpcz8uY2FuY2VsKCk7XG4gICAgdGhpcy5yZXNldFN0YXRlKCk7XG4gIH1cblxuICBwcml2YXRlIHJlc2V0U3RhdGUoKTogdm9pZCB7XG4gICAgdGhpcy51dHRlcmFuY2UgPSBudWxsO1xuICAgIHRoaXMuc3BlYWtpbmdTdWJqZWN0Lm5leHQoZmFsc2UpO1xuICAgIHRoaXMucGF1c2VkU3ViamVjdC5uZXh0KGZhbHNlKTtcbiAgfVxufVxuIl19
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import { CommonModule } from '@angular/common';
|
|
2
|
+
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, Input, Output, ViewEncapsulation, inject } from '@angular/core';
|
|
3
|
+
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
4
|
+
import { FormsModule } from '@angular/forms';
|
|
5
|
+
import { TranslateModule, TranslateService } from '@ngx-translate/core';
|
|
6
|
+
import { resolveTranslatableText } from '../../core/utils/i18n.util';
|
|
7
|
+
import { SpeechRecognitionService } from './services/speech-recognition.service';
|
|
8
|
+
import { TextToSpeechService } from './services/text-to-speech.service';
|
|
9
|
+
import * as i0 from "@angular/core";
|
|
10
|
+
import * as i1 from "@angular/common";
|
|
11
|
+
import * as i2 from "@angular/forms";
|
|
12
|
+
import * as i3 from "@ngx-translate/core";
|
|
13
|
+
const SPEECH_RECOGNITION_PLACEHOLDER_KEY = 'platform.datacore.speech_recognition.placeholder';
|
|
14
|
+
const DEFAULT_SPEECH_SILENCE_TIMEOUT_MS = 3000;
|
|
15
|
+
const VOICE_RATE_SLOW = 0.75;
|
|
16
|
+
const VOICE_RATE_NORMAL = 1;
|
|
17
|
+
const VOICE_RATE_FAST = 1.25;
|
|
18
|
+
const VOICE_RATE_FASTER = 1.5;
|
|
19
|
+
export class SpeechRecognitionComponent {
|
|
20
|
+
cdr = inject(ChangeDetectorRef);
|
|
21
|
+
translate = inject(TranslateService);
|
|
22
|
+
speechRecognitionService = inject(SpeechRecognitionService);
|
|
23
|
+
textToSpeechService = inject(TextToSpeechService);
|
|
24
|
+
baseText = '';
|
|
25
|
+
transcript = '';
|
|
26
|
+
textAreaElement;
|
|
27
|
+
keepContext = false;
|
|
28
|
+
speechRecognitionPlaceholder = '';
|
|
29
|
+
silenceTimeoutMs = DEFAULT_SPEECH_SILENCE_TIMEOUT_MS;
|
|
30
|
+
enableTextToSpeech = true;
|
|
31
|
+
recognizedText = new EventEmitter();
|
|
32
|
+
permissionDenied = new EventEmitter();
|
|
33
|
+
listeningChange = new EventEmitter();
|
|
34
|
+
previewText = '';
|
|
35
|
+
listening = false;
|
|
36
|
+
permissionDeniedState = false;
|
|
37
|
+
speaking = false;
|
|
38
|
+
paused = false;
|
|
39
|
+
voiceRate = VOICE_RATE_NORMAL;
|
|
40
|
+
voiceRates = [VOICE_RATE_SLOW, VOICE_RATE_NORMAL, VOICE_RATE_FAST, VOICE_RATE_FASTER];
|
|
41
|
+
constructor() {
|
|
42
|
+
this.speechRecognitionService.transcript$
|
|
43
|
+
.pipe(takeUntilDestroyed())
|
|
44
|
+
.subscribe((transcript) => {
|
|
45
|
+
this.transcript = transcript;
|
|
46
|
+
this.previewText = this.combineRecognizedText(this.baseText, transcript);
|
|
47
|
+
this.recognizedText.emit(this.previewText);
|
|
48
|
+
this.cdr.markForCheck();
|
|
49
|
+
});
|
|
50
|
+
this.speechRecognitionService.permissionDenied$
|
|
51
|
+
.pipe(takeUntilDestroyed())
|
|
52
|
+
.subscribe(() => {
|
|
53
|
+
this.permissionDeniedState = true;
|
|
54
|
+
this.permissionDenied.emit();
|
|
55
|
+
this.cdr.markForCheck();
|
|
56
|
+
});
|
|
57
|
+
this.speechRecognitionService.listening$
|
|
58
|
+
.pipe(takeUntilDestroyed())
|
|
59
|
+
.subscribe((listening) => {
|
|
60
|
+
this.listening = listening;
|
|
61
|
+
this.listeningChange.emit(listening);
|
|
62
|
+
this.cdr.markForCheck();
|
|
63
|
+
});
|
|
64
|
+
this.textToSpeechService.speaking$
|
|
65
|
+
.pipe(takeUntilDestroyed())
|
|
66
|
+
.subscribe((speaking) => {
|
|
67
|
+
this.speaking = speaking;
|
|
68
|
+
this.cdr.markForCheck();
|
|
69
|
+
});
|
|
70
|
+
this.textToSpeechService.paused$
|
|
71
|
+
.pipe(takeUntilDestroyed())
|
|
72
|
+
.subscribe((paused) => {
|
|
73
|
+
this.paused = paused;
|
|
74
|
+
this.cdr.markForCheck();
|
|
75
|
+
});
|
|
76
|
+
this.translate.onLangChange.pipe(takeUntilDestroyed()).subscribe(() => this.cdr.markForCheck());
|
|
77
|
+
}
|
|
78
|
+
ngOnDestroy() {
|
|
79
|
+
this.speechRecognitionService.abort();
|
|
80
|
+
this.textToSpeechService.cancel();
|
|
81
|
+
}
|
|
82
|
+
get canListen() {
|
|
83
|
+
return this.recognitionSupported && !!this.getTextArea();
|
|
84
|
+
}
|
|
85
|
+
get canApply() {
|
|
86
|
+
return !!this.getTextArea() && this.previewText.trim().length > 0;
|
|
87
|
+
}
|
|
88
|
+
get canSpeak() {
|
|
89
|
+
return this.enableTextToSpeech
|
|
90
|
+
&& this.textToSpeechService.supported
|
|
91
|
+
&& this.resolveSpeechSourceText().trim().length > 0;
|
|
92
|
+
}
|
|
93
|
+
get recognitionSupported() {
|
|
94
|
+
return this.speechRecognitionService.supported;
|
|
95
|
+
}
|
|
96
|
+
get pauseActionLabel() {
|
|
97
|
+
return this.paused
|
|
98
|
+
? this.translate.instant('platform.datacore.speech_recognition.resume')
|
|
99
|
+
: this.translate.instant('platform.datacore.speech_recognition.pause');
|
|
100
|
+
}
|
|
101
|
+
get previewPlaceholder() {
|
|
102
|
+
return resolveTranslatableText(this.translate, this.speechRecognitionPlaceholder, SPEECH_RECOGNITION_PLACEHOLDER_KEY);
|
|
103
|
+
}
|
|
104
|
+
get previewValue() {
|
|
105
|
+
return this.previewText.trim()
|
|
106
|
+
|| this.previewPlaceholder
|
|
107
|
+
|| this.translate.instant('platform.datacore.speech_recognition.empty_preview');
|
|
108
|
+
}
|
|
109
|
+
get statusMessage() {
|
|
110
|
+
if (!this.recognitionSupported) {
|
|
111
|
+
return this.translate.instant('platform.datacore.speech_recognition.unsupported');
|
|
112
|
+
}
|
|
113
|
+
if (!this.getTextArea()) {
|
|
114
|
+
return this.translate.instant('platform.datacore.speech_recognition.missing_target');
|
|
115
|
+
}
|
|
116
|
+
if (this.permissionDeniedState) {
|
|
117
|
+
return this.translate.instant('platform.datacore.speech_recognition.permission_denied');
|
|
118
|
+
}
|
|
119
|
+
if (this.listening) {
|
|
120
|
+
return this.translate.instant('platform.datacore.speech_recognition.listening');
|
|
121
|
+
}
|
|
122
|
+
return this.translate.instant('platform.datacore.speech_recognition.idle');
|
|
123
|
+
}
|
|
124
|
+
toggleListening() {
|
|
125
|
+
if (this.listening) {
|
|
126
|
+
this.speechRecognitionService.stop();
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
if (!this.canListen) {
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
this.permissionDeniedState = false;
|
|
133
|
+
this.baseText = this.keepContext ? this.readCurrentText() : '';
|
|
134
|
+
this.transcript = '';
|
|
135
|
+
this.previewText = this.baseText;
|
|
136
|
+
this.speechRecognitionService.start({
|
|
137
|
+
lang: resolveSpeechLocale(this.translate.currentLang),
|
|
138
|
+
silenceTimeoutMs: Math.max(0, this.silenceTimeoutMs)
|
|
139
|
+
});
|
|
140
|
+
this.cdr.markForCheck();
|
|
141
|
+
}
|
|
142
|
+
discardRecognition() {
|
|
143
|
+
this.speechRecognitionService.stop();
|
|
144
|
+
this.transcript = '';
|
|
145
|
+
this.baseText = this.keepContext ? this.readCurrentText() : '';
|
|
146
|
+
this.previewText = this.keepContext ? this.baseText : '';
|
|
147
|
+
this.cdr.markForCheck();
|
|
148
|
+
}
|
|
149
|
+
applyRecognizedText() {
|
|
150
|
+
const textArea = this.getTextArea();
|
|
151
|
+
const value = this.previewText.trim();
|
|
152
|
+
if (!textArea || !value) {
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
textArea.value = value;
|
|
156
|
+
textArea.dispatchEvent(new Event('input', { bubbles: true }));
|
|
157
|
+
textArea.dispatchEvent(new Event('change', { bubbles: true }));
|
|
158
|
+
this.speechRecognitionService.stop();
|
|
159
|
+
}
|
|
160
|
+
playSpeech() {
|
|
161
|
+
const text = this.resolveSpeechSourceText().trim();
|
|
162
|
+
if (!text) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
this.textToSpeechService.speak(text, {
|
|
166
|
+
lang: resolveSpeechLocale(this.translate.currentLang),
|
|
167
|
+
rate: this.voiceRate
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
togglePause() {
|
|
171
|
+
if (this.paused) {
|
|
172
|
+
this.textToSpeechService.resume();
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
this.textToSpeechService.pause();
|
|
176
|
+
}
|
|
177
|
+
restartSpeech() {
|
|
178
|
+
const text = this.resolveSpeechSourceText().trim();
|
|
179
|
+
if (!text) {
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
this.textToSpeechService.restart(text, {
|
|
183
|
+
lang: resolveSpeechLocale(this.translate.currentLang),
|
|
184
|
+
rate: this.voiceRate
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
updateVoiceRate(value) {
|
|
188
|
+
const parsedValue = typeof value === 'string' ? Number(value) : value;
|
|
189
|
+
this.voiceRate = Number.isFinite(parsedValue) && parsedValue > 0 ? parsedValue : 1;
|
|
190
|
+
}
|
|
191
|
+
combineRecognizedText(baseText, transcript) {
|
|
192
|
+
const parts = [baseText.trim(), transcript.trim()].filter(Boolean);
|
|
193
|
+
return parts.join(' ').trim();
|
|
194
|
+
}
|
|
195
|
+
readCurrentText() {
|
|
196
|
+
return this.getTextArea()?.value?.trim() ?? '';
|
|
197
|
+
}
|
|
198
|
+
resolveSpeechSourceText() {
|
|
199
|
+
return this.previewText.trim() || this.readCurrentText();
|
|
200
|
+
}
|
|
201
|
+
getTextArea() {
|
|
202
|
+
if (!this.textAreaElement) {
|
|
203
|
+
return null;
|
|
204
|
+
}
|
|
205
|
+
if (this.textAreaElement instanceof ElementRef) {
|
|
206
|
+
return this.textAreaElement.nativeElement;
|
|
207
|
+
}
|
|
208
|
+
return this.textAreaElement;
|
|
209
|
+
}
|
|
210
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SpeechRecognitionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
211
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: SpeechRecognitionComponent, isStandalone: true, selector: "sdc-speech-recognition", inputs: { textAreaElement: "textAreaElement", keepContext: "keepContext", speechRecognitionPlaceholder: "speechRecognitionPlaceholder", silenceTimeoutMs: "silenceTimeoutMs", enableTextToSpeech: "enableTextToSpeech" }, outputs: { recognizedText: "recognizedText", permissionDenied: "permissionDenied", listeningChange: "listeningChange" }, providers: [SpeechRecognitionService, TextToSpeechService], ngImport: i0, template: "<section\n class=\"sdc-speech-recognition\"\n [class.sdc-speech-recognition--unsupported]=\"!recognitionSupported\"\n>\n <div class=\"sdc-speech-recognition__toolbar\">\n <button\n class=\"sdc-speech-recognition__button sdc-speech-recognition__button--primary\"\n type=\"button\"\n [disabled]=\"!canListen\"\n (click)=\"toggleListening()\"\n >\n {{\n listening\n ? ('platform.datacore.speech_recognition.stop' | translate)\n : ('platform.datacore.speech_recognition.listen' | translate)\n }}\n </button>\n\n <button\n class=\"sdc-speech-recognition__button\"\n type=\"button\"\n [disabled]=\"!previewText.trim()\"\n (click)=\"discardRecognition()\"\n >\n {{ 'platform.datacore.speech_recognition.discard' | translate }}\n </button>\n\n <button\n class=\"sdc-speech-recognition__button\"\n type=\"button\"\n [disabled]=\"!canApply\"\n (click)=\"applyRecognizedText()\"\n >\n {{ 'platform.datacore.speech_recognition.apply' | translate }}\n </button>\n </div>\n\n <div class=\"sdc-speech-recognition__preview\">\n <span class=\"sdc-speech-recognition__label\">\n {{ 'platform.datacore.speech_recognition.preview' | translate }}\n </span>\n <div class=\"sdc-speech-recognition__previewValue\">\n {{ previewValue }}\n </div>\n </div>\n\n <div *ngIf=\"enableTextToSpeech\" class=\"sdc-speech-recognition__tts\">\n <button\n class=\"sdc-speech-recognition__button\"\n type=\"button\"\n [disabled]=\"!canSpeak\"\n (click)=\"playSpeech()\"\n >\n {{ 'platform.datacore.speech_recognition.play' | translate }}\n </button>\n\n <button\n class=\"sdc-speech-recognition__button\"\n type=\"button\"\n [disabled]=\"!speaking && !paused\"\n (click)=\"togglePause()\"\n >\n {{ pauseActionLabel }}\n </button>\n\n <button\n class=\"sdc-speech-recognition__button\"\n type=\"button\"\n [disabled]=\"!canSpeak\"\n (click)=\"restartSpeech()\"\n >\n {{ 'platform.datacore.speech_recognition.restart' | translate }}\n </button>\n\n <label class=\"sdc-speech-recognition__speed\">\n <span>{{ 'platform.datacore.speech_recognition.speed' | translate }}</span>\n <select\n class=\"sdc-speech-recognition__select\"\n [ngModel]=\"voiceRate\"\n (ngModelChange)=\"updateVoiceRate($event)\"\n >\n <option *ngFor=\"let rate of voiceRates\" [ngValue]=\"rate\">\n {{ rate }}x\n </option>\n </select>\n </label>\n </div>\n\n <p class=\"sdc-speech-recognition__status\">\n {{ statusMessage }}\n </p>\n</section>\n", styles: [":host{display:block}.sdc-speech-recognition{background:var(--sdc-surface-bg, #ffffff);border:1px solid var(--sdc-surface-border-color, #dedce5);border-radius:1rem;display:flex;flex-direction:column;gap:1rem;padding:1rem}.sdc-speech-recognition--unsupported{opacity:.72}.sdc-speech-recognition__toolbar,.sdc-speech-recognition__tts{display:flex;flex-wrap:wrap;gap:.75rem}.sdc-speech-recognition__button,.sdc-speech-recognition__select{background:var(--sdc-button-bg, #eceeef);border:1px solid var(--sdc-formfield-default-border, #cccccc);border-radius:.5rem;color:var(--sdc-text-default, #111827);font:inherit;min-height:2.5rem;padding:.625rem .9rem;transition:background-color var(--sdc-transition-fast, .18s ease),border-color var(--sdc-transition-fast, .18s ease),box-shadow var(--sdc-transition-fast, .18s ease)}.sdc-speech-recognition__button{cursor:pointer}.sdc-speech-recognition__button:disabled{cursor:default;opacity:.5}.sdc-speech-recognition__button:not(:disabled):hover,.sdc-speech-recognition__button:not(:disabled):focus-visible{background:var(--sdc-button-bg-hover, #e6e6e6);box-shadow:var(--sdc-focus-ring, 0 0 0 3px rgba(0, 123, 255, .25));outline:none}.sdc-speech-recognition__button--primary{background:var(--p-primary-color, #428bca);border-color:var(--p-primary-color, #428bca);color:#fff}.sdc-speech-recognition__preview{display:flex;flex-direction:column;gap:.4rem}.sdc-speech-recognition__label{color:var(--sdc-text-default, #111827);font-size:.85rem;font-weight:700}.sdc-speech-recognition__previewValue{background:#11182708;border:1px dashed var(--sdc-surface-border-color, #dedce5);border-radius:.75rem;line-height:1.5;min-height:5.5rem;padding:.9rem;white-space:pre-wrap;word-break:break-word}.sdc-speech-recognition__speed{align-items:center;color:var(--sdc-text-muted, #6b7280);display:inline-flex;gap:.5rem}.sdc-speech-recognition__select{min-width:5.5rem}.sdc-speech-recognition__status{color:var(--sdc-text-muted, #6b7280);font-size:.85rem;margin:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
212
|
+
}
|
|
213
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SpeechRecognitionComponent, decorators: [{
|
|
214
|
+
type: Component,
|
|
215
|
+
args: [{ selector: 'sdc-speech-recognition', standalone: true, imports: [CommonModule, FormsModule, TranslateModule], providers: [SpeechRecognitionService, TextToSpeechService], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.Emulated, template: "<section\n class=\"sdc-speech-recognition\"\n [class.sdc-speech-recognition--unsupported]=\"!recognitionSupported\"\n>\n <div class=\"sdc-speech-recognition__toolbar\">\n <button\n class=\"sdc-speech-recognition__button sdc-speech-recognition__button--primary\"\n type=\"button\"\n [disabled]=\"!canListen\"\n (click)=\"toggleListening()\"\n >\n {{\n listening\n ? ('platform.datacore.speech_recognition.stop' | translate)\n : ('platform.datacore.speech_recognition.listen' | translate)\n }}\n </button>\n\n <button\n class=\"sdc-speech-recognition__button\"\n type=\"button\"\n [disabled]=\"!previewText.trim()\"\n (click)=\"discardRecognition()\"\n >\n {{ 'platform.datacore.speech_recognition.discard' | translate }}\n </button>\n\n <button\n class=\"sdc-speech-recognition__button\"\n type=\"button\"\n [disabled]=\"!canApply\"\n (click)=\"applyRecognizedText()\"\n >\n {{ 'platform.datacore.speech_recognition.apply' | translate }}\n </button>\n </div>\n\n <div class=\"sdc-speech-recognition__preview\">\n <span class=\"sdc-speech-recognition__label\">\n {{ 'platform.datacore.speech_recognition.preview' | translate }}\n </span>\n <div class=\"sdc-speech-recognition__previewValue\">\n {{ previewValue }}\n </div>\n </div>\n\n <div *ngIf=\"enableTextToSpeech\" class=\"sdc-speech-recognition__tts\">\n <button\n class=\"sdc-speech-recognition__button\"\n type=\"button\"\n [disabled]=\"!canSpeak\"\n (click)=\"playSpeech()\"\n >\n {{ 'platform.datacore.speech_recognition.play' | translate }}\n </button>\n\n <button\n class=\"sdc-speech-recognition__button\"\n type=\"button\"\n [disabled]=\"!speaking && !paused\"\n (click)=\"togglePause()\"\n >\n {{ pauseActionLabel }}\n </button>\n\n <button\n class=\"sdc-speech-recognition__button\"\n type=\"button\"\n [disabled]=\"!canSpeak\"\n (click)=\"restartSpeech()\"\n >\n {{ 'platform.datacore.speech_recognition.restart' | translate }}\n </button>\n\n <label class=\"sdc-speech-recognition__speed\">\n <span>{{ 'platform.datacore.speech_recognition.speed' | translate }}</span>\n <select\n class=\"sdc-speech-recognition__select\"\n [ngModel]=\"voiceRate\"\n (ngModelChange)=\"updateVoiceRate($event)\"\n >\n <option *ngFor=\"let rate of voiceRates\" [ngValue]=\"rate\">\n {{ rate }}x\n </option>\n </select>\n </label>\n </div>\n\n <p class=\"sdc-speech-recognition__status\">\n {{ statusMessage }}\n </p>\n</section>\n", styles: [":host{display:block}.sdc-speech-recognition{background:var(--sdc-surface-bg, #ffffff);border:1px solid var(--sdc-surface-border-color, #dedce5);border-radius:1rem;display:flex;flex-direction:column;gap:1rem;padding:1rem}.sdc-speech-recognition--unsupported{opacity:.72}.sdc-speech-recognition__toolbar,.sdc-speech-recognition__tts{display:flex;flex-wrap:wrap;gap:.75rem}.sdc-speech-recognition__button,.sdc-speech-recognition__select{background:var(--sdc-button-bg, #eceeef);border:1px solid var(--sdc-formfield-default-border, #cccccc);border-radius:.5rem;color:var(--sdc-text-default, #111827);font:inherit;min-height:2.5rem;padding:.625rem .9rem;transition:background-color var(--sdc-transition-fast, .18s ease),border-color var(--sdc-transition-fast, .18s ease),box-shadow var(--sdc-transition-fast, .18s ease)}.sdc-speech-recognition__button{cursor:pointer}.sdc-speech-recognition__button:disabled{cursor:default;opacity:.5}.sdc-speech-recognition__button:not(:disabled):hover,.sdc-speech-recognition__button:not(:disabled):focus-visible{background:var(--sdc-button-bg-hover, #e6e6e6);box-shadow:var(--sdc-focus-ring, 0 0 0 3px rgba(0, 123, 255, .25));outline:none}.sdc-speech-recognition__button--primary{background:var(--p-primary-color, #428bca);border-color:var(--p-primary-color, #428bca);color:#fff}.sdc-speech-recognition__preview{display:flex;flex-direction:column;gap:.4rem}.sdc-speech-recognition__label{color:var(--sdc-text-default, #111827);font-size:.85rem;font-weight:700}.sdc-speech-recognition__previewValue{background:#11182708;border:1px dashed var(--sdc-surface-border-color, #dedce5);border-radius:.75rem;line-height:1.5;min-height:5.5rem;padding:.9rem;white-space:pre-wrap;word-break:break-word}.sdc-speech-recognition__speed{align-items:center;color:var(--sdc-text-muted, #6b7280);display:inline-flex;gap:.5rem}.sdc-speech-recognition__select{min-width:5.5rem}.sdc-speech-recognition__status{color:var(--sdc-text-muted, #6b7280);font-size:.85rem;margin:0}\n"] }]
|
|
216
|
+
}], ctorParameters: () => [], propDecorators: { textAreaElement: [{
|
|
217
|
+
type: Input,
|
|
218
|
+
args: [{ required: true }]
|
|
219
|
+
}], keepContext: [{
|
|
220
|
+
type: Input
|
|
221
|
+
}], speechRecognitionPlaceholder: [{
|
|
222
|
+
type: Input
|
|
223
|
+
}], silenceTimeoutMs: [{
|
|
224
|
+
type: Input
|
|
225
|
+
}], enableTextToSpeech: [{
|
|
226
|
+
type: Input
|
|
227
|
+
}], recognizedText: [{
|
|
228
|
+
type: Output
|
|
229
|
+
}], permissionDenied: [{
|
|
230
|
+
type: Output
|
|
231
|
+
}], listeningChange: [{
|
|
232
|
+
type: Output
|
|
233
|
+
}] } });
|
|
234
|
+
function resolveSpeechLocale(language) {
|
|
235
|
+
if (language === 'en') {
|
|
236
|
+
return 'en-US';
|
|
237
|
+
}
|
|
238
|
+
if (language === 'es-CO') {
|
|
239
|
+
return 'es-CO';
|
|
240
|
+
}
|
|
241
|
+
return 'pt-BR';
|
|
242
|
+
}
|
|
243
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BlZWNoLXJlY29nbml0aW9uLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL2xpYi9zcmMvZmVhdHVyZXMvc3BlZWNoLXJlY29nbml0aW9uL3NwZWVjaC1yZWNvZ25pdGlvbi5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9saWIvc3JjL2ZlYXR1cmVzL3NwZWVjaC1yZWNvZ25pdGlvbi9zcGVlY2gtcmVjb2duaXRpb24uY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFDTCx1QkFBdUIsRUFDdkIsaUJBQWlCLEVBQ2pCLFNBQVMsRUFDVCxVQUFVLEVBQ1YsWUFBWSxFQUNaLEtBQUssRUFFTCxNQUFNLEVBQ04saUJBQWlCLEVBQ2pCLE1BQU0sRUFDUCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0MsT0FBTyxFQUFFLGVBQWUsRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBRXhFLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ3JFLE9BQU8sRUFBRSx3QkFBd0IsRUFBRSxNQUFNLHVDQUF1QyxDQUFDO0FBQ2pGLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLG1DQUFtQyxDQUFDOzs7OztBQUl4RSxNQUFNLGtDQUFrQyxHQUFHLGtEQUFrRCxDQUFDO0FBQzlGLE1BQU0saUNBQWlDLEdBQUcsSUFBSSxDQUFDO0FBQy9DLE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQztBQUM3QixNQUFNLGlCQUFpQixHQUFHLENBQUMsQ0FBQztBQUM1QixNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUM7QUFDN0Is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QUFRLEtBQUssSUFBSSxFQUFFLENBQUM7UUFDdEIsT0FBTyxPQUFPLENBQUM7SUFDakIsQ0FBQztJQUVELElBQUksUUFBUSxLQUFLLE9BQU8sRUFBRSxDQUFDO1FBQ3pCLE9BQU8sT0FBTyxDQUFDO0lBQ2pCLENBQUM7SUFFRCxPQUFPLE9BQU8sQ0FBQztBQUNqQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7XG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIElucHV0LFxuICBPbkRlc3Ryb3ksXG4gIE91dHB1dCxcbiAgVmlld0VuY2Fwc3VsYXRpb24sXG4gIGluamVjdFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IHRha2VVbnRpbERlc3Ryb3llZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUvcnhqcy1pbnRlcm9wJztcbmltcG9ydCB7IEZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgVHJhbnNsYXRlTW9kdWxlLCBUcmFuc2xhdGVTZXJ2aWNlIH0gZnJvbSAnQG5neC10cmFuc2xhdGUvY29yZSc7XG5cbmltcG9ydCB7IHJlc29sdmVUcmFuc2xhdGFibGVUZXh0IH0gZnJvbSAnLi4vLi4vY29yZS91dGlscy9pMThuLnV0aWwnO1xuaW1wb3J0IHsgU3BlZWNoUmVjb2duaXRpb25TZXJ2aWNlIH0gZnJvbSAnLi9zZXJ2aWNlcy9zcGVlY2gtcmVjb2duaXRpb24uc2VydmljZSc7XG5pbXBvcnQgeyBUZXh0VG9TcGVlY2hTZXJ2aWNlIH0gZnJvbSAnLi9zZXJ2aWNlcy90ZXh0LXRvLXNwZWVjaC5zZXJ2aWNlJztcblxudHlwZSBUZXh0QXJlYUxpa2UgPSBIVE1MVGV4dEFyZWFFbGVtZW50IHwgRWxlbWVudFJlZjxIVE1MVGV4dEFyZWFFbGVtZW50PiB8IG51bGwgfCB1bmRlZmluZWQ7XG5cbmNvbnN0IFNQRUVDSF9SRUNPR05JVElPTl9QTEFDRUhPTERFUl9LRVkgPSAncGxhdGZvcm0uZGF0YWNvcmUuc3BlZWNoX3JlY29nbml0aW9uLnBsYWNlaG9sZGVyJztcbmNvbnN0IERFRkFVTFRfU1BFRUNIX1NJTEVOQ0VfVElNRU9VVF9NUyA9IDMwMDA7XG5jb25zdCBWT0lDRV9SQVRFX1NMT1cgPSAwLjc1O1xuY29uc3QgVk9JQ0VfUkFURV9OT1JNQUwgPSAxO1xuY29uc3QgVk9JQ0VfUkFURV9GQVNUID0gMS4yNTtcbmNvbnN0IFZPSUNFX1JBVEVfRkFTVEVSID0gMS41O1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdzZGMtc3BlZWNoLXJlY29nbml0aW9uJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW0NvbW1vbk1vZHVsZSwgRm9ybXNNb2R1bGUsIFRyYW5zbGF0ZU1vZHVsZV0sXG4gIHByb3ZpZGVyczogW1NwZWVjaFJlY29nbml0aW9uU2VydmljZSwgVGV4dFRvU3BlZWNoU2VydmljZV0sXG4gIHRlbXBsYXRlVXJsOiAnLi9zcGVlY2gtcmVjb2duaXRpb24uY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybDogJy4vc3BlZWNoLXJlY29nbml0aW9uLmNvbXBvbmVudC5zY3NzJyxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLkVtdWxhdGVkXG59KVxuZXhwb3J0IGNsYXNzIFNwZWVjaFJlY29nbml0aW9uQ29tcG9uZW50IGltcGxlbWVudHMgT25EZXN0cm95IHtcbiAgcHJpdmF0ZSByZWFkb25seSBjZHIgPSBpbmplY3QoQ2hhbmdlRGV0ZWN0b3JSZWYpO1xuICBwcml2YXRlIHJlYWRvbmx5IHRyYW5zbGF0ZSA9IGluamVjdChUcmFuc2xhdGVTZXJ2aWNlKTtcbiAgcHJpdmF0ZSByZWFkb25seSBzcGVlY2hSZWNvZ25pdGlvblNlcnZpY2UgPSBpbmplY3QoU3BlZWNoUmVjb2duaXRpb25TZXJ2aWNlKTtcbiAgcHJpdmF0ZSByZWFkb25seSB0ZXh0VG9TcGVlY2hTZXJ2aWNlID0gaW5qZWN0KFRleHRUb1NwZWVjaFNlcnZpY2UpO1xuXG4gIHByaXZhdGUgYmFzZVRleHQgPSAnJztcbiAgcHJpdmF0ZSB0cmFuc2NyaXB0ID0gJyc7XG5cbiAgQElucHV0KHsgcmVxdWlyZWQ6IHRydWUgfSkgdGV4dEFyZWFFbGVtZW50ITogVGV4dEFyZWFMaWtlO1xuICBASW5wdXQoKSBrZWVwQ29udGV4dCA9IGZhbHNlO1xuICBASW5wdXQoKSBzcGVlY2hSZWNvZ25pdGlvblBsYWNlaG9sZGVyID0gJyc7XG4gIEBJbnB1dCgpIHNpbGVuY2VUaW1lb3V0TXMgPSBERUZBVUxUX1NQRUVDSF9TSUxFTkNFX1RJTUVPVVRfTVM7XG4gIEBJbnB1dCgpIGVuYWJsZVRleHRUb1NwZWVjaCA9IHRydWU7XG5cbiAgQE91dHB1dCgpIHJlY29nbml6ZWRUZXh0ID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XG4gIEBPdXRwdXQoKSBwZXJtaXNzaW9uRGVuaWVkID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICBAT3V0cHV0KCkgbGlzdGVuaW5nQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxib29sZWFuPigpO1xuXG4gIHByb3RlY3RlZCBwcmV2aWV3VGV4dCA9ICcnO1xuICBwcm90ZWN0ZWQgbGlzdGVuaW5nID0gZmFsc2U7XG4gIHByb3RlY3RlZCBwZXJtaXNzaW9uRGVuaWVkU3RhdGUgPSBmYWxzZTtcbiAgcHJvdGVjdGVkIHNwZWFraW5nID0gZmFsc2U7XG4gIHByb3RlY3RlZCBwYXVzZWQgPSBmYWxzZTtcbiAgcHJvdGVjdGVkIHZvaWNlUmF0ZSA9IFZPSUNFX1JBVEVfTk9STUFMO1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgdm9pY2VSYXRlcyA9IFtWT0lDRV9SQVRFX1NMT1csIFZPSUNFX1JBVEVfTk9STUFMLCBWT0lDRV9SQVRFX0ZBU1QsIFZPSUNFX1JBVEVfRkFTVEVSXTtcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLnNwZWVjaFJlY29nbml0aW9uU2VydmljZS50cmFuc2NyaXB0JFxuICAgICAgLnBpcGUodGFrZVVudGlsRGVzdHJveWVkKCkpXG4gICAgICAuc3Vic2NyaWJlKCh0cmFuc2NyaXB0KSA9PiB7XG4gICAgICAgIHRoaXMudHJhbnNjcmlwdCA9IHRyYW5zY3JpcHQ7XG4gICAgICAgIHRoaXMucHJldmlld1RleHQgPSB0aGlzLmNvbWJpbmVSZWNvZ25pemVkVGV4dCh0aGlzLmJhc2VUZXh0LCB0cmFuc2NyaXB0KTtcbiAgICAgICAgdGhpcy5yZWNvZ25pemVkVGV4dC5lbWl0KHRoaXMucHJldmlld1RleHQpO1xuICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICAgIH0pO1xuXG4gICAgdGhpcy5zcGVlY2hSZWNvZ25pdGlvblNlcnZpY2UucGVybWlzc2lvbkRlbmllZCRcbiAgICAgIC5waXBlKHRha2VVbnRpbERlc3Ryb3llZCgpKVxuICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIHRoaXMucGVybWlzc2lvbkRlbmllZFN0YXRlID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5wZXJtaXNzaW9uRGVuaWVkLmVtaXQoKTtcbiAgICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgICB9KTtcblxuICAgIHRoaXMuc3BlZWNoUmVjb2duaXRpb25TZXJ2aWNlLmxpc3RlbmluZyRcbiAgICAgIC5waXBlKHRha2VVbnRpbERlc3Ryb3llZCgpKVxuICAgICAgLnN1YnNjcmliZSgobGlzdGVuaW5nKSA9PiB7XG4gICAgICAgIHRoaXMubGlzdGVuaW5nID0gbGlzdGVuaW5nO1xuICAgICAgICB0aGlzLmxpc3RlbmluZ0NoYW5nZS5lbWl0KGxpc3RlbmluZyk7XG4gICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgICAgfSk7XG5cbiAgICB0aGlzLnRleHRUb1NwZWVjaFNlcnZpY2Uuc3BlYWtpbmckXG4gICAgICAucGlwZSh0YWtlVW50aWxEZXN0cm95ZWQoKSlcbiAgICAgIC5zdWJzY3JpYmUoKHNwZWFraW5nKSA9PiB7XG4gICAgICAgIHRoaXMuc3BlYWtpbmcgPSBzcGVha2luZztcbiAgICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgICB9KTtcblxuICAgIHRoaXMudGV4dFRvU3BlZWNoU2VydmljZS5wYXVzZWQkXG4gICAgICAucGlwZSh0YWtlVW50aWxEZXN0cm95ZWQoKSlcbiAgICAgIC5zdWJzY3JpYmUoKHBhdXNlZCkgPT4ge1xuICAgICAgICB0aGlzLnBhdXNlZCA9IHBhdXNlZDtcbiAgICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgICB9KTtcblxuICAgIHRoaXMudHJhbnNsYXRlLm9uTGFuZ0NoYW5nZS5waXBlKHRha2VVbnRpbERlc3Ryb3llZCgpKS5zdWJzY3JpYmUoKCkgPT4gdGhpcy5jZHIubWFya0ZvckNoZWNrKCkpO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5zcGVlY2hSZWNvZ25pdGlvblNlcnZpY2UuYWJvcnQoKTtcbiAgICB0aGlzLnRleHRUb1NwZWVjaFNlcnZpY2UuY2FuY2VsKCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0IGNhbkxpc3RlbigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5yZWNvZ25pdGlvblN1cHBvcnRlZCAmJiAhIXRoaXMuZ2V0VGV4dEFyZWEoKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBnZXQgY2FuQXBwbHkoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICEhdGhpcy5nZXRUZXh0QXJlYSgpICYmIHRoaXMucHJldmlld1RleHQudHJpbSgpLmxlbmd0aCA+IDA7XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0IGNhblNwZWFrKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmVuYWJsZVRleHRUb1NwZWVjaFxuICAgICAgJiYgdGhpcy50ZXh0VG9TcGVlY2hTZXJ2aWNlLnN1cHBvcnRlZFxuICAgICAgJiYgdGhpcy5yZXNvbHZlU3BlZWNoU291cmNlVGV4dCgpLnRyaW0oKS5sZW5ndGggPiAwO1xuICB9XG5cbiAgcHJvdGVjdGVkIGdldCByZWNvZ25pdGlvblN1cHBvcnRlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5zcGVlY2hSZWNvZ25pdGlvblNlcnZpY2Uuc3VwcG9ydGVkO1xuICB9XG5cbiAgcHJvdGVjdGVkIGdldCBwYXVzZUFjdGlvbkxhYmVsKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMucGF1c2VkXG4gICAgICA/IHRoaXMudHJhbnNsYXRlLmluc3RhbnQoJ3BsYXRmb3JtLmRhdGFjb3JlLnNwZWVjaF9yZWNvZ25pdGlvbi5yZXN1bWUnKVxuICAgICAgOiB0aGlzLnRyYW5zbGF0ZS5pbnN0YW50KCdwbGF0Zm9ybS5kYXRhY29yZS5zcGVlY2hfcmVjb2duaXRpb24ucGF1c2UnKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBnZXQgcHJldmlld1BsYWNlaG9sZGVyKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHJlc29sdmVUcmFuc2xhdGFibGVUZXh0KFxuICAgICAgdGhpcy50cmFuc2xhdGUsXG4gICAgICB0aGlzLnNwZWVjaFJlY29nbml0aW9uUGxhY2Vob2xkZXIsXG4gICAgICBTUEVFQ0hfUkVDT0dOSVRJT05fUExBQ0VIT0xERVJfS0VZXG4gICAgKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBnZXQgcHJldmlld1ZhbHVlKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMucHJldmlld1RleHQudHJpbSgpXG4gICAgICB8fCB0aGlzLnByZXZpZXdQbGFjZWhvbGRlclxuICAgICAgfHwgdGhpcy50cmFuc2xhdGUuaW5zdGFudCgncGxhdGZvcm0uZGF0YWNvcmUuc3BlZWNoX3JlY29nbml0aW9uLmVtcHR5X3ByZXZpZXcnKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBnZXQgc3RhdHVzTWVzc2FnZSgpOiBzdHJpbmcge1xuICAgIGlmICghdGhpcy5yZWNvZ25pdGlvblN1cHBvcnRlZCkge1xuICAgICAgcmV0dXJuIHRoaXMudHJhbnNsYXRlLmluc3RhbnQoJ3BsYXRmb3JtLmRhdGFjb3JlLnNwZWVjaF9yZWNvZ25pdGlvbi51bnN1cHBvcnRlZCcpO1xuICAgIH1cblxuICAgIGlmICghdGhpcy5nZXRUZXh0QXJlYSgpKSB7XG4gICAgICByZXR1cm4gdGhpcy50cmFuc2xhdGUuaW5zdGFudCgncGxhdGZvcm0uZGF0YWNvcmUuc3BlZWNoX3JlY29nbml0aW9uLm1pc3NpbmdfdGFyZ2V0Jyk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMucGVybWlzc2lvbkRlbmllZFN0YXRlKSB7XG4gICAgICByZXR1cm4gdGhpcy50cmFuc2xhdGUuaW5zdGFudCgncGxhdGZvcm0uZGF0YWNvcmUuc3BlZWNoX3JlY29nbml0aW9uLnBlcm1pc3Npb25fZGVuaWVkJyk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMubGlzdGVuaW5nKSB7XG4gICAgICByZXR1cm4gdGhpcy50cmFuc2xhdGUuaW5zdGFudCgncGxhdGZvcm0uZGF0YWNvcmUuc3BlZWNoX3JlY29nbml0aW9uLmxpc3RlbmluZycpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnRyYW5zbGF0ZS5pbnN0YW50KCdwbGF0Zm9ybS5kYXRhY29yZS5zcGVlY2hfcmVjb2duaXRpb24uaWRsZScpO1xuICB9XG5cbiAgcHJvdGVjdGVkIHRvZ2dsZUxpc3RlbmluZygpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5saXN0ZW5pbmcpIHtcbiAgICAgIHRoaXMuc3BlZWNoUmVjb2duaXRpb25TZXJ2aWNlLnN0b3AoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMuY2FuTGlzdGVuKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5wZXJtaXNzaW9uRGVuaWVkU3RhdGUgPSBmYWxzZTtcbiAgICB0aGlzLmJhc2VUZXh0ID0gdGhpcy5rZWVwQ29udGV4dCA/IHRoaXMucmVhZEN1cnJlbnRUZXh0KCkgOiAnJztcbiAgICB0aGlzLnRyYW5zY3JpcHQgPSAnJztcbiAgICB0aGlzLnByZXZpZXdUZXh0ID0gdGhpcy5iYXNlVGV4dDtcbiAgICB0aGlzLnNwZWVjaFJlY29nbml0aW9uU2VydmljZS5zdGFydCh7XG4gICAgICBsYW5nOiByZXNvbHZlU3BlZWNoTG9jYWxlKHRoaXMudHJhbnNsYXRlLmN1cnJlbnRMYW5nKSxcbiAgICAgIHNpbGVuY2VUaW1lb3V0TXM6IE1hdGgubWF4KDAsIHRoaXMuc2lsZW5jZVRpbWVvdXRNcylcbiAgICB9KTtcbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBkaXNjYXJkUmVjb2duaXRpb24oKTogdm9pZCB7XG4gICAgdGhpcy5zcGVlY2hSZWNvZ25pdGlvblNlcnZpY2Uuc3RvcCgpO1xuICAgIHRoaXMudHJhbnNjcmlwdCA9ICcnO1xuICAgIHRoaXMuYmFzZVRleHQgPSB0aGlzLmtlZXBDb250ZXh0ID8gdGhpcy5yZWFkQ3VycmVudFRleHQoKSA6ICcnO1xuICAgIHRoaXMucHJldmlld1RleHQgPSB0aGlzLmtlZXBDb250ZXh0ID8gdGhpcy5iYXNlVGV4dCA6ICcnO1xuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFwcGx5UmVjb2duaXplZFRleHQoKTogdm9pZCB7XG4gICAgY29uc3QgdGV4dEFyZWEgPSB0aGlzLmdldFRleHRBcmVhKCk7XG4gICAgY29uc3QgdmFsdWUgPSB0aGlzLnByZXZpZXdUZXh0LnRyaW0oKTtcblxuICAgIGlmICghdGV4dEFyZWEgfHwgIXZhbHVlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGV4dEFyZWEudmFsdWUgPSB2YWx1ZTtcbiAgICB0ZXh0QXJlYS5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudCgnaW5wdXQnLCB7IGJ1YmJsZXM6IHRydWUgfSkpO1xuICAgIHRleHRBcmVhLmRpc3BhdGNoRXZlbnQobmV3IEV2ZW50KCdjaGFuZ2UnLCB7IGJ1YmJsZXM6IHRydWUgfSkpO1xuICAgIHRoaXMuc3BlZWNoUmVjb2duaXRpb25TZXJ2aWNlLnN0b3AoKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBwbGF5U3BlZWNoKCk6IHZvaWQge1xuICAgIGNvbnN0IHRleHQgPSB0aGlzLnJlc29sdmVTcGVlY2hTb3VyY2VUZXh0KCkudHJpbSgpO1xuXG4gICAgaWYgKCF0ZXh0KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy50ZXh0VG9TcGVlY2hTZXJ2aWNlLnNwZWFrKHRleHQsIHtcbiAgICAgIGxhbmc6IHJlc29sdmVTcGVlY2hMb2NhbGUodGhpcy50cmFuc2xhdGUuY3VycmVudExhbmcpLFxuICAgICAgcmF0ZTogdGhpcy52b2ljZVJhdGVcbiAgICB9KTtcbiAgfVxuXG4gIHByb3RlY3RlZCB0b2dnbGVQYXVzZSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5wYXVzZWQpIHtcbiAgICAgIHRoaXMudGV4dFRvU3BlZWNoU2VydmljZS5yZXN1bWUoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLnRleHRUb1NwZWVjaFNlcnZpY2UucGF1c2UoKTtcbiAgfVxuXG4gIHByb3RlY3RlZCByZXN0YXJ0U3BlZWNoKCk6IHZvaWQge1xuICAgIGNvbnN0IHRleHQgPSB0aGlzLnJlc29sdmVTcGVlY2hTb3VyY2VUZXh0KCkudHJpbSgpO1xuXG4gICAgaWYgKCF0ZXh0KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy50ZXh0VG9TcGVlY2hTZXJ2aWNlLnJlc3RhcnQodGV4dCwge1xuICAgICAgbGFuZzogcmVzb2x2ZVNwZWVjaExvY2FsZSh0aGlzLnRyYW5zbGF0ZS5jdXJyZW50TGFuZyksXG4gICAgICByYXRlOiB0aGlzLnZvaWNlUmF0ZVxuICAgIH0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIHVwZGF0ZVZvaWNlUmF0ZSh2YWx1ZTogc3RyaW5nIHwgbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgcGFyc2VkVmFsdWUgPSB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnID8gTnVtYmVyKHZhbHVlKSA6IHZhbHVlO1xuICAgIHRoaXMudm9pY2VSYXRlID0gTnVtYmVyLmlzRmluaXRlKHBhcnNlZFZhbHVlKSAmJiBwYXJzZWRWYWx1ZSA+IDAgPyBwYXJzZWRWYWx1ZSA6IDE7XG4gIH1cblxuICBwcml2YXRlIGNvbWJpbmVSZWNvZ25pemVkVGV4dChiYXNlVGV4dDogc3RyaW5nLCB0cmFuc2NyaXB0OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IHBhcnRzID0gW2Jhc2VUZXh0LnRyaW0oKSwgdHJhbnNjcmlwdC50cmltKCldLmZpbHRlcihCb29sZWFuKTtcbiAgICByZXR1cm4gcGFydHMuam9pbignICcpLnRyaW0oKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVhZEN1cnJlbnRUZXh0KCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0VGV4dEFyZWEoKT8udmFsdWU/LnRyaW0oKSA/PyAnJztcbiAgfVxuXG4gIHByaXZhdGUgcmVzb2x2ZVNwZWVjaFNvdXJjZVRleHQoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5wcmV2aWV3VGV4dC50cmltKCkgfHwgdGhpcy5yZWFkQ3VycmVudFRleHQoKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0VGV4dEFyZWEoKTogSFRNTFRleHRBcmVhRWxlbWVudCB8IG51bGwge1xuICAgIGlmICghdGhpcy50ZXh0QXJlYUVsZW1lbnQpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnRleHRBcmVhRWxlbWVudCBpbnN0YW5jZW9mIEVsZW1lbnRSZWYpIHtcbiAgICAgIHJldHVybiB0aGlzLnRleHRBcmVhRWxlbWVudC5uYXRpdmVFbGVtZW50O1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnRleHRBcmVhRWxlbWVudDtcbiAgfVxufVxuXG5mdW5jdGlvbiByZXNvbHZlU3BlZWNoTG9jYWxlKGxhbmd1YWdlOiBzdHJpbmcgfCB1bmRlZmluZWQpOiBzdHJpbmcge1xuICBpZiAobGFuZ3VhZ2UgPT09ICdlbicpIHtcbiAgICByZXR1cm4gJ2VuLVVTJztcbiAgfVxuXG4gIGlmIChsYW5ndWFnZSA9PT0gJ2VzLUNPJykge1xuICAgIHJldHVybiAnZXMtQ08nO1xuICB9XG5cbiAgcmV0dXJuICdwdC1CUic7XG59XG4iLCI8c2VjdGlvblxuICBjbGFzcz1cInNkYy1zcGVlY2gtcmVjb2duaXRpb25cIlxuICBbY2xhc3Muc2RjLXNwZWVjaC1yZWNvZ25pdGlvbi0tdW5zdXBwb3J0ZWRdPVwiIXJlY29nbml0aW9uU3VwcG9ydGVkXCJcbj5cbiAgPGRpdiBjbGFzcz1cInNkYy1zcGVlY2gtcmVjb2duaXRpb25fX3Rvb2xiYXJcIj5cbiAgICA8YnV0dG9uXG4gICAgICBjbGFzcz1cInNkYy1zcGVlY2gtcmVjb2duaXRpb25fX2J1dHRvbiBzZGMtc3BlZWNoLXJlY29nbml0aW9uX19idXR0b24tLXByaW1hcnlcIlxuICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICBbZGlzYWJsZWRdPVwiIWNhbkxpc3RlblwiXG4gICAgICAoY2xpY2spPVwidG9nZ2xlTGlzdGVuaW5nKClcIlxuICAgID5cbiAgICAgIHt7XG4gICAgICAgIGxpc3RlbmluZ1xuICAgICAgICAgID8gKCdwbGF0Zm9ybS5kYXRhY29yZS5zcGVlY2hfcmVjb2duaXRpb24uc3RvcCcgfCB0cmFuc2xhdGUpXG4gICAgICAgICAgOiAoJ3BsYXRmb3JtLmRhdGFjb3JlLnNwZWVjaF9yZWNvZ25pdGlvbi5saXN0ZW4nIHwgdHJhbnNsYXRlKVxuICAgICAgfX1cbiAgICA8L2J1dHRvbj5cblxuICAgIDxidXR0b25cbiAgICAgIGNsYXNzPVwic2RjLXNwZWVjaC1yZWNvZ25pdGlvbl9fYnV0dG9uXCJcbiAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgW2Rpc2FibGVkXT1cIiFwcmV2aWV3VGV4dC50cmltKClcIlxuICAgICAgKGNsaWNrKT1cImRpc2NhcmRSZWNvZ25pdGlvbigpXCJcbiAgICA+XG4gICAgICB7eyAncGxhdGZvcm0uZGF0YWNvcmUuc3BlZWNoX3JlY29nbml0aW9uLmRpc2NhcmQnIHwgdHJhbnNsYXRlIH19XG4gICAgPC9idXR0b24+XG5cbiAgICA8YnV0dG9uXG4gICAgICBjbGFzcz1cInNkYy1zcGVlY2gtcmVjb2duaXRpb25fX2J1dHRvblwiXG4gICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgIFtkaXNhYmxlZF09XCIhY2FuQXBwbHlcIlxuICAgICAgKGNsaWNrKT1cImFwcGx5UmVjb2duaXplZFRleHQoKVwiXG4gICAgPlxuICAgICAge3sgJ3BsYXRmb3JtLmRhdGFjb3JlLnNwZWVjaF9yZWNvZ25pdGlvbi5hcHBseScgfCB0cmFuc2xhdGUgfX1cbiAgICA8L2J1dHRvbj5cbiAgPC9kaXY+XG5cbiAgPGRpdiBjbGFzcz1cInNkYy1zcGVlY2gtcmVjb2duaXRpb25fX3ByZXZpZXdcIj5cbiAgICA8c3BhbiBjbGFzcz1cInNkYy1zcGVlY2gtcmVjb2duaXRpb25fX2xhYmVsXCI+XG4gICAgICB7eyAncGxhdGZvcm0uZGF0YWNvcmUuc3BlZWNoX3JlY29nbml0aW9uLnByZXZpZXcnIHwgdHJhbnNsYXRlIH19XG4gICAgPC9zcGFuPlxuICAgIDxkaXYgY2xhc3M9XCJzZGMtc3BlZWNoLXJlY29nbml0aW9uX19wcmV2aWV3VmFsdWVcIj5cbiAgICAgIHt7IHByZXZpZXdWYWx1ZSB9fVxuICAgIDwvZGl2PlxuICA8L2Rpdj5cblxuICA8ZGl2ICpuZ0lmPVwiZW5hYmxlVGV4dFRvU3BlZWNoXCIgY2xhc3M9XCJzZGMtc3BlZWNoLXJlY29nbml0aW9uX190dHNcIj5cbiAgICA8YnV0dG9uXG4gICAgICBjbGFzcz1cInNkYy1zcGVlY2gtcmVjb2duaXRpb25fX2J1dHRvblwiXG4gICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgIFtkaXNhYmxlZF09XCIhY2FuU3BlYWtcIlxuICAgICAgKGNsaWNrKT1cInBsYXlTcGVlY2goKVwiXG4gICAgPlxuICAgICAge3sgJ3BsYXRmb3JtLmRhdGFjb3JlLnNwZWVjaF9yZWNvZ25pdGlvbi5wbGF5JyB8IHRyYW5zbGF0ZSB9fVxuICAgIDwvYnV0dG9uPlxuXG4gICAgPGJ1dHRvblxuICAgICAgY2xhc3M9XCJzZGMtc3BlZWNoLXJlY29nbml0aW9uX19idXR0b25cIlxuICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICBbZGlzYWJsZWRdPVwiIXNwZWFraW5nICYmICFwYXVzZWRcIlxuICAgICAgKGNsaWNrKT1cInRvZ2dsZVBhdXNlKClcIlxuICAgID5cbiAgICAgIHt7IHBhdXNlQWN0aW9uTGFiZWwgfX1cbiAgICA8L2J1dHRvbj5cblxuICAgIDxidXR0b25cbiAgICAgIGNsYXNzPVwic2RjLXNwZWVjaC1yZWNvZ25pdGlvbl9fYnV0dG9uXCJcbiAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgW2Rpc2FibGVkXT1cIiFjYW5TcGVha1wiXG4gICAgICAoY2xpY2spPVwicmVzdGFydFNwZWVjaCgpXCJcbiAgICA+XG4gICAgICB7eyAncGxhdGZvcm0uZGF0YWNvcmUuc3BlZWNoX3JlY29nbml0aW9uLnJlc3RhcnQnIHwgdHJhbnNsYXRlIH19XG4gICAgPC9idXR0b24+XG5cbiAgICA8bGFiZWwgY2xhc3M9XCJzZGMtc3BlZWNoLXJlY29nbml0aW9uX19zcGVlZFwiPlxuICAgICAgPHNwYW4+e3sgJ3BsYXRmb3JtLmRhdGFjb3JlLnNwZWVjaF9yZWNvZ25pdGlvbi5zcGVlZCcgfCB0cmFuc2xhdGUgfX08L3NwYW4+XG4gICAgICA8c2VsZWN0XG4gICAgICAgIGNsYXNzPVwic2RjLXNwZWVjaC1yZWNvZ25pdGlvbl9fc2VsZWN0XCJcbiAgICAgICAgW25nTW9kZWxdPVwidm9pY2VSYXRlXCJcbiAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwidXBkYXRlVm9pY2VSYXRlKCRldmVudClcIlxuICAgICAgPlxuICAgICAgICA8b3B0aW9uICpuZ0Zvcj1cImxldCByYXRlIG9mIHZvaWNlUmF0ZXNcIiBbbmdWYWx1ZV09XCJyYXRlXCI+XG4gICAgICAgICAge3sgcmF0ZSB9fXhcbiAgICAgICAgPC9vcHRpb24+XG4gICAgICA8L3NlbGVjdD5cbiAgICA8L2xhYmVsPlxuICA8L2Rpdj5cblxuICA8cCBjbGFzcz1cInNkYy1zcGVlY2gtcmVjb2duaXRpb25fX3N0YXR1c1wiPlxuICAgIHt7IHN0YXR1c01lc3NhZ2UgfX1cbiAgPC9wPlxuPC9zZWN0aW9uPlxuIl19
|