@burdenoff/website-sdk 2026.1105.3 → 2026.1106.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +79 -0
- package/dist/avatar-live-view/index.d.mts +1 -1
- package/dist/avatar-live-view/index.d.ts +1 -1
- package/dist/avatar-live-view/index.js +850 -175
- package/dist/avatar-live-view/index.js.map +1 -1
- package/dist/avatar-live-view/index.mjs +843 -168
- package/dist/avatar-live-view/index.mjs.map +1 -1
- package/dist/avatar-mic/index.d.mts +54 -60
- package/dist/avatar-mic/index.d.ts +54 -60
- package/dist/avatar-mic/index.js +283 -23
- package/dist/avatar-mic/index.js.map +1 -1
- package/dist/avatar-mic/index.mjs +283 -23
- package/dist/avatar-mic/index.mjs.map +1 -1
- package/dist/{chunk-JGU6JW4N.mjs → chunk-BHEHF3Y5.mjs} +2 -2
- package/dist/{chunk-JGU6JW4N.mjs.map → chunk-BHEHF3Y5.mjs.map} +1 -1
- package/dist/{chunk-3AIAJ2L4.js → chunk-Z2UP22GV.js} +2 -2
- package/dist/{chunk-3AIAJ2L4.js.map → chunk-Z2UP22GV.js.map} +1 -1
- package/dist/{explore-avatar-live-config-1zeXdMer.d.ts → explore-avatar-live-config-CJstiSAN.d.ts} +5 -1
- package/dist/{explore-avatar-live-config-BxiE66Im.d.mts → explore-avatar-live-config-D2PGF8fG.d.mts} +5 -1
- package/dist/index.d.mts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +5 -5
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
package/dist/avatar-mic/index.js
CHANGED
|
@@ -2,6 +2,146 @@
|
|
|
2
2
|
|
|
3
3
|
var chunkZSTFX7FV_js = require('../chunk-ZSTFX7FV.js');
|
|
4
4
|
|
|
5
|
+
// src/avatar-mic/speech-words.ts
|
|
6
|
+
var FILLERS = /* @__PURE__ */ new Set([
|
|
7
|
+
"uh",
|
|
8
|
+
"um",
|
|
9
|
+
"uhm",
|
|
10
|
+
"umm",
|
|
11
|
+
"er",
|
|
12
|
+
"erm",
|
|
13
|
+
"eh",
|
|
14
|
+
"ah",
|
|
15
|
+
"hm",
|
|
16
|
+
"hmm",
|
|
17
|
+
"hmmm",
|
|
18
|
+
"mm",
|
|
19
|
+
"mmm",
|
|
20
|
+
"mhm",
|
|
21
|
+
"huh",
|
|
22
|
+
"oh",
|
|
23
|
+
"so",
|
|
24
|
+
"well",
|
|
25
|
+
"okay",
|
|
26
|
+
"ok",
|
|
27
|
+
"and",
|
|
28
|
+
"like",
|
|
29
|
+
"hey",
|
|
30
|
+
"hi",
|
|
31
|
+
"hello",
|
|
32
|
+
"actually"
|
|
33
|
+
]);
|
|
34
|
+
var OPEN_ENDINGS = /* @__PURE__ */ new Set([
|
|
35
|
+
"the",
|
|
36
|
+
"a",
|
|
37
|
+
"an",
|
|
38
|
+
"of",
|
|
39
|
+
"to",
|
|
40
|
+
"for",
|
|
41
|
+
"about",
|
|
42
|
+
"and",
|
|
43
|
+
"or",
|
|
44
|
+
"but",
|
|
45
|
+
"what",
|
|
46
|
+
"how",
|
|
47
|
+
"which",
|
|
48
|
+
"is",
|
|
49
|
+
"are",
|
|
50
|
+
"can"
|
|
51
|
+
]);
|
|
52
|
+
var PRONOUNS = /* @__PURE__ */ new Set([
|
|
53
|
+
"i",
|
|
54
|
+
"me",
|
|
55
|
+
"you",
|
|
56
|
+
"it",
|
|
57
|
+
"we",
|
|
58
|
+
"us",
|
|
59
|
+
"they",
|
|
60
|
+
"them",
|
|
61
|
+
"he",
|
|
62
|
+
"him",
|
|
63
|
+
"she",
|
|
64
|
+
"her",
|
|
65
|
+
"this",
|
|
66
|
+
"that",
|
|
67
|
+
"these",
|
|
68
|
+
"those"
|
|
69
|
+
]);
|
|
70
|
+
var ECHO_MIN_WORDS = 3;
|
|
71
|
+
var SELF_CONTAINED_SCRIPT = /[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Hangul}]/u;
|
|
72
|
+
function tidyWords(text) {
|
|
73
|
+
return text.replace(/\s+/g, " ").trim();
|
|
74
|
+
}
|
|
75
|
+
function speechWords(text) {
|
|
76
|
+
const flat = text.toLowerCase().replace(/[^\p{L}\p{M}\p{N}]+/gu, " ").trim();
|
|
77
|
+
return flat === "" ? [] : flat.split(" ");
|
|
78
|
+
}
|
|
79
|
+
function startsWithWords(whole, head) {
|
|
80
|
+
return head.length <= whole.length && head.every((word, index) => whole[index] === word);
|
|
81
|
+
}
|
|
82
|
+
function endsWithWords(whole, tail) {
|
|
83
|
+
return tail.length <= whole.length && tail.every(
|
|
84
|
+
(word, index) => whole[whole.length - tail.length + index] === word
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
function startsWithWordsOf(text, head) {
|
|
88
|
+
return startsWithWords(speechWords(text), speechWords(head));
|
|
89
|
+
}
|
|
90
|
+
function mergeTurnPhrase(turn, phrase) {
|
|
91
|
+
const heard = speechWords(turn);
|
|
92
|
+
const incoming = speechWords(phrase);
|
|
93
|
+
if (incoming.length === 0) return turn;
|
|
94
|
+
if (heard.length === 0) return tidyWords(phrase);
|
|
95
|
+
if (startsWithWords(incoming, heard)) {
|
|
96
|
+
return incoming.length === heard.length ? turn : tidyWords(phrase);
|
|
97
|
+
}
|
|
98
|
+
if (incoming.length >= 2 && endsWithWords(heard, incoming)) return turn;
|
|
99
|
+
return tidyWords(`${turn} ${phrase}`);
|
|
100
|
+
}
|
|
101
|
+
function mergeInterim(turn, interim) {
|
|
102
|
+
const said = tidyWords(interim);
|
|
103
|
+
if (said === "") return turn;
|
|
104
|
+
const head = speechWords(turn);
|
|
105
|
+
if (head.length === 0) return said;
|
|
106
|
+
const tokens = said.split(" ");
|
|
107
|
+
let matched = 0;
|
|
108
|
+
for (let at = 0; at < tokens.length; at += 1) {
|
|
109
|
+
const words = speechWords(tokens[at] ?? "");
|
|
110
|
+
for (const word of words) {
|
|
111
|
+
if (word !== head[matched]) return tidyWords(`${turn} ${said}`);
|
|
112
|
+
matched += 1;
|
|
113
|
+
if (matched === head.length) {
|
|
114
|
+
return tidyWords(`${turn} ${tokens.slice(at + 1).join(" ")}`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return tidyWords(`${turn} ${said}`);
|
|
119
|
+
}
|
|
120
|
+
function saidWords(words) {
|
|
121
|
+
return words.filter((word) => !FILLERS.has(word));
|
|
122
|
+
}
|
|
123
|
+
function isGenuineSpeech(text) {
|
|
124
|
+
const said = saidWords(speechWords(text));
|
|
125
|
+
if (said.length === 1 && PRONOUNS.has(said[0] ?? "")) return false;
|
|
126
|
+
const content = said.filter((word) => !OPEN_ENDINGS.has(word));
|
|
127
|
+
if (content.length === 0) return false;
|
|
128
|
+
const letters = [...content.join("")];
|
|
129
|
+
if (letters.length >= 2) return true;
|
|
130
|
+
return letters.length === 1 && SELF_CONTAINED_SCRIPT.test(letters[0] ?? "");
|
|
131
|
+
}
|
|
132
|
+
function waitsLonger(text) {
|
|
133
|
+
const words = speechWords(text);
|
|
134
|
+
const last = words[words.length - 1];
|
|
135
|
+
if (last === void 0) return false;
|
|
136
|
+
return saidWords(words).length <= 1 || OPEN_ENDINGS.has(last) || FILLERS.has(last);
|
|
137
|
+
}
|
|
138
|
+
function isEchoOf(text, spoken) {
|
|
139
|
+
if (spoken === null) return false;
|
|
140
|
+
const heard = speechWords(text);
|
|
141
|
+
if (heard.length < ECHO_MIN_WORDS) return false;
|
|
142
|
+
return ` ${speechWords(spoken).join(" ")} `.includes(` ${heard.join(" ")} `);
|
|
143
|
+
}
|
|
144
|
+
|
|
5
145
|
// src/avatar-mic/browser-press.ts
|
|
6
146
|
var BROWSER_START_WAIT_MS = 15e3;
|
|
7
147
|
var BROWSER_FINAL_WAIT_MS = 3e3;
|
|
@@ -11,6 +151,11 @@ var BROWSER_MAX_QUICK_ENDS = 8;
|
|
|
11
151
|
var BROWSER_MAX_RESTARTS = 60;
|
|
12
152
|
var BROWSER_PRIME_SETTLE_MS = 250;
|
|
13
153
|
var BROWSER_GRANT_RETRY_MS = 350;
|
|
154
|
+
var BROWSER_PAUSE_MIN_MS = 2e3;
|
|
155
|
+
var BROWSER_PAUSE_MAX_MS = 2500;
|
|
156
|
+
var BROWSER_PAUSE_AFTER_START_MS = 1500;
|
|
157
|
+
var BROWSER_PAUSE_SHOWN_MS = 800;
|
|
158
|
+
var BROWSER_ECHO_WINDOW_MS = 2500;
|
|
14
159
|
var QUICK_END_MS = 1e3;
|
|
15
160
|
var NETWORK_FAILURES_FOR_GOOD = 2;
|
|
16
161
|
var IDLE = { name: "idle" };
|
|
@@ -82,8 +227,7 @@ function readRecognitionResults(results) {
|
|
|
82
227
|
continue;
|
|
83
228
|
}
|
|
84
229
|
const last = finals.length > 0 ? finals[finals.length - 1] : void 0;
|
|
85
|
-
|
|
86
|
-
if (last !== void 0 && (lower === last.toLowerCase() || lower.startsWith(`${last.toLowerCase()} `))) {
|
|
230
|
+
if (last !== void 0 && startsWithWordsOf(text, last)) {
|
|
87
231
|
finals[finals.length - 1] = text;
|
|
88
232
|
} else {
|
|
89
233
|
finals.push(text);
|
|
@@ -93,6 +237,11 @@ function readRecognitionResults(results) {
|
|
|
93
237
|
}
|
|
94
238
|
function createBrowserAvatarMic(options, seams = {}) {
|
|
95
239
|
const { createRecognition, now, primeMicrophone, watchMicPermission, touch } = { ...BROWSER, ...seams };
|
|
240
|
+
const { endpoint } = options;
|
|
241
|
+
const pauseMs = endpoint === void 0 || !Number.isFinite(endpoint.pauseMs) ? BROWSER_PAUSE_MIN_MS : Math.min(
|
|
242
|
+
BROWSER_PAUSE_MAX_MS,
|
|
243
|
+
Math.max(BROWSER_PAUSE_MIN_MS, endpoint.pauseMs)
|
|
244
|
+
);
|
|
96
245
|
let press = null;
|
|
97
246
|
let epoch = 0;
|
|
98
247
|
let state = IDLE;
|
|
@@ -106,14 +255,23 @@ function createBrowserAvatarMic(options, seams = {}) {
|
|
|
106
255
|
state = next;
|
|
107
256
|
options.onState(next);
|
|
108
257
|
};
|
|
109
|
-
const
|
|
258
|
+
const turnOf = (earlier, instance) => {
|
|
259
|
+
let turn = earlier;
|
|
260
|
+
for (const final of instance?.finals ?? []) {
|
|
261
|
+
turn = mergeTurnPhrase(turn, final);
|
|
262
|
+
}
|
|
263
|
+
return mergeInterim(turn, instance?.interim ?? "");
|
|
264
|
+
};
|
|
265
|
+
const heard = (p) => turnOf(p.earlier, p.instance);
|
|
110
266
|
const show = (p) => {
|
|
111
267
|
if (p.stage === "listening") {
|
|
268
|
+
const text = heard(p);
|
|
112
269
|
report({
|
|
113
270
|
name: "listening",
|
|
114
271
|
epoch: p.epoch,
|
|
115
272
|
startedAt: p.startedAt,
|
|
116
|
-
text
|
|
273
|
+
text,
|
|
274
|
+
...endpoint === void 0 ? {} : { genuine: isGenuineSpeech(text), pausing: p.pausing }
|
|
117
275
|
});
|
|
118
276
|
} else if (p.stage === "finishing") {
|
|
119
277
|
report({
|
|
@@ -140,7 +298,9 @@ function createBrowserAvatarMic(options, seams = {}) {
|
|
|
140
298
|
p.startTimer,
|
|
141
299
|
p.limitTimer,
|
|
142
300
|
p.finalTimer,
|
|
143
|
-
p.launchTimer
|
|
301
|
+
p.launchTimer,
|
|
302
|
+
p.pauseTimer,
|
|
303
|
+
p.pausingTimer
|
|
144
304
|
]) {
|
|
145
305
|
if (timer !== null) clearTimeout(timer);
|
|
146
306
|
}
|
|
@@ -148,6 +308,14 @@ function createBrowserAvatarMic(options, seams = {}) {
|
|
|
148
308
|
p.limitTimer = null;
|
|
149
309
|
p.finalTimer = null;
|
|
150
310
|
p.launchTimer = null;
|
|
311
|
+
p.pauseTimer = null;
|
|
312
|
+
p.pausingTimer = null;
|
|
313
|
+
};
|
|
314
|
+
const clearPause = (p) => {
|
|
315
|
+
if (p.pauseTimer !== null) clearTimeout(p.pauseTimer);
|
|
316
|
+
if (p.pausingTimer !== null) clearTimeout(p.pausingTimer);
|
|
317
|
+
p.pauseTimer = null;
|
|
318
|
+
p.pausingTimer = null;
|
|
151
319
|
};
|
|
152
320
|
const settle = (p, next) => {
|
|
153
321
|
if (p.stage === "ended") return;
|
|
@@ -162,23 +330,104 @@ function createBrowserAvatarMic(options, seams = {}) {
|
|
|
162
330
|
const complete = (p) => {
|
|
163
331
|
const text = heard(p);
|
|
164
332
|
if (text !== "") networkFailures = 0;
|
|
165
|
-
|
|
333
|
+
if (endpoint === void 0) {
|
|
334
|
+
settle(p, { name: "done", epoch: p.epoch, text, limit: p.limit });
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
const by = p.stage === "finishing" ? p.by ?? "tap" : p.stage === "starting" ? "silence" : "failed";
|
|
338
|
+
const echo = by === "pause" && p.speechAt !== null && p.speechAt - p.listenedAt <= BROWSER_ECHO_WINDOW_MS && isEchoOf(text, endpoint.echoOf());
|
|
339
|
+
settle(p, {
|
|
340
|
+
name: "done",
|
|
341
|
+
epoch: p.epoch,
|
|
342
|
+
text,
|
|
343
|
+
limit: p.limit,
|
|
344
|
+
by,
|
|
345
|
+
echo
|
|
346
|
+
});
|
|
166
347
|
};
|
|
167
348
|
const fail = (p, reason) => settle(p, { name: "failed", epoch: p.epoch, reason, text: heard(p) });
|
|
168
349
|
const current = (p, instance) => press === p && p.stage !== "ended" && p.instance === instance;
|
|
350
|
+
const armPause = (p, turn, speech) => {
|
|
351
|
+
clearPause(p);
|
|
352
|
+
if (!speech) return;
|
|
353
|
+
const at = now();
|
|
354
|
+
if (!p.pausing) {
|
|
355
|
+
p.pausingTimer = setTimeout(
|
|
356
|
+
() => {
|
|
357
|
+
p.pausingTimer = null;
|
|
358
|
+
if (press !== p || p.stage !== "listening") return;
|
|
359
|
+
p.pausing = true;
|
|
360
|
+
show(p);
|
|
361
|
+
},
|
|
362
|
+
Math.max(0, p.wordsAt + BROWSER_PAUSE_SHOWN_MS - at)
|
|
363
|
+
);
|
|
364
|
+
}
|
|
365
|
+
const instance = p.instance;
|
|
366
|
+
if (instance === null || !instance.started) return;
|
|
367
|
+
const wait = waitsLonger(turn) ? 2 * pauseMs : pauseMs;
|
|
368
|
+
const due = Math.max(
|
|
369
|
+
p.wordsAt + wait,
|
|
370
|
+
instance.startedAt + BROWSER_PAUSE_AFTER_START_MS
|
|
371
|
+
);
|
|
372
|
+
p.pauseTimer = setTimeout(
|
|
373
|
+
() => {
|
|
374
|
+
p.pauseTimer = null;
|
|
375
|
+
if (press === p && p.stage === "listening" && p.instance === instance) {
|
|
376
|
+
stopRecording(p, "pause");
|
|
377
|
+
}
|
|
378
|
+
},
|
|
379
|
+
Math.max(0, due - at)
|
|
380
|
+
);
|
|
381
|
+
};
|
|
382
|
+
const listenOn = (p) => {
|
|
383
|
+
if (endpoint === void 0 || p.stage !== "listening") return;
|
|
384
|
+
const turn = heard(p);
|
|
385
|
+
const words = speechWords(turn).join(" ");
|
|
386
|
+
const at = now();
|
|
387
|
+
if (words !== p.words) {
|
|
388
|
+
p.words = words;
|
|
389
|
+
p.wordsAt = at;
|
|
390
|
+
p.pausing = false;
|
|
391
|
+
}
|
|
392
|
+
const speech = isGenuineSpeech(turn);
|
|
393
|
+
if (speech && p.speechAt === null) {
|
|
394
|
+
p.speechAt = at;
|
|
395
|
+
if (p.limitTimer !== null) clearTimeout(p.limitTimer);
|
|
396
|
+
p.limitTimer = setTimeout(() => {
|
|
397
|
+
p.limitTimer = null;
|
|
398
|
+
if (press === p) stopRecording(p, "limit");
|
|
399
|
+
}, options.maxPressMs);
|
|
400
|
+
}
|
|
401
|
+
armPause(p, turn, speech);
|
|
402
|
+
};
|
|
169
403
|
const began = (p, instance) => {
|
|
170
404
|
instance.started = true;
|
|
171
405
|
instance.startedAt = now();
|
|
172
406
|
hadMicrophone = true;
|
|
173
|
-
if (p.stage
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
p.limitTimer =
|
|
180
|
-
|
|
181
|
-
|
|
407
|
+
if (p.stage === "starting") {
|
|
408
|
+
if (p.startTimer !== null) clearTimeout(p.startTimer);
|
|
409
|
+
p.startTimer = null;
|
|
410
|
+
p.stage = "listening";
|
|
411
|
+
p.startedAt = Date.now();
|
|
412
|
+
p.listenedAt = instance.startedAt;
|
|
413
|
+
p.limitTimer = setTimeout(() => {
|
|
414
|
+
p.limitTimer = null;
|
|
415
|
+
if (press !== p) return;
|
|
416
|
+
if (endpoint === void 0) {
|
|
417
|
+
stopRecording(p, "limit");
|
|
418
|
+
} else if (p.stage === "listening" && p.speechAt === null) {
|
|
419
|
+
settle(p, {
|
|
420
|
+
name: "done",
|
|
421
|
+
epoch: p.epoch,
|
|
422
|
+
text: "",
|
|
423
|
+
limit: false,
|
|
424
|
+
by: "silence",
|
|
425
|
+
echo: false
|
|
426
|
+
});
|
|
427
|
+
}
|
|
428
|
+
}, options.maxPressMs);
|
|
429
|
+
}
|
|
430
|
+
listenOn(p);
|
|
182
431
|
};
|
|
183
432
|
const launchIn = (p, delay) => {
|
|
184
433
|
if (delay <= 0) {
|
|
@@ -204,9 +453,7 @@ function createBrowserAvatarMic(options, seams = {}) {
|
|
|
204
453
|
);
|
|
205
454
|
};
|
|
206
455
|
const keep = (p, instance) => {
|
|
207
|
-
|
|
208
|
-
if (text !== "") p.earlier.push(text);
|
|
209
|
-
}
|
|
456
|
+
p.earlier = turnOf(p.earlier, instance);
|
|
210
457
|
};
|
|
211
458
|
const onError = (p, instance, code) => {
|
|
212
459
|
if (code === "no-speech") {
|
|
@@ -272,6 +519,8 @@ function createBrowserAvatarMic(options, seams = {}) {
|
|
|
272
519
|
else fail(p, "failed");
|
|
273
520
|
return;
|
|
274
521
|
case "listening": {
|
|
522
|
+
if (p.pauseTimer !== null) clearTimeout(p.pauseTimer);
|
|
523
|
+
p.pauseTimer = null;
|
|
275
524
|
const quick = !instance.started || now() - instance.startedAt < QUICK_END_MS && instance.finals.length === 0 && instance.interim === "";
|
|
276
525
|
restart(p, quick ? "quick" : "listened");
|
|
277
526
|
return;
|
|
@@ -318,6 +567,7 @@ function createBrowserAvatarMic(options, seams = {}) {
|
|
|
318
567
|
const read = readRecognitionResults(event.results);
|
|
319
568
|
instance.finals = read.finals;
|
|
320
569
|
instance.interim = read.interim;
|
|
570
|
+
listenOn(p);
|
|
321
571
|
show(p);
|
|
322
572
|
};
|
|
323
573
|
recognition.onerror = (event) => {
|
|
@@ -361,14 +611,16 @@ function createBrowserAvatarMic(options, seams = {}) {
|
|
|
361
611
|
}
|
|
362
612
|
);
|
|
363
613
|
}
|
|
364
|
-
function stopRecording(p,
|
|
614
|
+
function stopRecording(p, by) {
|
|
365
615
|
if (p.stage !== "listening") return;
|
|
366
616
|
if (p.limitTimer !== null) clearTimeout(p.limitTimer);
|
|
367
617
|
if (p.launchTimer !== null) clearTimeout(p.launchTimer);
|
|
368
618
|
p.limitTimer = null;
|
|
369
619
|
p.launchTimer = null;
|
|
620
|
+
clearPause(p);
|
|
370
621
|
p.stage = "finishing";
|
|
371
|
-
p.limit = limit;
|
|
622
|
+
p.limit = by === "limit";
|
|
623
|
+
p.by = by;
|
|
372
624
|
const instance = p.instance;
|
|
373
625
|
if (instance === null || !instance.started) {
|
|
374
626
|
complete(p);
|
|
@@ -416,7 +668,7 @@ function createBrowserAvatarMic(options, seams = {}) {
|
|
|
416
668
|
epoch,
|
|
417
669
|
stage: "starting",
|
|
418
670
|
instance: null,
|
|
419
|
-
earlier:
|
|
671
|
+
earlier: "",
|
|
420
672
|
lang: options.lang,
|
|
421
673
|
langRetried: false,
|
|
422
674
|
restarts: 0,
|
|
@@ -429,7 +681,15 @@ function createBrowserAvatarMic(options, seams = {}) {
|
|
|
429
681
|
startTimer: null,
|
|
430
682
|
limitTimer: null,
|
|
431
683
|
finalTimer: null,
|
|
432
|
-
launchTimer: null
|
|
684
|
+
launchTimer: null,
|
|
685
|
+
by: null,
|
|
686
|
+
words: "",
|
|
687
|
+
wordsAt: 0,
|
|
688
|
+
speechAt: null,
|
|
689
|
+
listenedAt: 0,
|
|
690
|
+
pausing: false,
|
|
691
|
+
pauseTimer: null,
|
|
692
|
+
pausingTimer: null
|
|
433
693
|
};
|
|
434
694
|
press = p;
|
|
435
695
|
report({ name: "starting", epoch });
|
|
@@ -446,7 +706,7 @@ function createBrowserAvatarMic(options, seams = {}) {
|
|
|
446
706
|
const p = press;
|
|
447
707
|
if (p === null) return;
|
|
448
708
|
if (p.stage === "starting") cancel();
|
|
449
|
-
else stopRecording(p,
|
|
709
|
+
else stopRecording(p, "tap");
|
|
450
710
|
},
|
|
451
711
|
cancel,
|
|
452
712
|
state: () => state
|