@arcgis/ai-components 5.1.0-next.61 → 5.1.0-next.63
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/dist/cdn/5RA2JKQ5.js +3 -0
- package/dist/cdn/6IDESYBP.js +2 -0
- package/dist/cdn/E4J4SWHB.js +2 -0
- package/dist/cdn/MP7AEALE.js +2 -0
- package/dist/cdn/SOPNKXO5.js +2 -0
- package/dist/cdn/VJGA26MX.js +2 -0
- package/dist/cdn/assets/assistant-chat-card/t9n/messages.en.json +1 -1
- package/dist/cdn/index.js +1 -1
- package/dist/cdn/main.css +1 -1
- package/dist/components/arcgis-assistant/customElement.d.ts +4 -0
- package/dist/components/arcgis-assistant/customElement.js +30 -30
- package/dist/components/arcgis-assistant-chat/customElement.d.ts +2 -0
- package/dist/components/arcgis-assistant-chat/customElement.js +7 -7
- package/dist/components/arcgis-assistant-chat-card/customElement.d.ts +6 -0
- package/dist/components/arcgis-assistant-chat-card/customElement.js +101 -25
- package/dist/components/arcgis-assistant-chat-entry/customElement.d.ts +2 -0
- package/dist/components/arcgis-assistant-chat-entry/customElement.js +129 -33
- package/dist/components/arcgis-assistant-chat-entry/index.js +1 -0
- package/dist/components/arcgis-assistant-chat-entry-speech-input/customElement.d.ts +26 -0
- package/dist/components/arcgis-assistant-chat-entry-speech-input/customElement.js +437 -0
- package/dist/components/arcgis-assistant-chat-entry-speech-input/index.d.ts +1 -0
- package/dist/components/arcgis-assistant-chat-entry-speech-input/index.js +2 -0
- package/dist/components/arcgis-assistant-chat-entry-speech-input/support/types.d.ts +15 -0
- package/dist/components/arcgis-assistant-shell/customElement.d.ts +2 -0
- package/dist/components/arcgis-assistant-shell/customElement.js +6 -6
- package/dist/docs/api.json +1 -1
- package/dist/docs/docs.json +1 -1
- package/dist/docs/vscode.html-custom-data.json +1 -1
- package/dist/docs/web-types.json +1 -1
- package/dist/index.d.ts +10 -0
- package/dist/loader.js +6 -5
- package/dist/types/lumina.d.ts +16 -5
- package/dist/types/preact.d.ts +17 -5
- package/dist/types/react.d.ts +18 -5
- package/dist/types/stencil.d.ts +16 -5
- package/package.json +6 -6
- package/dist/cdn/ETKNVWKV.js +0 -2
- package/dist/cdn/JPYSTYTV.js +0 -2
- package/dist/cdn/NN7QKIMP.js +0 -2
- package/dist/cdn/WO6WO3SH.js +0 -3
- package/dist/cdn/ZLYDPB4L.js +0 -2
|
@@ -1,66 +1,162 @@
|
|
|
1
1
|
/* COPYRIGHT Esri - https://js.arcgis.com/5.1/LICENSE.txt */
|
|
2
|
-
import { c as
|
|
3
|
-
import { css as
|
|
4
|
-
import { LitElement as
|
|
5
|
-
import { createRef as
|
|
6
|
-
import { watch as
|
|
7
|
-
import { u as
|
|
8
|
-
import
|
|
9
|
-
const
|
|
10
|
-
|
|
2
|
+
import { c as p } from "../../chunks/runtime.js";
|
|
3
|
+
import { css as d, html as c } from "lit";
|
|
4
|
+
import { LitElement as f, createEvent as h, nothing as g } from "@arcgis/lumina";
|
|
5
|
+
import { createRef as v, ref as m } from "lit/directives/ref.js";
|
|
6
|
+
import { watch as y } from "@arcgis/core/core/reactiveUtils.js";
|
|
7
|
+
import { u as _ } from "../../chunks/useT9n.js";
|
|
8
|
+
import V from "@arcgis/core/core/Collection.js";
|
|
9
|
+
const I = d`.assistant-chat-entry__input-container{display:flex;flex-direction:column}.assistant-chat-entry__footer-start{display:flex;gap:var(--calcite-spacing-md);flex-wrap:wrap;align-items:center}.assistant-chat-entry__footer-end{display:flex;gap:var(--calcite-spacing-md);align-items:center}.assistant-chat-entry__status-indicator{width:9px;height:9px;border-radius:100%;background-color:var(--calcite-color-status-success)}.assistant-chat-entry__status-indicator[data-status=working]{background-color:var(--calcite-color-status-warning)}.assistant-chat-entry__status-indicator[data-status=error]{background-color:var(--calcite-color-status-danger)}.assistant-chat-entry__status-text{text-transform:capitalize}`;
|
|
10
|
+
function l(u) {
|
|
11
|
+
const { baseValue: t, transcript: s } = u;
|
|
12
|
+
if (!s)
|
|
13
|
+
return t;
|
|
14
|
+
const e = t.trim();
|
|
15
|
+
return e ? `${e} ${s}` : s;
|
|
16
|
+
}
|
|
17
|
+
class b extends f {
|
|
11
18
|
constructor() {
|
|
12
|
-
super(...arguments), this.#
|
|
19
|
+
super(...arguments), this.#t = v(), this.#s = -1, this.#i = "", this.#e = null, this.#a = (t) => {
|
|
20
|
+
const s = t.detail;
|
|
21
|
+
this._applyVoiceInputTranscript(s?.transcript);
|
|
22
|
+
}, this.#n = () => {
|
|
23
|
+
this._startVoiceInputSession();
|
|
24
|
+
}, this.#r = () => {
|
|
25
|
+
this._finishVoiceInputSession();
|
|
26
|
+
}, this.#o = (t) => {
|
|
27
|
+
const s = t.detail;
|
|
28
|
+
this._applyVoiceInputTranscript(s?.transcript, { final: !0 });
|
|
29
|
+
}, this.#c = (t) => {
|
|
30
|
+
}, this._messages = _({ blocking: !0 }), this.keyboardShortcutsDisabled = !1, this.awaitingResponse = !1, this.inputValue = "", this.voiceInputEnabled = !1, this.messages = new V([]), this.arcgisCancel = h(), this.arcgisSubmit = h();
|
|
13
31
|
}
|
|
14
32
|
static {
|
|
15
|
-
this.properties = { _userMessages: 16, keyboardShortcutsDisabled: 5, entryPlaceholder: 1, awaitingResponse: 5, inputValue: 1, status: 1, messages: 0 };
|
|
33
|
+
this.properties = { _userMessages: 16, keyboardShortcutsDisabled: 5, entryPlaceholder: 1, awaitingResponse: 5, inputValue: 1, status: 1, voiceInputEnabled: 5, messages: 0 };
|
|
16
34
|
}
|
|
17
35
|
static {
|
|
18
|
-
this.styles =
|
|
36
|
+
this.styles = I;
|
|
19
37
|
}
|
|
20
|
-
#s;
|
|
21
38
|
#t;
|
|
39
|
+
#s;
|
|
40
|
+
#i;
|
|
22
41
|
#e;
|
|
42
|
+
#a;
|
|
43
|
+
#n;
|
|
44
|
+
#r;
|
|
45
|
+
#o;
|
|
46
|
+
#c;
|
|
23
47
|
get _userMessages() {
|
|
24
48
|
return this.messages.toArray().filter((t) => t.role === "user").map(({ content: t }) => t);
|
|
25
49
|
}
|
|
26
50
|
loaded() {
|
|
27
|
-
this.manager.onLifecycle(() =>
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
51
|
+
this.manager.onLifecycle(() => {
|
|
52
|
+
const t = [
|
|
53
|
+
{
|
|
54
|
+
eventType: "arcgisVoiceInputInterimTranscription",
|
|
55
|
+
callback: this.#a
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
eventType: "arcgisVoiceInputStart",
|
|
59
|
+
callback: this.#n
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
eventType: "arcgisVoiceInputStop",
|
|
63
|
+
callback: this.#r
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
eventType: "arcgisVoiceInputTranscription",
|
|
67
|
+
callback: this.#o
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
eventType: "arcgisVoiceInputTranscriptionStreamChunk",
|
|
71
|
+
callback: this.#c
|
|
72
|
+
}
|
|
73
|
+
];
|
|
74
|
+
for (const { eventType: s, callback: e } of t)
|
|
75
|
+
this.el.addEventListener(s, e);
|
|
76
|
+
return [
|
|
77
|
+
y(() => this.inputValue, (s) => {
|
|
78
|
+
this.#t.value && (this.#t.value.value = s);
|
|
79
|
+
}, { initial: !0 }),
|
|
80
|
+
{
|
|
81
|
+
remove: () => {
|
|
82
|
+
for (const { eventType: s, callback: e } of t)
|
|
83
|
+
this.el.removeEventListener(s, e);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
];
|
|
87
|
+
});
|
|
32
88
|
}
|
|
33
89
|
async _submitMessage() {
|
|
34
90
|
if (this.awaitingResponse) {
|
|
35
91
|
this.arcgisCancel.emit();
|
|
36
92
|
return;
|
|
37
93
|
}
|
|
38
|
-
const t = this.#
|
|
39
|
-
t && (this.arcgisSubmit.emit(t), this.#
|
|
94
|
+
const t = this.#t.value?.value.trim();
|
|
95
|
+
t && (this.arcgisSubmit.emit(t), this.#s = -1, this.#i = "", this._clearVoiceInputSession(), this.#t.value && (this.#t.value.value = "", await this.#t.value.setFocus()));
|
|
40
96
|
}
|
|
41
|
-
async _navigateHistory(t,
|
|
42
|
-
const
|
|
43
|
-
if (!
|
|
97
|
+
async _navigateHistory(t, s) {
|
|
98
|
+
const e = this.#t.value;
|
|
99
|
+
if (!e)
|
|
44
100
|
return;
|
|
45
|
-
const
|
|
46
|
-
if (
|
|
101
|
+
const i = this._userMessages;
|
|
102
|
+
if (i.length === 0)
|
|
47
103
|
return;
|
|
48
|
-
const
|
|
49
|
-
if (!(
|
|
104
|
+
const a = e.value ?? "", r = e.shadowRoot?.querySelector("textarea"), n = r?.selectionStart, o = r?.selectionEnd;
|
|
105
|
+
if (!(n == null || o == null) && !(n !== o || t === "up" && n !== 0 || t === "down" && n !== a.length)) {
|
|
50
106
|
if (t === "up") {
|
|
51
|
-
this.#
|
|
107
|
+
this.#s === -1 ? (this.#i = a, this.#s = i.length - 1) : this.#s = Math.max(0, this.#s - 1), e.value = i[this.#s] ?? "", s.preventDefault();
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
this.#s !== -1 && (this.#s < i.length - 1 ? (this.#s += 1, e.value = i[this.#s] ?? "") : (this.#s = -1, e.value = this.#i), s.preventDefault());
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
_startVoiceInputSession() {
|
|
114
|
+
this.#e = {
|
|
115
|
+
baseValue: this.#t.value?.value?.trim() ?? "",
|
|
116
|
+
phase: "listening",
|
|
117
|
+
transcript: ""
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
_finishVoiceInputSession() {
|
|
121
|
+
const t = this.#t.value, s = this.#e;
|
|
122
|
+
if (!t) {
|
|
123
|
+
this._clearVoiceInputSession();
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
if (!s) {
|
|
127
|
+
this._setDraftValue(t.value?.trim() ?? "");
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
const e = { ...s, phase: "stopped" }, i = l(e);
|
|
131
|
+
this.#e = e, this._setDraftValue(i);
|
|
132
|
+
}
|
|
133
|
+
async _applyVoiceInputTranscript(t, s) {
|
|
134
|
+
const e = this.#t.value, i = this.#e;
|
|
135
|
+
if (!e || !t || !i)
|
|
136
|
+
return;
|
|
137
|
+
if (i.phase === "stopped") {
|
|
138
|
+
const n = l(i);
|
|
139
|
+
if ((e.value?.trim() ?? "") !== n) {
|
|
140
|
+
this._clearVoiceInputSession();
|
|
52
141
|
return;
|
|
53
142
|
}
|
|
54
|
-
this.#t !== -1 && (this.#t < e.length - 1 ? (this.#t += 1, s.value = e[this.#t] ?? "") : (this.#t = -1, s.value = this.#e), i.preventDefault());
|
|
55
143
|
}
|
|
144
|
+
const a = { ...i, transcript: t }, r = l(a);
|
|
145
|
+
this.#e = a, this._setDraftValue(r), s?.final && a.phase === "stopped" && await e.setFocus();
|
|
146
|
+
}
|
|
147
|
+
_setDraftValue(t) {
|
|
148
|
+
this.#t.value && (this.#t.value.value = t), this.#s = -1, this.#i = t;
|
|
149
|
+
}
|
|
150
|
+
_clearVoiceInputSession() {
|
|
151
|
+
this.#e = null;
|
|
56
152
|
}
|
|
57
153
|
render() {
|
|
58
|
-
return
|
|
154
|
+
return c`<div class="assistant-chat-entry__input-container"><calcite-text-area .value=${this.#t.value?.value} .placeholder=${this.entryPlaceholder ?? this._messages.entryPlaceholder} resize=vertical @keydown=${async (t) => {
|
|
59
155
|
t.altKey || t.ctrlKey || t.metaKey || t.shiftKey || this.keyboardShortcutsDisabled || (t.key === "Enter" ? (t.preventDefault(), await this._submitMessage()) : t.key === "ArrowUp" ? await this._navigateHistory("up", t) : t.key === "ArrowDown" && await this._navigateHistory("down", t));
|
|
60
|
-
}} ${
|
|
156
|
+
}} ${m(this.#t)}><div slot=footer-start class="assistant-chat-entry__footer-start"><slot name=entry-actions-start></slot></div><div slot=footer-end class="assistant-chat-entry__footer-end">${this.status ? c`<div id=tooltip-status class="assistant-chat-entry__status-indicator" data-status=${this.status ?? g}></div><calcite-tooltip reference-element=tooltip-status offset-distance=12><span class="assistant-chat-entry__status-text">${this.status}</span></calcite-tooltip>` : null}${this.voiceInputEnabled ? c`<arcgis-assistant-chat-entry-speech-input .awaitingResponse=${this.awaitingResponse}></arcgis-assistant-chat-entry-speech-input>` : null}<calcite-button .iconStart=${this.awaitingResponse ? "circle-stop" : "send"} slot=footer-end round @click=${() => void this._submitMessage()}>${this.awaitingResponse ? this._messages.stopButtonLabel : this._messages.askButtonLabel}</calcite-button></div></calcite-text-area></div>`;
|
|
61
157
|
}
|
|
62
158
|
}
|
|
63
|
-
|
|
159
|
+
p("arcgis-assistant-chat-entry", b);
|
|
64
160
|
export {
|
|
65
|
-
|
|
161
|
+
b as ArcgisAssistantChatEntry
|
|
66
162
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import "@esri/calcite-components/components/calcite-text-area";
|
|
2
2
|
import "@esri/calcite-components/components/calcite-tooltip";
|
|
3
|
+
import "../arcgis-assistant-chat-entry-speech-input/index.js";
|
|
3
4
|
import "@esri/calcite-components/components/calcite-button";
|
|
4
5
|
export * from "./customElement.js";
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/// <reference path="../../index.d.ts" />
|
|
2
|
+
import type { PublicLitElement as LitElement } from "@arcgis/lumina";
|
|
3
|
+
import type { VoiceInputErrorCode, VoiceInputMode, VoiceInputTranscriptDetail, VoiceInputTranscriptionStreamChunkDetail } from "./support/types.js";
|
|
4
|
+
|
|
5
|
+
/** @internal */
|
|
6
|
+
export abstract class ArcgisAssistantChatEntrySpeechInput extends LitElement {
|
|
7
|
+
/** @default false */
|
|
8
|
+
accessor awaitingResponse: boolean;
|
|
9
|
+
accessor language: string | undefined;
|
|
10
|
+
/** @default "web-speech" */
|
|
11
|
+
accessor mode: VoiceInputMode;
|
|
12
|
+
readonly arcgisVoiceInputError: import("@arcgis/lumina").TargetedEvent<this, { errorCode: VoiceInputErrorCode; }>;
|
|
13
|
+
readonly arcgisVoiceInputInterimTranscription: import("@arcgis/lumina").TargetedEvent<this, VoiceInputTranscriptDetail>;
|
|
14
|
+
readonly arcgisVoiceInputStart: import("@arcgis/lumina").TargetedEvent<this, void>;
|
|
15
|
+
readonly arcgisVoiceInputStop: import("@arcgis/lumina").TargetedEvent<this, void>;
|
|
16
|
+
readonly arcgisVoiceInputTranscription: import("@arcgis/lumina").TargetedEvent<this, VoiceInputTranscriptDetail>;
|
|
17
|
+
readonly arcgisVoiceInputTranscriptionStreamChunk: import("@arcgis/lumina").TargetedEvent<this, VoiceInputTranscriptionStreamChunkDetail>;
|
|
18
|
+
readonly "@eventTypes": {
|
|
19
|
+
arcgisVoiceInputError: ArcgisAssistantChatEntrySpeechInput["arcgisVoiceInputError"]["detail"];
|
|
20
|
+
arcgisVoiceInputInterimTranscription: ArcgisAssistantChatEntrySpeechInput["arcgisVoiceInputInterimTranscription"]["detail"];
|
|
21
|
+
arcgisVoiceInputStart: ArcgisAssistantChatEntrySpeechInput["arcgisVoiceInputStart"]["detail"];
|
|
22
|
+
arcgisVoiceInputStop: ArcgisAssistantChatEntrySpeechInput["arcgisVoiceInputStop"]["detail"];
|
|
23
|
+
arcgisVoiceInputTranscription: ArcgisAssistantChatEntrySpeechInput["arcgisVoiceInputTranscription"]["detail"];
|
|
24
|
+
arcgisVoiceInputTranscriptionStreamChunk: ArcgisAssistantChatEntrySpeechInput["arcgisVoiceInputTranscriptionStreamChunk"]["detail"];
|
|
25
|
+
};
|
|
26
|
+
}
|
|
@@ -0,0 +1,437 @@
|
|
|
1
|
+
/* COPYRIGHT Esri - https://js.arcgis.com/5.1/LICENSE.txt */
|
|
2
|
+
import { c as C } from "../../chunks/runtime.js";
|
|
3
|
+
import { css as S, html as R } from "lit";
|
|
4
|
+
import { when as f, watch as u } from "@arcgis/core/core/reactiveUtils.js";
|
|
5
|
+
import { LitElement as y, createEvent as h, nothing as v } from "@arcgis/lumina";
|
|
6
|
+
import w from "@arcgis/core/core/Accessor.js";
|
|
7
|
+
import { property as l, subclass as m } from "@arcgis/core/core/accessorSupport/decorators.js";
|
|
8
|
+
const T = S`.assistant-chat-entry-speech-input__button{--calcite-button-background-color: var(--calcite-color-transparent);--calcite-button-border-color: transparent;--calcite-button-icon-color: var(--calcite-color-text-3);--calcite-button-text-color: var(--calcite-color-text-3);flex:0 0 auto;position:relative}.assistant-chat-entry-speech-input__button[data-state=disabled]{--calcite-button-icon-color: var(--calcite-color-text-3);opacity:var(--calcite-opacity-disabled)}.assistant-chat-entry-speech-input__button[data-state=listening]{--calcite-button-background-color: color-mix( in srgb, var(--calcite-color-brand) 14%, var(--calcite-color-foreground-1) );--calcite-button-border-color: color-mix(in srgb, var(--calcite-color-brand) 24%, transparent);--calcite-button-icon-color: var(--calcite-color-brand);--calcite-button-text-color: var(--calcite-color-brand);box-shadow:var(--calcite-shadow-sm)}.assistant-chat-entry-speech-input__button[data-state=listening]:hover{--calcite-button-background-color: color-mix( in srgb, var(--calcite-color-brand-hover, var(--calcite-color-brand)) 18%, var(--calcite-color-foreground-1) )}.assistant-chat-entry-speech-input__button[data-state=listening]:active{--calcite-button-background-color: color-mix( in srgb, var(--calcite-color-brand) 24%, var(--calcite-color-foreground-1) )}.assistant-chat-entry-speech-input__button[data-state=processing]{--calcite-button-background-color: color-mix( in srgb, var(--calcite-color-brand) 10%, var(--calcite-color-foreground-1) );--calcite-button-border-color: color-mix(in srgb, var(--calcite-color-brand) 20%, transparent);--calcite-button-icon-color: var(--calcite-color-brand);--calcite-button-text-color: var(--calcite-color-brand)}.assistant-chat-entry-speech-input__button[data-state=error]{--calcite-button-background-color: color-mix( in srgb, var(--calcite-color-status-danger) 12%, var(--calcite-color-foreground-1) );--calcite-button-border-color: color-mix(in srgb, var(--calcite-color-status-danger) 24%, transparent);--calcite-button-icon-color: var(--calcite-color-status-danger);--calcite-button-text-color: var(--calcite-color-status-danger)}.assistant-chat-entry-speech-input__button[data-state=listening]:after{content:"";position:absolute;inset:-4px;border:1px solid color-mix(in srgb,var(--calcite-color-brand) 40%,transparent);border-radius:inherit;opacity:0;pointer-events:none;transform:scale(.92);animation:assistant-chat-entry-speech-input-recording-pulse 1.8s ease-out infinite}@keyframes assistant-chat-entry-speech-input-recording-pulse{0%{opacity:.65;transform:scale(.92)}70%{opacity:0;transform:scale(1.16)}to{opacity:0;transform:scale(1.16)}}@media(prefers-reduced-motion){.assistant-chat-entry-speech-input__button[data-state=listening]:after{animation:none;opacity:1;transform:none}}`;
|
|
9
|
+
var k = Object.defineProperty, I = Object.getOwnPropertyDescriptor, p = (t, e, s, r) => {
|
|
10
|
+
for (var i = r > 1 ? void 0 : r ? I(e, s) : e, n = t.length - 1, o; n >= 0; n--)
|
|
11
|
+
(o = t[n]) && (i = (r ? o(e, s, i) : o(i)) || i);
|
|
12
|
+
return r && i && k(e, s, i), i;
|
|
13
|
+
};
|
|
14
|
+
let a = class extends w {
|
|
15
|
+
constructor(t) {
|
|
16
|
+
super(t), this.state = "idle", this.liveTranscript = "", this.transcript = "", this.errorCode = void 0;
|
|
17
|
+
}
|
|
18
|
+
static isSupported() {
|
|
19
|
+
return !1;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
p([
|
|
23
|
+
l()
|
|
24
|
+
], a.prototype, "language", 2);
|
|
25
|
+
p([
|
|
26
|
+
l({ readOnly: !0 })
|
|
27
|
+
], a.prototype, "state", 2);
|
|
28
|
+
p([
|
|
29
|
+
l({ readOnly: !0 })
|
|
30
|
+
], a.prototype, "liveTranscript", 2);
|
|
31
|
+
p([
|
|
32
|
+
l({ readOnly: !0 })
|
|
33
|
+
], a.prototype, "transcript", 2);
|
|
34
|
+
p([
|
|
35
|
+
l({ readOnly: !0 })
|
|
36
|
+
], a.prototype, "errorCode", 2);
|
|
37
|
+
a = p([
|
|
38
|
+
m("SpeechController")
|
|
39
|
+
], a);
|
|
40
|
+
const x = [
|
|
41
|
+
"audio/webm;codecs=opus",
|
|
42
|
+
"audio/webm",
|
|
43
|
+
"audio/mp4",
|
|
44
|
+
"audio/ogg;codecs=opus",
|
|
45
|
+
"audio/ogg"
|
|
46
|
+
];
|
|
47
|
+
function d(t) {
|
|
48
|
+
return t.replace(/\s+/gu, " ").trim();
|
|
49
|
+
}
|
|
50
|
+
var O = Object.defineProperty, M = Object.getOwnPropertyDescriptor, g = (t, e, s, r) => {
|
|
51
|
+
for (var i = r > 1 ? void 0 : r ? M(e, s) : e, n = t.length - 1, o; n >= 0; n--)
|
|
52
|
+
(o = t[n]) && (i = (r ? o(e, s, i) : o(i)) || i);
|
|
53
|
+
return r && i && O(e, s, i), i;
|
|
54
|
+
};
|
|
55
|
+
let c = class extends a {
|
|
56
|
+
constructor(t) {
|
|
57
|
+
super(t), this._activeSessionId = null, this._mediaRecorder = null, this._mediaRecorderChunkIndex = 0, this._mediaRecorderStopReason = null, this._mediaStream = null, this._pendingChunkOperations = /* @__PURE__ */ new Set(), this._recordedChunks = [], this.handleRecording = null, this.chunkTimeSlice = 3e3;
|
|
58
|
+
}
|
|
59
|
+
get _mimeType() {
|
|
60
|
+
return typeof window > "u" || typeof window.MediaRecorder?.isTypeSupported != "function" ? "" : x.find((t) => window.MediaRecorder.isTypeSupported(t)) ?? "";
|
|
61
|
+
}
|
|
62
|
+
initialize() {
|
|
63
|
+
c.isSupported() && this.addHandles(
|
|
64
|
+
f(
|
|
65
|
+
() => !!this.errorCode,
|
|
66
|
+
() => {
|
|
67
|
+
this._set("state", "error");
|
|
68
|
+
}
|
|
69
|
+
)
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
destroy() {
|
|
73
|
+
this._mediaRecorder && (this._mediaRecorder.onstart = null, this._mediaRecorder.ondataavailable = null, this._mediaRecorder.onerror = null, this._mediaRecorder.onstop = null), this.cancel(), this._mediaRecorder = null;
|
|
74
|
+
}
|
|
75
|
+
// Stop waits for any in-flight chunk transcription before finalizing the session transcript.
|
|
76
|
+
_queuePendingChunkOperation(t) {
|
|
77
|
+
this._pendingChunkOperations.add(t), t.finally(() => {
|
|
78
|
+
this._pendingChunkOperations.delete(t);
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
async _awaitPendingChunkOperations() {
|
|
82
|
+
this._pendingChunkOperations.size && await Promise.allSettled(Array.from(this._pendingChunkOperations));
|
|
83
|
+
}
|
|
84
|
+
_onDataAvailable(t) {
|
|
85
|
+
const e = this._activeSessionId;
|
|
86
|
+
e != null && this._queuePendingChunkOperation(this._processDataAvailable(t, e));
|
|
87
|
+
}
|
|
88
|
+
async _processDataAvailable(t, e) {
|
|
89
|
+
const s = t.data;
|
|
90
|
+
if (!s.size || e !== this._activeSessionId)
|
|
91
|
+
return;
|
|
92
|
+
this._recordedChunks.push(s);
|
|
93
|
+
const r = s.type || this._mediaRecorder?.mimeType || this._mimeType, i = this._mediaRecorderStopReason === "toggle" && this._mediaRecorder?.state === "inactive";
|
|
94
|
+
try {
|
|
95
|
+
if (!this.handleRecording)
|
|
96
|
+
return;
|
|
97
|
+
const n = d(
|
|
98
|
+
await this.handleRecording(s, r, this._mediaRecorderChunkIndex, i) ?? ""
|
|
99
|
+
);
|
|
100
|
+
if (e !== this._activeSessionId)
|
|
101
|
+
return;
|
|
102
|
+
n && this._set("liveTranscript", d(`${this.liveTranscript} ${n}`));
|
|
103
|
+
} catch (n) {
|
|
104
|
+
if (e !== this._activeSessionId)
|
|
105
|
+
return;
|
|
106
|
+
this._failSession(
|
|
107
|
+
n instanceof Error && n.message === "transcription-unavailable" ? "transcription-unavailable" : "transcription-failed"
|
|
108
|
+
);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
!i && e === this._activeSessionId && (this._mediaRecorderChunkIndex += 1);
|
|
112
|
+
}
|
|
113
|
+
_failSession(t) {
|
|
114
|
+
const e = this._mediaRecorder;
|
|
115
|
+
if (e) {
|
|
116
|
+
e.onstart = null, e.ondataavailable = null, e.onerror = null, e.onstop = null;
|
|
117
|
+
try {
|
|
118
|
+
e.state !== "inactive" && e.stop();
|
|
119
|
+
} catch {
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
this._activeSessionId = null, this._mediaRecorder = null, this._mediaRecorderChunkIndex = 0, this._mediaRecorderStopReason = null, this._pendingChunkOperations.clear(), this._recordedChunks = [], this._releaseMediaStream(), this._set("liveTranscript", ""), this._set("transcript", ""), this._set("errorCode", t);
|
|
123
|
+
}
|
|
124
|
+
_onError() {
|
|
125
|
+
this._failSession("recording-failed");
|
|
126
|
+
}
|
|
127
|
+
_onStart() {
|
|
128
|
+
this._set("state", "listening");
|
|
129
|
+
}
|
|
130
|
+
_onStop() {
|
|
131
|
+
this._handleStop();
|
|
132
|
+
}
|
|
133
|
+
_releaseMediaStream() {
|
|
134
|
+
this._mediaStream?.getTracks().forEach((t) => t.stop()), this._mediaStream = null;
|
|
135
|
+
}
|
|
136
|
+
async _handleStop() {
|
|
137
|
+
const t = this._mediaRecorder, e = this._activeSessionId, s = this._mediaRecorderStopReason, r = t?.mimeType || this._recordedChunks.find((o) => !!o.type)?.type || "", i = [...this._recordedChunks];
|
|
138
|
+
if (this._mediaRecorder = null, this._mediaRecorderChunkIndex = 0, this._releaseMediaStream(), s === "cancel") {
|
|
139
|
+
this._activeSessionId === e && (this._activeSessionId = null), this._mediaRecorderStopReason = null, this._pendingChunkOperations.clear(), this._recordedChunks = [], this._set("liveTranscript", ""), this._set("transcript", ""), this._set("state", "idle"), this._set("errorCode", void 0);
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
if (e == null) {
|
|
143
|
+
this._mediaRecorderStopReason = null, this._pendingChunkOperations.clear(), this._recordedChunks = [], this._set("state", "idle"), this._set("errorCode", void 0);
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
if (await this._awaitPendingChunkOperations(), e !== this._activeSessionId)
|
|
147
|
+
return;
|
|
148
|
+
if (!(r ? new Blob(i, { type: r }) : new Blob(i)).size) {
|
|
149
|
+
this._activeSessionId === e && (this._activeSessionId = null), this._mediaRecorderStopReason = null, this._recordedChunks = [], this._set("errorCode", "recording-failed");
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
this._set("state", "processing"), this._set("transcript", d(`${this.transcript} ${this.liveTranscript}`)), this._set("liveTranscript", ""), this._activeSessionId === e && (this._activeSessionId = null), this._set("state", "idle"), this._set("errorCode", void 0), this._mediaRecorderStopReason = null, this._recordedChunks = [];
|
|
153
|
+
}
|
|
154
|
+
start() {
|
|
155
|
+
if (!c.isSupported()) {
|
|
156
|
+
this._set("errorCode", "not-supported");
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
const t = Date.now();
|
|
160
|
+
this._activeSessionId = t, this._mediaRecorderChunkIndex = 0, this._mediaRecorderStopReason = null, this._pendingChunkOperations.clear(), this._recordedChunks = [], this._set("liveTranscript", ""), this._set("transcript", ""), this._set("errorCode", void 0), navigator.mediaDevices.getUserMedia({ audio: !0 }).then((e) => {
|
|
161
|
+
if (t !== this._activeSessionId) {
|
|
162
|
+
e.getTracks().forEach((i) => i.stop());
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
const s = this._mimeType, r = s ? new window.MediaRecorder(e, { mimeType: s }) : new window.MediaRecorder(e);
|
|
166
|
+
this._mediaStream = e, this._mediaRecorder = r, this._mediaRecorderChunkIndex = 0, this._mediaRecorderStopReason = null, this._recordedChunks = [], r.ondataavailable = this._onDataAvailable.bind(this), r.onerror = this._onError.bind(this), r.onstart = this._onStart.bind(this), r.onstop = this._onStop.bind(this), this._mediaRecorder.start(this.chunkTimeSlice);
|
|
167
|
+
}).catch((e) => {
|
|
168
|
+
t === this._activeSessionId && (this._activeSessionId = null, this._mediaRecorder = null, this._mediaRecorderChunkIndex = 0, this._mediaRecorderStopReason = null, this._pendingChunkOperations.clear(), this._recordedChunks = [], this._releaseMediaStream(), e instanceof DOMException && e.name === "NotAllowedError" ? this._set("errorCode", "not-allowed") : this._set("errorCode", "recording-failed"));
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
stop() {
|
|
172
|
+
if (this._mediaRecorder) {
|
|
173
|
+
this._mediaRecorderStopReason = "toggle";
|
|
174
|
+
try {
|
|
175
|
+
this._mediaRecorder.state !== "inactive" ? this._mediaRecorder.stop() : this._handleStop();
|
|
176
|
+
} catch {
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
cancel() {
|
|
181
|
+
const t = this._mediaRecorder;
|
|
182
|
+
if (this._activeSessionId = null, this._mediaRecorderStopReason = "cancel", this._mediaRecorderChunkIndex = 0, this._pendingChunkOperations.clear(), this._recordedChunks = [], this._set("liveTranscript", ""), this._set("transcript", ""), this._set("state", "idle"), this._set("errorCode", void 0), !t) {
|
|
183
|
+
this._releaseMediaStream();
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
try {
|
|
187
|
+
if (t.state !== "inactive") {
|
|
188
|
+
t.stop();
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
} catch {
|
|
192
|
+
}
|
|
193
|
+
this._mediaRecorder = null, this._releaseMediaStream();
|
|
194
|
+
}
|
|
195
|
+
static isSupported() {
|
|
196
|
+
return typeof window < "u" && !!(window.MediaRecorder && navigator.mediaDevices?.getUserMedia);
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
g([
|
|
200
|
+
l()
|
|
201
|
+
], c.prototype, "_mimeType", 1);
|
|
202
|
+
g([
|
|
203
|
+
l()
|
|
204
|
+
], c.prototype, "handleRecording", 2);
|
|
205
|
+
g([
|
|
206
|
+
l()
|
|
207
|
+
], c.prototype, "chunkTimeSlice", 2);
|
|
208
|
+
c = g([
|
|
209
|
+
m("MediaRecorderController")
|
|
210
|
+
], c);
|
|
211
|
+
var E = Object.getOwnPropertyDescriptor, $ = (t, e, s, r) => {
|
|
212
|
+
for (var i = r > 1 ? void 0 : r ? E(e, s) : e, n = t.length - 1, o; n >= 0; n--)
|
|
213
|
+
(o = t[n]) && (i = o(i) || i);
|
|
214
|
+
return i;
|
|
215
|
+
};
|
|
216
|
+
function b() {
|
|
217
|
+
if (typeof window > "u")
|
|
218
|
+
return null;
|
|
219
|
+
const t = window;
|
|
220
|
+
return t.SpeechRecognition ?? t.webkitSpeechRecognition ?? null;
|
|
221
|
+
}
|
|
222
|
+
let _ = class extends a {
|
|
223
|
+
constructor(t) {
|
|
224
|
+
super(t), this._isCancelled = !1, this._recognition = null;
|
|
225
|
+
}
|
|
226
|
+
initialize() {
|
|
227
|
+
const t = b();
|
|
228
|
+
if (!t)
|
|
229
|
+
return;
|
|
230
|
+
const e = new t();
|
|
231
|
+
e.continuous = !0, e.interimResults = !0, this.language && (e.lang = this.language), e.onstart = this._onStart.bind(this), e.onresult = this._onResult.bind(this), e.onerror = this._onError.bind(this), e.onend = this._onEnd.bind(this), e.onspeechend = this._onSpeechEnd.bind(this), this._recognition = e, this.addHandles(
|
|
232
|
+
f(
|
|
233
|
+
() => !!this.errorCode,
|
|
234
|
+
() => {
|
|
235
|
+
this._set("state", "error");
|
|
236
|
+
}
|
|
237
|
+
)
|
|
238
|
+
);
|
|
239
|
+
}
|
|
240
|
+
destroy() {
|
|
241
|
+
this._recognition && (this._recognition.onstart = null, this._recognition.onresult = null, this._recognition.onerror = null, this._recognition.onend = null, this._recognition.onspeechend = null, this.cancel(), this._recognition = null);
|
|
242
|
+
}
|
|
243
|
+
_onStart() {
|
|
244
|
+
this._isCancelled = !1, this._set("state", "listening");
|
|
245
|
+
}
|
|
246
|
+
// SpeechRecognition result lists are cumulative, so rebuild finalized and live text from the full list.
|
|
247
|
+
_onResult(t) {
|
|
248
|
+
const { finalTranscript: e, liveTranscript: s } = Array.from(t.results).reduce(
|
|
249
|
+
(r, i) => (i.isFinal ? r.finalTranscript += i[0].transcript : r.liveTranscript += i[0].transcript, r),
|
|
250
|
+
{ finalTranscript: "", liveTranscript: "" }
|
|
251
|
+
);
|
|
252
|
+
this._set("transcript", d(e)), this._set("liveTranscript", d(s));
|
|
253
|
+
}
|
|
254
|
+
_onError(t) {
|
|
255
|
+
if (t.error === "aborted" && this._isCancelled) {
|
|
256
|
+
this._set("state", "idle");
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
let e = "unhandled";
|
|
260
|
+
switch (t.error) {
|
|
261
|
+
case "no-speech":
|
|
262
|
+
e = "no-speech";
|
|
263
|
+
break;
|
|
264
|
+
case "service-not-allowed":
|
|
265
|
+
case "not-allowed":
|
|
266
|
+
e = "not-allowed";
|
|
267
|
+
break;
|
|
268
|
+
default:
|
|
269
|
+
e = "unhandled";
|
|
270
|
+
}
|
|
271
|
+
this._set("errorCode", e);
|
|
272
|
+
}
|
|
273
|
+
// Natural end can arrive before the last interim segment becomes final, so preserve that trailing text.
|
|
274
|
+
_onEnd() {
|
|
275
|
+
const t = d(`${this.transcript} ${this.liveTranscript}`);
|
|
276
|
+
if (this._set("liveTranscript", ""), this._isCancelled) {
|
|
277
|
+
this._set("transcript", ""), this._set("state", "idle"), this._set("errorCode", void 0);
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
this.errorCode ? this._set("transcript", "") : (this._set("transcript", t), this._set("state", "idle")), this._set("errorCode", void 0);
|
|
281
|
+
}
|
|
282
|
+
_onSpeechEnd() {
|
|
283
|
+
this._set("state", "processing");
|
|
284
|
+
}
|
|
285
|
+
_reset(t = !1) {
|
|
286
|
+
this._isCancelled = t, this._set("liveTranscript", ""), this._set("transcript", ""), this._set("errorCode", void 0), this._set("state", "idle");
|
|
287
|
+
}
|
|
288
|
+
start() {
|
|
289
|
+
if (!this._recognition) {
|
|
290
|
+
this._set("errorCode", "not-supported");
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
this._reset(!1);
|
|
294
|
+
try {
|
|
295
|
+
this._recognition.start();
|
|
296
|
+
} catch {
|
|
297
|
+
this._set("errorCode", "unhandled");
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
stop() {
|
|
301
|
+
if (this._recognition) {
|
|
302
|
+
this._set("state", "processing");
|
|
303
|
+
try {
|
|
304
|
+
this._recognition.stop();
|
|
305
|
+
} catch {
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
cancel() {
|
|
310
|
+
if (this._recognition) {
|
|
311
|
+
this._reset(!0);
|
|
312
|
+
try {
|
|
313
|
+
this._recognition.abort();
|
|
314
|
+
} catch {
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
static isSupported() {
|
|
319
|
+
return !!b();
|
|
320
|
+
}
|
|
321
|
+
};
|
|
322
|
+
_ = $([
|
|
323
|
+
m("WebSpeechController")
|
|
324
|
+
], _);
|
|
325
|
+
class D extends y {
|
|
326
|
+
constructor() {
|
|
327
|
+
super(...arguments), this._resolvedMode = "disabled", this.awaitingResponse = !1, this.mode = "web-speech", this.arcgisVoiceInputError = h(), this.arcgisVoiceInputStart = h(), this.arcgisVoiceInputStop = h(), this.arcgisVoiceInputInterimTranscription = h(), this.arcgisVoiceInputTranscription = h(), this.arcgisVoiceInputTranscriptionStreamChunk = h();
|
|
328
|
+
}
|
|
329
|
+
static {
|
|
330
|
+
this.properties = { _resolvedMode: 16, _state: 16, _errorCode: 16, _liveTranscript: 16, _transcript: 16, _isButtonDisabled: 16, _buttonLabel: 16, awaitingResponse: 5, language: 1, mode: 1 };
|
|
331
|
+
}
|
|
332
|
+
static {
|
|
333
|
+
this.styles = T;
|
|
334
|
+
}
|
|
335
|
+
get _state() {
|
|
336
|
+
return this._speechController?.state ?? "idle";
|
|
337
|
+
}
|
|
338
|
+
get _errorCode() {
|
|
339
|
+
return this._speechController?.errorCode ?? null;
|
|
340
|
+
}
|
|
341
|
+
get _liveTranscript() {
|
|
342
|
+
return this._speechController?.liveTranscript ?? "";
|
|
343
|
+
}
|
|
344
|
+
get _transcript() {
|
|
345
|
+
return this._speechController?.transcript ?? "";
|
|
346
|
+
}
|
|
347
|
+
get _isButtonDisabled() {
|
|
348
|
+
return this._resolvedMode === "disabled" || this.awaitingResponse || this._state === "processing";
|
|
349
|
+
}
|
|
350
|
+
get _buttonLabel() {
|
|
351
|
+
if (this.awaitingResponse)
|
|
352
|
+
return "Voice input unavailable while assistant is responding";
|
|
353
|
+
if (this._resolvedMode === "disabled")
|
|
354
|
+
return "Voice input unavailable";
|
|
355
|
+
switch (this._state) {
|
|
356
|
+
case "error":
|
|
357
|
+
return this._errorCode === "not-allowed" ? "Microphone permission denied. Retry voice input" : "Retry voice input";
|
|
358
|
+
case "listening":
|
|
359
|
+
return "Stop voice input";
|
|
360
|
+
case "processing":
|
|
361
|
+
return "Processing voice input";
|
|
362
|
+
default:
|
|
363
|
+
return "Start voice input";
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
loaded() {
|
|
367
|
+
this.manager.onLifecycle(() => [
|
|
368
|
+
u(() => [this.mode, this.language], () => {
|
|
369
|
+
this._configureController();
|
|
370
|
+
}, { initial: !0 }),
|
|
371
|
+
u(() => this.awaitingResponse, (e) => {
|
|
372
|
+
e && this._cancelActiveSession();
|
|
373
|
+
}, { initial: !0 }),
|
|
374
|
+
u(() => this._liveTranscript, (e) => {
|
|
375
|
+
if (e) {
|
|
376
|
+
const s = d(`${this._transcript} ${e}`);
|
|
377
|
+
this.arcgisVoiceInputInterimTranscription.emit({ transcript: s });
|
|
378
|
+
}
|
|
379
|
+
}),
|
|
380
|
+
u(() => this._transcript, (e) => {
|
|
381
|
+
e && this.arcgisVoiceInputTranscription.emit({ transcript: e });
|
|
382
|
+
}),
|
|
383
|
+
u(() => this._state, (e) => {
|
|
384
|
+
e === "error" && this._errorCode && this.arcgisVoiceInputError.emit({ errorCode: this._errorCode });
|
|
385
|
+
})
|
|
386
|
+
]);
|
|
387
|
+
}
|
|
388
|
+
disconnectedCallback() {
|
|
389
|
+
super.disconnectedCallback(), this._destroySpeechController();
|
|
390
|
+
}
|
|
391
|
+
_configureController() {
|
|
392
|
+
const e = this._resolveMode();
|
|
393
|
+
this._destroySpeechController(), this._resolvedMode = e, e !== "disabled" && (this._speechController = e === "web-speech" ? new _({
|
|
394
|
+
language: this.language
|
|
395
|
+
}) : new c({
|
|
396
|
+
language: this.language,
|
|
397
|
+
handleRecording: this._handleRecording.bind(this)
|
|
398
|
+
}));
|
|
399
|
+
}
|
|
400
|
+
_destroySpeechController() {
|
|
401
|
+
this._speechController?.cancel(), this._speechController?.destroy(), this._speechController = void 0;
|
|
402
|
+
}
|
|
403
|
+
async _handleToggle() {
|
|
404
|
+
if (!(this._isButtonDisabled || !this._speechController)) {
|
|
405
|
+
if (this._state === "listening") {
|
|
406
|
+
this._speechController.stop(), this.arcgisVoiceInputStop.emit();
|
|
407
|
+
return;
|
|
408
|
+
}
|
|
409
|
+
this._speechController.start(), this.arcgisVoiceInputStart.emit();
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
async _handleRecording(e, s, r, i) {
|
|
413
|
+
let n;
|
|
414
|
+
return this.arcgisVoiceInputTranscriptionStreamChunk.emit({
|
|
415
|
+
blob: e,
|
|
416
|
+
chunkIndex: r,
|
|
417
|
+
isFinal: i,
|
|
418
|
+
mimeType: s,
|
|
419
|
+
respondWithTranscript: (o) => {
|
|
420
|
+
n = o;
|
|
421
|
+
}
|
|
422
|
+
}), n;
|
|
423
|
+
}
|
|
424
|
+
_resolveMode() {
|
|
425
|
+
return this.mode === "disabled" ? "disabled" : this.mode === "web-speech" && _.isSupported() ? "web-speech" : c.isSupported() ? "media-recorder" : "disabled";
|
|
426
|
+
}
|
|
427
|
+
async _cancelActiveSession() {
|
|
428
|
+
this._speechController && this._resolvedMode !== "disabled" && this._speechController.cancel();
|
|
429
|
+
}
|
|
430
|
+
render() {
|
|
431
|
+
return R`<calcite-button appearance=transparent class="assistant-chat-entry-speech-input__button" data-mode=${this._resolvedMode ?? v} data-state=${(this._resolvedMode === "disabled" ? "disabled" : this._state) ?? v} .disabled=${this._isButtonDisabled} icon-start=microphone kind=neutral .label=${this._buttonLabel} .loading=${this._state === "processing"} round scale=m @click=${() => void this._handleToggle()}></calcite-button>`;
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
C("arcgis-assistant-chat-entry-speech-input", D);
|
|
435
|
+
export {
|
|
436
|
+
D as ArcgisAssistantChatEntrySpeechInput
|
|
437
|
+
};
|