@seams/voiceid 0.44.0 → 0.46.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/README.md +7 -4
- package/dist/esm/capture/prompt.js +9 -0
- package/dist/public/sdk/voiceid/addVoiceId-eGEbWa1n.js +1 -0
- package/dist/public/sdk/voiceid/deviceBridge-DTN7sn5D.js +1 -0
- package/dist/public/sdk/voiceid/host.js +2 -2
- package/dist/public/sdk/voiceid/operation-C2wM5i7x.js +1 -0
- package/dist/public/sdk/voiceid/{prompt-DsRKGfyb.js → prompt-BMATEY7H.js} +9 -0
- package/dist/public/sdk/voiceid/unlock-C1jW7c3K.js +1 -0
- package/dist/types/capture/deviceBridge.d.ts +2 -1
- package/dist/types/capture/surface.d.ts +4 -1
- package/dist/types/host.d.ts +1 -1
- package/dist/types/session/operation.d.ts +4 -0
- package/package.json +2 -2
- package/dist/public/sdk/voiceid/addVoiceId-B2XmPljL.js +0 -1
- package/dist/public/sdk/voiceid/deviceBridge-vf25pKzp.js +0 -1
- package/dist/public/sdk/voiceid/unlock-DdzR0kE9.js +0 -1
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ and the trusted host API. Existing voice enrollments keep their storage identity
|
|
|
10
10
|
Install matching Wallet and VoiceID versions, then import the descriptor:
|
|
11
11
|
|
|
12
12
|
```sh
|
|
13
|
-
pnpm add @seams/wallet@0.
|
|
13
|
+
pnpm add @seams/wallet@0.46.0 @seams/voiceid@0.46.0
|
|
14
14
|
```
|
|
15
15
|
|
|
16
16
|
```ts
|
|
@@ -51,9 +51,12 @@ The optional `VoiceBeam` and `VoiceAssistantCard` visuals are exported from
|
|
|
51
51
|
|
|
52
52
|
VoiceID works like a passkey. A VoiceID unlock opens a normal signing session.
|
|
53
53
|
Each operation on any chain shows the ordinary **Confirm**, with no further voice
|
|
54
|
-
check, within the session's uses and expiry. When the session
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
check, within the session's uses and expiry. When the session runs out or
|
|
55
|
+
expires, the next operation asks for VoiceID again inside the Wallet, then signs. A
|
|
56
|
+
transaction asks inside its own confirm card: **Confirm with VoiceID**, the voice
|
|
57
|
+
capture in the same card, then the receipt.
|
|
58
|
+
It never asks for a passkey. Key export asks for one more voice check, bound to
|
|
59
|
+
that export, and never for a passkey or Email OTP.
|
|
57
60
|
|
|
58
61
|
## Install on the Wallet host
|
|
59
62
|
|
|
@@ -4,6 +4,15 @@ import { createCspStylesheetManager, getDefaultCspNonce } from "@seams/wallet/vo
|
|
|
4
4
|
//#region src/capture/prompt.ts
|
|
5
5
|
const CSS = `
|
|
6
6
|
.seams-voiceid-activation-surface { width: min(100%, 26.25rem); margin: 0 auto; background: transparent; }
|
|
7
|
+
/* Inside an operation's card the card is the frame: the prompt fills it edge to edge. */
|
|
8
|
+
.seams-voiceid-activation-surface.seams-voiceid-in-card { width: 100%; }
|
|
9
|
+
.seams-voiceid-in-card .seams-voiceid-prompt {
|
|
10
|
+
width: 100%;
|
|
11
|
+
padding-top: 0.75rem;
|
|
12
|
+
border: 0;
|
|
13
|
+
border-radius: 0;
|
|
14
|
+
background: transparent;
|
|
15
|
+
}
|
|
7
16
|
|
|
8
17
|
.seams-voiceid-prompt {
|
|
9
18
|
box-sizing: border-box;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"./prompt-BMATEY7H.js";import{a as e,i as t,o as n,s as r,t as i}from"./deviceBridge-DTN7sn5D.js";import{WorkerDeferred as a,prepareVoiceOwner as o,toError as s}from"../voiceid-host.js";const c=`http://www.w3.org/2000/svg`;async function l(e,t,n,r,i){let a=new u(e,t,n,r,i);try{await a.result}finally{a.dispose()}}var u=class{completion=new a;result=this.completion.promise;document;element;enrollment;enrollmentValue;enrollmentSummary;startOver;status;actions;busy=!1;closed=!1;constructor(e,t,n,r,i){this.parent=e,this.confirmChange=t,this.scope=n,this.signal=r,this.model=i,this.document=e.ownerDocument,this.element=this.document.createElement(`div`),this.enrollment=this.document.createElement(`div`),this.enrollmentValue=this.document.createElement(`span`),this.enrollmentSummary=this.document.createElement(`span`),this.startOver=this.document.createElement(`p`),this.status=this.document.createElement(`p`),this.element.className=`seams-voiceid-prompt seams-voiceid-management`;let a=this.document.createElement(`div`);a.className=`seams-voiceid-management-header`;let o=this.document.createElement(`button`);o.type=`button`,o.className=`seams-voiceid-management-back`,o.setAttribute(`aria-label`,`Back`),o.append(d(this.document,`M15 6l-6 6 6 6`,20)),o.addEventListener(`click`,this.cancel);let s=this.document.createElement(`h2`);s.textContent=`Manage voice`,a.append(o,s);let c=this.document.createElement(`p`);c.className=`seams-voiceid-management-intro`,c.textContent=`Voice unlock on this device. Each change asks for your passkey.`,this.element.append(a,c,this.enrollmentRow()),this.actions={reset:this.resetAction(),improve:this.action(`improve`,`Improve recognition`,!0),import:this.action(`import`,`Use saved enrollment`,!1),replace:this.startOverAction()},this.status.setAttribute(`role`,`status`),this.element.append(this.status),this.enrollmentValue.textContent=`Checking…`,this.actions.import.button.hidden=!0,this.render(null,!1,!1),this.parent.replaceChildren(this.element),this.signal.addEventListener(`abort`,this.cancel,{once:!0}),this.refresh(),o.focus()}enrollmentRow(){this.enrollment.className=`seams-voiceid-management-enrollment`;let e=this.document.createElement(`span`);return e.textContent=`Enrollment`,this.enrollmentValue.className=`seams-voiceid-management-value`,this.enrollmentSummary.className=`seams-voiceid-management-summary`,this.enrollmentSummary.append(this.enrollmentValue),this.enrollment.append(e,this.enrollmentSummary),this.enrollment}resetAction(){let e=this.document.createElement(`button`);e.type=`button`,e.className=`seams-voiceid-management-reset`,e.textContent=`Reset`,e.setAttribute(`aria-label`,`Reset improvements`),e.addEventListener(`click`,this.begin.bind(this,`reset`));let t=this.document.createElement(`span`);return t.className=`seams-voiceid-management-enrollment-detail`,this.enrollmentSummary.append(t),this.enrollment.append(e),{button:e,title:e,detail:t,frame:this.enrollment}}startOverAction(){return this.startOver.className=`seams-voiceid-management-section`,this.startOver.textContent=`Start over`,this.element.append(this.startOver),this.action(`replace`,`Record voice again`,!1)}action(e,t,n){let r=this.document.createElement(`button`);r.type=`button`,r.className=`seams-voiceid-management-action`;let i=this.document.createElement(`span`),a=this.document.createElement(`span`);a.className=`seams-voiceid-management-action-heading`;let o=this.document.createElement(`span`);o.id=`seams-voiceid-management-${e}-title`,o.textContent=t,a.append(o);let s=[];if(n){let t=this.document.createElement(`span`);t.id=`seams-voiceid-management-${e}-chip`,t.className=`seams-voiceid-management-chip`,t.textContent=`Experimental`,a.append(t),s.push(t.id)}let c=this.document.createElement(`span`);return c.id=`seams-voiceid-management-${e}-detail`,c.className=`seams-voiceid-management-action-detail`,s.push(c.id),i.append(a,c),r.append(i,d(this.document,`M9 6l6 6-6 6`,16)),r.setAttribute(`aria-labelledby`,o.id),r.setAttribute(`aria-describedby`,s.join(` `)),r.disabled=!0,r.addEventListener(`click`,this.begin.bind(this,e)),this.element.append(r),{button:r,title:o,detail:c,frame:r}}async refresh(){try{let e=await r(this.scope),t=e?null:await n();if(this.closed)return;this.render(e,t!==null,!0)}catch(e){this.completion.reject(s(e))}}render(e,t,n){let r=e?.adaptation??null,{improve:i,reset:a,import:o,replace:s}=this.actions;n&&(this.enrollment.dataset.enrollment=r?.kind??`missing`,this.enrollmentValue.textContent=r===null?`Not on this device`:r.kind===`adapted`?`Improved`:`Original`,i.button.hidden=e===null,o.button.hidden=!t),a.button.hidden=r?.kind!==`adapted`,a.detail.textContent=r?.kind===`adapted`?`Saved on this device`:``,i.title.textContent=r?.kind===`adapted`?`Improve again`:`Improve recognition`,i.detail.textContent=r?.kind===`adapted`?`Replace the added samples. Your original enrollment stays.`:`Add three samples. They stay until you replace or reset them.`,o.detail.textContent=`Import the voice enrollment saved in this browser.`,s.detail.textContent=r?.kind===`adapted`?`Replace your enrollment and remove improvements.`:`Replace your enrollment with three new samples.`,this.startOver.hidden=i.button.hidden&&o.button.hidden;for(let e of Object.values(this.actions))delete e.frame.dataset.state,e.button.disabled=!n;this.status.textContent=``,delete this.status.dataset.placement}show(e,t,n){let r=this.actions[e];if(this.status.textContent=n,r.button.hidden){this.status.dataset.placement=`dialog`;return}r.frame.dataset.state=t,r.detail.textContent=n}begin(e){if(!(this.busy||this.closed)){this.busy=!0;for(let e of Object.values(this.actions))e.button.disabled=!0;this.show(e,`pending`,`Confirm with your passkey to continue.`),this.perform(e)}}async perform(n){try{let i=await o(this.scope,`enrolled`),a=await r(this.scope),s=await f(n,i,a?{kind:`present`,enrollment:a}:{kind:`missing`},this.signal),c=await this.confirmChange(s);switch(this.signal.throwIfAborted(),s.kind){case`improve`:await t(this.parent,{kind:`improve`,scope:this.scope,guard:s.guard,snapshot:s.snapshot,confirmation:c},this.signal,this.model);break;case`replace`:await t(this.parent,{kind:`replace`,scope:this.scope,guard:s.guard,snapshot:s.snapshot,confirmation:c},this.signal,this.model);break;case`reset`:await e({kind:`reset`,scope:this.scope,guard:s.guard,snapshot:s.snapshot,confirmation:c,signal:this.signal});break;case`import`:await e({kind:`import`,scope:this.scope,guard:s.guard,snapshot:s.snapshot,baseline:s.baseline,confirmation:c,signal:this.signal});break;default:return p(s)}this.closed||this.completion.resolve()}catch(e){if(this.closed)return;this.parent.replaceChildren(this.element),await this.refresh(),this.closed||this.show(n,`error`,e instanceof Error?e.message:`VoiceID could not be updated.`)}finally{this.busy=!1}}cancel=()=>{this.closed||(this.closed=!0,this.parent.dispatchEvent(new Event(`cancel`,{bubbles:!0})),this.completion.reject(Error(`VoiceID management was cancelled.`)))};dispose(){this.closed=!0,this.signal.removeEventListener(`abort`,this.cancel),this.element.remove()}};function d(e,t,n){let r=e.createElementNS(c,`svg`);r.setAttribute(`viewBox`,`0 0 24 24`),r.setAttribute(`width`,String(n)),r.setAttribute(`height`,String(n)),r.setAttribute(`aria-hidden`,`true`);let i=e.createElementNS(c,`path`);return i.setAttribute(`d`,t),i.setAttribute(`fill`,`none`),i.setAttribute(`stroke`,`currentColor`),i.setAttribute(`stroke-width`,`1.75`),i.setAttribute(`stroke-linecap`,`round`),i.setAttribute(`stroke-linejoin`,`round`),r.append(i),r}async function f(e,t,r,i){switch(e){case`replace`:return{kind:e,guard:t,snapshot:r,signal:i};case`import`:{if(r.kind!==`missing`)throw Error(`The previous enrollment is unavailable.`);let a=await n();if(!a)throw Error(`The previous enrollment is unavailable.`);return{kind:e,guard:t,snapshot:r,signal:i,baseline:a}}case`improve`:case`reset`:if(r.kind!==`present`)throw Error(`Record or import your original voice first.`);return{kind:e,guard:t,snapshot:r,signal:i};default:return p(e)}}function p(e){throw Error(`Unsupported VoiceID enrollment management action.`)}async function m(e,t,n,r){t.throwIfAborted();let i=await e.prepareActivation();return t.throwIfAborted(),i.kind===`enroll_existing`?{kind:`management`,action:h.bind(null,r,i,n)}:{kind:`recording`,action:g.bind(null,r,i,n),expiresAtMs:null}}async function h(e,t,n,r){return await l(n,t.confirmChange,t.scope,r,e),r.throwIfAborted(),{kind:`activated`,walletId:t.scope.walletId,walletAuthMethodId:t.scope.walletAuthMethodId}}function g(e,t,n,r,a,o){return t.activate(i.bind(null,e,{parent:n,onCapture:a,phrase:o}),r)}export{m as prepareActivationSurface};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{_ as e,a as t,c as n,d as r,f as i,g as a,h as o,i as s,m as c,o as ee,p as l,s as u,t as d,u as f,v as p}from"./prompt-BMATEY7H.js";import{WorkerDeferred as m,assertVoiceOwner as h,base64UrlEncode as g,createBrowserVoiceDevice as _,isFiniteNumber as v,openBrowserVoiceFactor as y,parseVoiceIdDeviceAssertion as te,parseVoiceIdOperationAssertion as b,prepareVoiceOwner as x,readBrowserVoiceDevice as S,requireRecord as C,resolveActivatingVoiceEnrollmentScope as w,resolveVoiceEnrollmentScope as T,toError as E,voiceEnrollmentStorage as D,voiceIdOperationStatementBytes as O,voiceIdWalletSessionChallengeBytes as k}from"../voiceid-host.js";const A=`e04dd7a6a1e23fc7b89e47682ea9d0a3946cf7bc59d07922c3db3efc52ae4269`,j=`redimnet-b1:${A}`,M=new o({path:`/sdk/voiceid/redimnet-b1.onnx`,sha256:A,bytes:8859593,label:`Speaker verification`});async function N(e){let t=await M.prepare(),n=new(await(import(`./ort.wasm.bundle.min-7y-hlRN8.js`))).Tensor(`float32`,e,[1,e.length]);try{let e=await t.run({samples:n});try{let t=e.embedding;if(!t||!(t.data instanceof Float32Array))throw Error(`VoiceID model returned an invalid embedding.`);return P(Array.from(t.data))}finally{for(let t of Object.values(e))t.dispose()}}finally{n.dispose()}}function P(e){if(e.length!==192)throw Error(`VoiceID template dimensions are invalid.`);let t=0;for(let n of e){if(!Number.isFinite(n))throw Error(`VoiceID template is invalid.`);t+=n*n}if(t<1e-12)throw Error(`VoiceID template contains no signal.`);let n=Math.sqrt(t),r=[];for(let t of e)r.push(t/n);return r}function F(e,t){if(e.length!==192||t.length!==192)throw Error(`VoiceID templates are incompatible.`);let n=0;for(let r=0;r<e.length;r+=1)n+=e[r]*t[r];return n}function I(e){return e.asset}function L(e,t){return e+t.size}var R=class{element=document.createElement(`section`);status=document.createElement(`p`);meter=document.createElement(`progress`);retryButton=document.createElement(`button`);retry=null;cancelled=new m;reveal;received=new Map;models;assets;total;constructor(t,n,r){this.parent=t,this.signal=n,this.models=[M,l(r),f],this.assets=[e,...this.models.map(I)],this.total=this.assets.reduce(L,0),this.element.className=`seams-voiceid-model-download`,this.status.setAttribute(`role`,`status`),this.status.setAttribute(`aria-live`,`polite`),this.meter.setAttribute(`aria-label`,`VoiceID download`),this.meter.style.width=`100%`,this.retryButton.type=`button`,this.retryButton.className=`seams-voiceid-primary`,this.retryButton.textContent=`Retry loading`,this.retryButton.hidden=!0,this.retryButton.addEventListener(`click`,this.retryLoading),this.element.append(this.status,this.meter,this.retryButton),this.status.textContent=`Loading saved VoiceID…`,this.reveal=setTimeout(t.append.bind(t,this.element),300),n.addEventListener(`abort`,this.abort,{once:!0})}settle=()=>{clearTimeout(this.reveal),this.signal.removeEventListener(`abort`,this.abort),this.retryButton.removeEventListener(`click`,this.retryLoading)};abort=()=>{let e=new DOMException(`VoiceID preparation was cancelled.`,`AbortError`);this.cancelled.reject(e),this.retry?.reject(e)};retryLoading=()=>{this.retry?.resolve(),this.retry=null};async prepare(){this.signal.throwIfAborted(),await Promise.race([this.prepareUntilReady(),this.cancelled.promise])}async prepareUntilReady(){for(;;){this.signal.throwIfAborted(),this.retryButton.hidden=!0,this.meter.hidden=!1;try{for(let e of this.assets)await e.download(this.update.bind(this,e)),this.signal.throwIfAborted();this.preparing();for(let e of this.models)await e.prepare(),this.signal.throwIfAborted();this.ready();return}catch(e){if(this.signal.throwIfAborted(),!(e instanceof a))throw e;clearTimeout(this.reveal),this.parent.append(this.element),this.element.dataset.state=`failed`,this.meter.hidden=!0,this.status.textContent=e.message,this.retry=new m,this.retryButton.hidden=!1,this.retryButton.focus(),await this.retry.promise}}}update=(e,t)=>{switch(t.kind){case`checking_cache`:return;case`downloading`:this.received.set(e,t.received),this.element.dataset.state=`downloading`;break;case`ready`:this.received.set(e,e.size);break;default:}if(this.element.dataset.state!==`downloading`)return;let n=0;for(let e of this.received.values())n+=e;this.meter.max=this.total,this.meter.value=n,this.status.textContent=`Downloading VoiceID: ${(n/1e6).toFixed(1)} of ${(this.total/1e6).toFixed(1)} MB · ${Math.floor(n/this.total*100)}%`};preparing(){this.element.dataset.state=`preparing`,this.meter.removeAttribute(`value`),this.status.textContent=`Preparing VoiceID…`}ready(){this.element.dataset.state=`ready`,this.meter.hidden=!0,this.status.textContent=`VoiceID is ready.`}};async function z(e,t,n){let r=new R(e,t,n);try{await r.prepare()}finally{r.settle()}}const B=.2,V=D({model:j,parseEnrollment:U});function H(e){if(!Array.isArray(e)||!e.every(v))throw Error(`VoiceID template is invalid.`);let t=P(e);for(let n=0;n<e.length;n+=1)if(Math.abs(e[n]-t[n])>1e-6)throw Error(`VoiceID template is not normalized.`);return e.slice()}function U(e,t){if(e===void 0)return null;let n=C(e,`VoiceID enrollment`),r=C(n.scope,`VoiceID enrollment scope`);if(n.kind!==`browser_voiceid_enrollment_v2`||r.walletId!==t.walletId||r.authorityId!==t.authorityId||r.walletAuthMethodId!==t.walletAuthMethodId||r.deviceKeyId!==t.deviceKeyId||typeof n.generation!=`string`||!n.generation||typeof n.revision!=`number`||!Number.isSafeInteger(n.revision)||n.revision<0)throw Error(`VoiceID enrollment identity is invalid.`);if(n.model!==j)return null;let i=H(n.baseline),a={kind:`baseline`};try{let e=C(n.adaptation,`VoiceID improvements`);if(e.kind===`adapted`&&Array.isArray(e.samples)&&e.samples.length===3){let t=e.samples.map(H);G(i,t),a={kind:`adapted`,samples:t}}}catch{a={kind:`baseline`}}return{kind:`browser_voiceid_enrollment_v2`,scope:t,model:j,generation:n.generation,revision:n.revision,baseline:i,adaptation:a}}function W(e,t){let n=Array(192).fill(0);for(let e of t)for(let r=0;r<n.length;r+=1)n[r]+=e[r]/t.length;let r=P(n);for(let t=0;t<n.length;t+=1)n[t]=(1-B)*e[t]+B*r[t];return P(n)}function G(e,t){if(t.length!==3)throw Error(`Record three samples before saving voice improvements.`);for(let n of t)if(F(e,n)<.45)throw Error(`This sample differs from your original voice. Try again or re-record your enrollment.`);if(F(e,W(e,t))<.98)throw Error(`These samples differ too much from your original voice. Re-record your enrollment instead.`)}function K(e){return V.read(e)}async function q(e,t){let n=await V.readTemplate(e,t),r=n.adaptation;return{template:r.kind===`adapted`?W(n.baseline,r.samples):[...n.baseline],baseline:[...n.baseline],kind:r.kind}}async function J(){let e=await V.readImportable();if(e===void 0)return null;let t=C(e,`Previous VoiceID enrollment`);return t.kind!==`browser_voiceid_enrollment_v1`||t.model!==j?null:H(t.template)}async function Y(e){let{scope:t,signal:n}=e;switch(e.kind){case`activate`:return V.commit({kind:`activate`,scope:t,signal:n,guard:e.guard,snapshot:e.snapshot,baseline:H(e.baseline)});case`import`:return V.commit({kind:`import`,scope:t,signal:n,guard:e.guard,snapshot:e.snapshot,confirmation:e.confirmation,baseline:H(e.baseline)});case`replace`:return V.commit({kind:`replace`,scope:t,signal:n,guard:e.guard,snapshot:e.snapshot,confirmation:e.confirmation,baseline:H(e.baseline)});case`improve`:return G(e.snapshot.enrollment.baseline,e.samples),V.commit({kind:`improve`,scope:t,signal:n,guard:e.guard,snapshot:e.snapshot,confirmation:e.confirmation,samples:e.samples});case`reset`:return V.commit({kind:`reset`,scope:t,signal:n,guard:e.guard,snapshot:e.snapshot,confirmation:e.confirmation});default:return X(e)}}function X(e){throw Error(`Unsupported VoiceID enrollment change.`)}async function Z(e,t,n,r){await z(e,n,r),n.throwIfAborted();let i=new ne(e,t,n,r);try{await i.result}finally{i.dispose()}}var ne=class{completion=new m;result=this.completion.promise;status;prompt;phrase=c(null);record;cancel;samples=[];phase=`ready`;get closed(){return this.phase===`closed`}controller=new AbortController;guardTimer;checkingGuard=!1;constructor(e,t,n,r){this.plan=t,this.signal=n,this.model=r,this.prompt=new d(e.ownerDocument,`Enroll your voice in this browser`,this.phrase),this.prompt.title.textContent=`Read aloud · 0 of 3 accepted`,this.status=this.prompt.status,this.record=this.prompt.record,this.cancel=this.prompt.cancel,this.record.textContent=`Record sample 1`,this.record.addEventListener(`click`,this.capture),this.cancel.setAttribute(`aria-label`,`Cancel enrollment`),this.cancel.addEventListener(`click`,this.cancelled),this.prompt.ready(t.kind===`improve`?`Read naturally. Your original enrollment stays unchanged.`:`Read the full phrase at your normal pace.`),e.replaceChildren(this.prompt.element),n.addEventListener(`abort`,this.cancelled,{once:!0}),this.guardTimer=setInterval(this.checkGuard,250),n.aborted?this.cancelled():this.record.focus()}capture=()=>{this.collect()};async collect(){if(this.phase!==`ready`)return;let e=this.samples.length+1;try{u(),this.phase=`recording`,this.record.disabled=!0,this.status.textContent=`Opening microphone…`;let e=await t(this.controller.signal,this.prompt.capture);if(this.signal.aborted||this.closed){e.kind===`captured`&&e.samples.fill(0);return}if(e.kind===`insufficient_audio`){this.status.textContent=n(e.quality);return}if(this.plan.kind===`improve`&&e.quality.noise!==`normal`){e.samples.fill(0),this.status.textContent=`Use a quiet place to improve your voice enrollment.`;return}let a;try{if(await h(this.plan.scope,this.plan.guard),this.status.textContent=`Checking your voice…`,(await i(e.samples,this.phrase,this.model)).kind===`mismatch`)throw new r;a=await N(e.samples)}finally{e.samples.fill(0)}if(this.signal.aborted||this.closed){a.fill(0);return}if(this.plan.kind===`improve`&&F(this.plan.snapshot.enrollment.baseline,a)<.45)throw a.fill(0),Error(`Your voice did not match the original enrollment. To replace it, return to Manage voice and choose Record voice again.`);for(let e of this.samples)if(F(e,a)<.45)throw a.fill(0),Error(`This sample differs from the earlier samples. Use the same microphone and try again.`);if(this.samples.push(a),this.samples.length<3){this.prompt.accepted(),this.status.textContent=`Sample ${this.samples.length} accepted. Record the next sample.`,this.record.textContent=`Record sample ${this.samples.length+1}`;return}let o=Array(192).fill(0);for(let e of this.samples)for(let t=0;t<o.length;t+=1)o[t]+=e[t]/3;this.phase=`committing`,this.prompt.title.textContent=`3 of 3 accepted`,this.status.textContent=`Saving voice enrollment…`;let s=this.plan;switch(s.kind){case`activate`:await Y({kind:`activate`,scope:s.scope,guard:s.guard,snapshot:s.snapshot,baseline:P(o),signal:this.controller.signal});break;case`replace`:await Y({kind:`replace`,scope:s.scope,guard:s.guard,snapshot:s.snapshot,baseline:P(o),confirmation:s.confirmation,signal:this.controller.signal});break;case`improve`:await Y({kind:`improve`,scope:s.scope,guard:s.guard,snapshot:s.snapshot,samples:this.samples,confirmation:s.confirmation,signal:this.controller.signal});break;default:return re(s)}if(this.signal.aborted||this.closed)return;this.phase=`closed`,this.prompt.accepted(),this.status.textContent=`Voice enrollment saved.`,this.completion.resolve()}catch(e){if(!this.closed&&this.phase===`committing`){this.phase=`closed`,this.controller.abort(),this.completion.reject(E(e));return}!this.closed&&this.samples.length===3&&this.samples.pop()?.fill(0),this.closed||(this.status.textContent=e instanceof Error?e.message:`VoiceID enrollment failed.`)}finally{this.closed||(this.samples.length<e&&(this.record.textContent=`Retry sample ${e}`,this.status.textContent=`Sample ${e} was not accepted. ${this.status.textContent??``}`),this.phrase=c(this.phrase),this.prompt.setPhrase(this.phrase),this.prompt.title.textContent=`Read aloud · ${this.samples.length} of 3 accepted`,this.prompt.ready(this.status.textContent??``),this.phase=`ready`,this.record.disabled=!1)}}cancelled=()=>{this.closed||(this.phase=`closed`,this.controller.abort(),this.completion.reject(Error(`VoiceID enrollment was cancelled.`)))};checkGuard=()=>{this.closed||this.checkingGuard||(this.checkingGuard=!0,this.validateGuard())};async validateGuard(){try{await h(this.plan.scope,this.plan.guard)}catch(e){this.closed||(this.phase=`closed`,this.controller.abort(),this.completion.reject(E(e)))}finally{this.checkingGuard=!1}}dispose(){this.phase=`closed`,this.controller.abort(),clearInterval(this.guardTimer),this.signal.removeEventListener(`abort`,this.cancelled),this.prompt.dispose(),this.record.removeEventListener(`click`,this.capture),this.cancel.removeEventListener(`click`,this.cancelled);for(let e of this.samples)e.fill(0)}};function re(e){throw Error(`Unsupported VoiceID enrollment capture.`)}async function Q(e,n,r,a,o){let s=await t(n,r);if(s.kind===`insufficient_audio`)return n.throwIfAborted(),s;try{n.throwIfAborted();let t=await i(s.samples,a,o),r=await N(s.samples),c;try{n.throwIfAborted();let t=await q(e,n);try{c=F(r,t.template)}finally{t.template.fill(0),t.baseline.fill(0)}}finally{r.fill(0)}return c<.45?{kind:`mismatch`,quality:s.quality}:t.kind===`matched`?{kind:`matched`}:{kind:`phrase_mismatch`}}finally{s.samples.fill(0)}}async function ie(e,t,n){u();let r=await _(n.walletId,n.walletAuthMethodId),i=await w(r);if(await K(i))await $({kind:`activation`,scope:i,owner:await x(i,`activating`)},n.signal,t.onCapture,t.phrase,e);else{let r=await x(i,`activating`);await Z(t.parent,{kind:`activate`,scope:i,guard:r,snapshot:{kind:`missing`}},n.signal,e)}n.signal.throwIfAborted();let a=await y(r);if(n.signal.aborted)throw a.fill(0),Error(`VoiceID activation was cancelled.`);return{kind:`activated`,publicKeyB64u:r.publicKeyB64u,deviceKeyId:r.deviceKeyId,factorSecret32:a}}async function ae(e,t,n){ee();let{challenge:r}=n;if(r.requestOrigin!==location.origin||r.expiresAtMs<=Date.now())throw Error(`VoiceID challenge is expired or belongs to another Wallet origin.`);let i=await S(r.walletId,r.walletAuthMethodId);if(!i||i.deviceKeyId!==r.deviceKeyId)throw Error(`VoiceID device key is unavailable in this browser.`);if(await $({kind:`active`,scope:await T(r.walletId,r.walletAuthMethodId)},n.signal,t.onCapture,t.phrase,e),n.signal.throwIfAborted(),r.expiresAtMs<=Date.now())throw Error(`VoiceID challenge expired. Start unlock again.`);let a=await crypto.subtle.sign(`Ed25519`,i.privateKey,k(r)),o=await y(i);if(n.signal.aborted||r.expiresAtMs<=Date.now())throw o.fill(0),Error(`VoiceID unlock expired or was cancelled.`);return{kind:`unlocked`,assertion:te({kind:`voiceid_device_assertion_v1`,challenge:r,signatureB64u:g(new Uint8Array(a))}),factorSecret32:o}}async function oe(e,t,n){u();let{statement:r}=n;if(r.requestOrigin!==location.origin||r.expiresAtMs<=Date.now())throw Error(`VoiceID check is expired or belongs to another Wallet origin.`);let i=await S(r.walletId,r.walletAuthMethodId);if(!i||i.deviceKeyId!==r.deviceKeyId)throw Error(`VoiceID device key is unavailable in this browser.`);if(await $({kind:`active`,scope:await T(r.walletId,r.walletAuthMethodId)},n.signal,t.onCapture,t.phrase,e),n.signal.throwIfAborted(),r.expiresAtMs<=Date.now())throw Error(`VoiceID check expired. Start again.`);let a=await crypto.subtle.sign(`Ed25519`,i.privateKey,O(r)),o=await y(i);if(n.signal.aborted||r.expiresAtMs<=Date.now())throw o.fill(0),Error(`VoiceID check expired or was cancelled.`);return{kind:`confirmed`,assertion:b({kind:`voiceid_operation_assertion_v1`,statement:r,signatureB64u:g(new Uint8Array(a))}),factorSecret32:o}}async function $(e,t,n,i,a){let o=await Q(e,t,n,i,a);switch(o.kind){case`matched`:return;case`insufficient_audio`:throw new s(o.quality);case`mismatch`:throw new p(o.quality);case`phrase_mismatch`:throw new r;default:return se(o)}}function se(e){throw Error(`Unexpected voice result: ${String(e)}`)}export{Y as a,z as c,Z as i,oe as n,J as o,ae as r,K as s,ie as t};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{d as e,i as t,l as n,m as r,n as i,r as a,t as o,v as s}from"./prompt-
|
|
1
|
+
import{d as e,i as t,l as n,m as r,n as i,r as a,t as o,v as s}from"./prompt-BMATEY7H.js";import{SeamsWordmark as c,VOICE_ID_HOST_API_VERSION as l,WorkerDeferred as u,authMenuSuccessCopy as d,backIcon as f,createCspStylesheetManager as p,createWalletIframeSurfaceMeasurementReporter as m,getDefaultCspNonce as h,toError as g}from"../voiceid-host.js";const _=new WeakMap;var v=class{footer;constructor(e,t){this.prompt=t;let n=e.ownerDocument,r=_.get(n);r||(r=p({doc:n,baseCss:`
|
|
2
2
|
.seams-voiceid-activation-surface.seams-voiceid-unlock {
|
|
3
3
|
box-sizing: border-box;
|
|
4
4
|
overflow: hidden;
|
|
@@ -78,4 +78,4 @@ import{d as e,i as t,l as n,m as r,n as i,r as a,t as o,v as s}from"./prompt-DsR
|
|
|
78
78
|
color: var(--seams-colors-textPrimary, #eff2f3);
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
|
-
`,nonce:h}),_.set(n,r)),r.ensureBase(),e.classList.add(`seams-voiceid-unlock`);let o=n.createElement(`div`);o.className=`seams-voiceid-unlock-header`,t.cancel.className=`seams-voiceid-unlock-back`,t.cancel.setAttribute(`aria-label`,`Back`),t.cancel.replaceChildren(),i(f(),t.cancel),o.append(t.cancel),e.prepend(o),this.footer=n.createElement(`div`),this.footer.className=`seams-voiceid-unlock-footer`,i([a(`span`,null,`Secured by`),` `,a(c,{})],this.footer),e.append(this.footer)}succeed(){let e=this.prompt.cancel;return e.animate([{opacity:1},{opacity:0}],{duration:150,easing:`ease-in`,fill:`forwards`}),{top:e.getBoundingClientRect().top,bottom:this.footer.getBoundingClientRect().top}}dispose(){i(null,this.prompt.cancel),i(null,this.footer)}}
|
|
81
|
+
`,nonce:h}),_.set(n,r)),r.ensureBase(),e.classList.add(`seams-voiceid-unlock`);let o=n.createElement(`div`);o.className=`seams-voiceid-unlock-header`,t.cancel.className=`seams-voiceid-unlock-back`,t.cancel.setAttribute(`aria-label`,`Back`),t.cancel.replaceChildren(),i(f(),t.cancel),o.append(t.cancel),e.prepend(o),this.footer=n.createElement(`div`),this.footer.className=`seams-voiceid-unlock-footer`,i([a(`span`,null,`Secured by`),` `,a(c,{})],this.footer),e.append(this.footer)}succeed(){let e=this.prompt.cancel;return e.animate([{opacity:1},{opacity:0}],{duration:150,easing:`ease-in`,fill:`forwards`}),{top:e.getBoundingClientRect().top,bottom:this.footer.getBoundingClientRect().top}}dispose(){i(null,this.prompt.cancel),i(null,this.footer)}};const y={activation:`Activate VoiceID`,unlock:`Unlock with VoiceID`,export:`Export keys with VoiceID`};var b=class{result;completion=new u;controller=new AbortController;element;activateButton;cancelButton;status;prompt;unlockFrame;autoStartUnlock;unlockSuccess;unmountCapture;measurement;phrase=r(null);state={kind:`preparing`};settlement=`closed`;expiryTimer=null;constructor(e,t,n,r,i){this.unlockSuccess=r;let a=y[t],s=document.getElementById(`root`)??document.body;if(!s)throw Error(`Wallet activation surface has no mount root.`);this.element=document.createElement(`section`),this.element.className=`seams-wallet-ui seams-auth-method-activation-surface seams-voiceid-activation-surface`,this.element.setAttribute(`role`,`dialog`),this.element.setAttribute(`aria-modal`,`true`),this.element.setAttribute(`aria-label`,a);let c=t===`unlock`&&r===`skip`&&i!==void 0;this.prompt=new o(document,a,this.phrase,c?`segments`:`ring`),this.element.append(this.prompt.element),this.unlockFrame=t===`unlock`&&!c?new v(this.element,this.prompt):null,this.autoStartUnlock=t===`unlock`&&i!==void 0,c&&(this.element.classList.add(`seams-voiceid-in-card`),this.prompt.cancel.hidden=!0),this.status=this.prompt.status,this.status.textContent=`Loading VoiceID…`,this.prompt.title.textContent=`VoiceID`,this.element.dataset.preparation=`loading`,this.activateButton=this.prompt.record,this.activateButton.textContent=a,this.activateButton.disabled=!0,this.activateButton.hidden=this.autoStartUnlock,this.activateButton.addEventListener(`click`,this.begin),this.cancelButton=this.prompt.cancel,this.cancelButton.addEventListener(`click`,this.cancel),this.element.addEventListener(`cancel`,this.cancel),this.unmountCapture=i?i(this.element):null,i||s.appendChild(this.element),this.measurement=!i&&n.kind===`wallet_iframe`?m({kind:`request_surface`,element:this.element,requestId:n.requestId,postMeasurement:n.postMeasurement}):null,this.cancelButton.focus(),this.result=this.completion.promise,this.initialize(e)}dispose(){this.measurement?.disconnect(),this.expiryTimer!==null&&clearTimeout(this.expiryTimer),this.element.removeEventListener(`cancel`,this.cancel),this.activateButton.removeEventListener(`click`,this.begin),this.cancelButton.removeEventListener(`click`,this.cancel),this.unlockFrame?.dispose(),this.prompt.dispose(),this.unmountCapture?this.unmountCapture(this.settlement):this.element.remove()}async initialize(e){try{await new Promise(C),this.controller.signal.throwIfAborted();let t=await e(this.controller.signal,{parent:this.element,progress:this.prompt.progress});if(this.state.kind===`closed`)return;if(t.kind===`management`){this.element.setAttribute(`aria-label`,`Manage voice`),this.element.dataset.preparation=`ready`,this.state={kind:`capturing`};let e=await t.action(this.controller.signal);this.controller.signal.throwIfAborted(),this.state={kind:`closed`},this.completion.resolve(e);return}let n=t.expiresAtMs===null?null:t.expiresAtMs-Date.now();if(n!==null&&n<=0)throw Error(`VoiceID challenge expired. Start unlock again.`);this.state={kind:`ready`,capture:t},this.expiryTimer=n===null?null:setTimeout(this.expire,n);for(let e of this.element.querySelectorAll(`.seams-voiceid-model-download`))e.remove();this.element.dataset.preparation=`ready`,this.prompt.title.textContent=`Read aloud`,this.status.textContent=`Read naturally, then pause.`,this.activateButton.disabled=!1,this.autoStartUnlock?this.begin():this.activateButton.focus()}catch(e){if(this.state.kind===`closed`)return;this.state={kind:`closed`},this.completion.reject(g(e))}}begin=()=>{if(this.state.kind!==`ready`)return;let e=this.state.capture;this.state={kind:`capturing`},this.perform(e)};async perform(i){this.activateButton.disabled=!0,this.status.textContent=`Opening microphone…`;try{let e=await i.action(this.controller.signal,this.prompt.capture,this.phrase);if(this.state.kind===`closed`)return;this.unlockFrame&&this.unlockSuccess===`show`&&await this.showUnlocked(this.unlockFrame),this.settlement=`succeeded`,this.state={kind:`closed`},this.completion.resolve(e)}catch(a){if(this.state.kind===`closed`)return;if(a instanceof t||a instanceof e||a instanceof n||a instanceof s){if(i.expiresAtMs!==null&&Date.now()>=i.expiresAtMs){this.expire();return}let e=this.phrase;this.phrase=r(e),this.prompt.setPhrase(this.phrase),this.state={kind:`ready`,capture:i},this.activateButton.hidden=!1,this.activateButton.textContent=`Try again`,this.prompt.ready(a.message),this.activateButton.focus();return}this.state={kind:`closed`},this.completion.reject(g(a))}}async showUnlocked(e){this.state={kind:`succeeding`},this.settlement=`succeeded`,this.expiryTimer!==null&&clearTimeout(this.expiryTimer),this.expiryTimer=null,this.cancelButton.disabled=!0;let t=performance.now(),n=d(`authenticated`);await this.prompt.succeed(n.headline,n.message,e.succeed());let r=Math.max(0,1300-(performance.now()-t));await this.element.animate([{opacity:1},{opacity:1,offset:r/(r+240),easing:`ease-in`},{opacity:0}],{duration:r+240,fill:`forwards`}).finished}cancel=()=>{this.state.kind===`closed`||this.state.kind===`succeeding`||(this.state={kind:`closed`},this.controller.abort(),this.completion.reject(new x))};expire=()=>{this.state.kind===`closed`||this.state.kind===`succeeding`||(this.state={kind:`closed`},this.controller.abort(),this.completion.reject(Error(`VoiceID challenge expired. Start unlock again.`)))}},x=class extends Error{constructor(){super(`VoiceID capture was cancelled.`),this.name=`VoiceIdCaptureCancelledError`}};async function S(e){let t=new b(e.prepare,e.purpose,e.measurement,e.unlockSuccess??`show`,e.mountCapture);try{return await t.result}finally{t.dispose()}}function C(e){requestAnimationFrame(w.bind(null,e))}function w(e){setTimeout(e,0)}const T=8;if(l!==8)throw Error(`VoiceID requires a matching Wallet host API.`);function E(e){return{unlock:k.bind(null,e),activate:j.bind(null,e),confirmOperation:D.bind(null,e)}}function D(e,t){return S({purpose:`export`,measurement:t.surfaceMeasurementBinding,prepare:O.bind(null,e,t)})}async function O(e,t,n,r){let i=await import(`./operation-C2wM5i7x.js`);return n.throwIfAborted(),i.prepareOperationSurface(t,n,r.progress,e)}function k(e,t){return S({purpose:`unlock`,unlockSuccess:t.purpose===`step_up`?`skip`:`show`,measurement:t.surfaceMeasurementBinding,mountCapture:t.mountCapture,prepare:A.bind(null,e,t)})}async function A(e,t,n,r){let i=await import(`./unlock-C1jW7c3K.js`);return n.throwIfAborted(),i.prepareUnlockSurface(t,n,r.progress,e)}async function j(e,t){try{return await S({purpose:`activation`,measurement:t.surfaceMeasurementBinding,prepare:M.bind(null,e,t)})}catch(e){if(e instanceof x)return{kind:`cancelled`};throw e}}async function M(e,t,n,r){let i=await import(`./addVoiceId-eGEbWa1n.js`);return n.throwIfAborted(),i.prepareActivationSurface(t,n,r.parent,e)}export{E as createVoiceIdHostPlugin,T as hostApiVersion};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"./prompt-BMATEY7H.js";import{c as e,n as t,s as n}from"./deviceBridge-DTN7sn5D.js";async function r(t,r,a,o){let s=await t.prepareOperation(r);if(!await n(s.scope))throw Error(`Open Manage voice to import or record your enrollment on this device.`);await e(a,r,o),r.throwIfAborted();let c=await s.challenge(r);return r.throwIfAborted(),{kind:`recording`,expiresAtMs:c.expiresAtMs,action:i.bind(null,o,c)}}function i(e,n,r,i,a){return n.complete(t.bind(null,e,{onCapture:i,phrase:a}),r)}export{r as prepareOperationSurface};
|
|
@@ -294,6 +294,15 @@ ${D?`[data-voice-beam="${t}"][data-voice-halfres][data-active]::before,
|
|
|
294
294
|
`}let kn=null;function An(){if(typeof window>`u`)return null;let e=window;return e.AudioContext??e.webkitAudioContext??null}function jn(){let e=An();return e?(kn||=new e,kn.state===`suspended`&&kn.resume().catch(()=>{}),kn):null}const Mn=new WeakMap;function Nn(e){let t=jn();if(!t||e.getAudioTracks().length===0)return null;let n=Mn.get(e);n||(n={node:t.createMediaStreamSource(e),refs:0},Mn.set(e,n)),n.refs+=1;let r=t.createAnalyser();r.fftSize=1024,r.smoothingTimeConstant=.5,n.node.connect(r);let i=!1;return{analyser:r,release:()=>{if(!i){i=!0;try{n.node.disconnect(r)}catch{}if(--n.refs,n.refs<=0){try{n.node.disconnect()}catch{}Mn.delete(e)}}}}}const Pn=new WeakMap;function Fn(e){let t=Pn.get(e);return t||(t={level:0,bands:[0,0,0],phase:0,scanA:0,scanT:0,t:0,lastTs:0,warp:1},Pn.set(e,t)),t}const In=new Set;let Ln=null,Rn=0,zn=0,Bn=!1,Vn=!1,Hn=0,Un=0;const Wn=Math.PI*2,Gn=[[80,300],[300,2e3],[2e3,6e3]];function Kn(e){return e<0?0:e>1?1:e}function qn(e,t){let n=t/2;return((e+n)%t+t)%t-n}function Jn(e,t){let n=e/(t/2+4);return Math.max(0,1-n*n)}function Yn(e,t){if(e<=t)return 0;let n=(e-t)/Math.max(.001,1-t);return Kn((1-Math.exp(-3*n))/(1-Math.exp(-3)))}function Xn(e,t,n,r,i){let a=t>e?r:i,o=1-Math.exp(-n/Math.max(.001,a));return e+(t-e)*o}const Zn=!(typeof navigator<`u`&&/AppleWebKit/.test(navigator.userAgent)&&!/Chrome\/|Chromium\/|Edg\/|OPR\//.test(navigator.userAgent)),Qn=.05,$n=.1;function er(e,t,n,r){let i=e<0?1-r:1+r,a=Math.max(.05,n*i),o=Math.exp(-((Math.abs(e)/a)**+t)),s=Math.exp(-((1/a)**t));return Math.max(0,(o-s)/(1-s))}function tr(e,t,n,r,i){if(n<=0||t<=0)return 0;let a=t*Math.max(0,Math.min(.98,r));return e<=a?0:n*Math.min(1,(e-a)/Math.max(1,t-a))**+Math.max(.5,i)}function nr(e,t,n){return Math.max(0,Math.min(e,t/2,n/2))}function rr(e,t,n,r=0){if(n<=0)return 0;let i=Math.min(e,t-e)-r;if(i>=n)return 0;if(i<=0)return n;let a=n-i;return n-Math.sqrt(Math.max(0,n*n-a*a))}function ir(e,t,n,r){let i=n/2+t.cx*t.w,a=170*e.rangeWidth*t.w*t.mw,o=r*.82*Math.min(1,e.scale),s=Math.min(o,(64*e.rangeHeight*t.h+t.lift)*e.bandPosition),c=r-e.bandOffset,l=Math.min(1,t.corner*4),u=e.bandTail*(1-l*l*(3-2*l)),d=u>.001,f=d?e.bandTailOverflow:0,p=d?-f:i-a,m=d?n+f:i+a,h=[];for(let o=0;o<=56;o++){let l=p+(m-p)*o/56,d=Math.max(-1,Math.min(1,(l-i)/Math.max(1,a))),g=(l<i?i:n-i)+f,_=er(d,e.bandCurve,e.bandSpread,e.bandSkew)+tr(Math.abs(l-i),g,u,e.bandTailPosition,e.bandTailCurve),v=t.corner>0?rr(l,n,nr(e.radius,n,r))*t.corner:0;h.push([l,c-s*_-v])}return h}function ar(e,t,n,r,i){for(let[a,o]of[[``,1],[`-z`,.5]]){let s=e=>(e*o).toFixed(1)+`px`,c=n.map(([e,t])=>`${s(e)} ${s(t)}`),l=`polygon(0 ${s(i)}, ${c.join(`, `)}, ${s(r)} ${s(i)})`,u=`polygon(0 0, ${s(r)} 0, ${s(r)} ${s(i)}, ${c.slice().reverse().join(`, `)}, 0 ${s(i)})`;e.style.setProperty(`--vb-clip-below${a}-${t}`,l),e.style.setProperty(`--vb-clip-above${a}-${t}`,u)}}function or(e,t,n){let r=n;for(let e=0;e<t.length;e++)t[e][1]<r&&(r=t[e][1]);let i=Math.max(0,Math.min(.9,Math.floor((r-6)/n/Qn)*Qn));if(i===e.filterTop)return;e.filterTop=i;let a=1+Math.max(.1,12/n),o=e.filter;o.setAttribute(`x`,`${-$n*100}%`),o.setAttribute(`width`,`${(1+2*$n)*100}%`),o.setAttribute(`y`,`${(i*100).toFixed(0)}%`),o.setAttribute(`height`,`${((a-i)*100).toFixed(1)}%`)}function sr(e,t,n){let{canvas:r,ctx:i,el:a,config:o}=e;if(!r||!i)return;let s=a.clientWidth,c=a.clientHeight;if(!s||!c)return;let l=Math.min(2,typeof window<`u`&&window.devicePixelRatio||1),u=Math.round(s*l),d=Math.round(c*l);(r.width!==u||r.height!==d)&&(r.width=u,r.height=d),i.setTransform(l,0,0,l,0,0),i.clearRect(0,0,s,c);let f=e.haloCanvas,p=e.haloCtx;f&&p&&((f.width!==u||f.height!==d)&&(f.width=u,f.height=d),p.setTransform(l,0,0,l,0,0),p.clearRect(0,0,s,c));let m=Math.min(1,.6*o.bandStrength*t.strength);if(m<.005||o.bandWidth<=0)return;let h=o.theme===`dark`,g=o.bandWidth*(1+.35*t.level),_=o.bandAberration*(.35+.65*t.level),v=(4+12*_)*o.scale,y=4*_*o.scale,b=(e,t)=>{i.beginPath(),i.moveTo(n[0][0]+e,n[0][1]+t);for(let r=1;r<n.length;r++)i.lineTo(n[r][0]+e,n[r][1]+t)},x={r:o.bandColors.above,g:o.bandColors.mid,c:o.bandColors.core,b:o.bandColors.below},S=(h?.42:.4)*m,C=14*g,w=3.5*o.bandWidth/2,T=w*l,E=typeof i.filter==`string`,ee=E?`0px`:`${w.toFixed(2)}px`;e.cssBlur!==ee&&(a.style.setProperty(`--vb-band-blur-${o.id}`,ee),a.style.setProperty(`--vb-band-halo-blur-${o.id}`,E?`0px`:`${(w*3).toFixed(2)}px`),e.cssBlur=ee);let te=[[1,.16],[.72,.2],[.46,.26],[.22,.34]],D=[{rgb:x.r,a:1,ox:y,oy:-v},{rgb:x.g,a:.55,ox:y*.35,oy:-v*.35},{rgb:x.b,a:1,ox:-y,oy:v},{rgb:x.c,a:.9,ox:0,oy:0}];i.lineCap=`round`,i.lineJoin=`round`,i.globalCompositeOperation=`source-over`;let O=n[0][0],k=n[n.length-1][0],ne=(e,t)=>{let n=i.createLinearGradient(O,0,k,0),r=o.bandTail>0?.015:.18;return n.addColorStop(0,`rgba(${e}, 0)`),n.addColorStop(r,`rgba(${e}, ${t.toFixed(3)})`),n.addColorStop(1-r,`rgba(${e}, ${t.toFixed(3)})`),n.addColorStop(1,`rgba(${e}, 0)`),n},A=!E&&p?p:i;E&&(i.filter=`blur(${(T*3).toFixed(1)}px)`),A.lineCap=`round`,A.lineJoin=`round`,A.strokeStyle=ne(x.c,S*.3),A.lineWidth=C*2.2,A.beginPath(),A.moveTo(n[0][0],n[0][1]);for(let e=1;e<n.length;e++)A.lineTo(n[e][0],n[e][1]);A.stroke(),E&&(i.filter=`blur(${T.toFixed(1)}px)`);for(let e of D)for(let[t,n]of te)i.strokeStyle=ne(e.rgb,S*e.a*n),i.lineWidth=Math.max(.6,C*t),b(e.ox,e.oy),i.stroke();E&&(i.filter=`none`),i.globalCompositeOperation=`source-over`}function cr(e){return(1-Math.cos(Wn*e))/2}function lr(e,t){let n=e.analyser,r=e.time,i=e.freq;n.getFloatTimeDomainData(r);let a=0;for(let e=0;e<r.length;e++)a+=r[e]*r[e];t.level=Math.sqrt(a/r.length)*5*e.config.sensitivity,n.getByteFrequencyData(i);let o=n.context.sampleRate/n.fftSize;for(let n=0;n<3;n++){let[r,a]=Gn[n],s=Math.max(0,Math.floor(r/o)),c=Math.min(i.length-1,Math.ceil(a/o)),l=0;for(let e=s;e<=c;e++)l+=i[e];let u=c>=s?l/(c-s+1)/255:0;t.bands[n]=u*1.7*e.config.sensitivity}}const ur={level:0,bands:[0,0,0]};function dr(e){Ln=requestAnimationFrame(dr);let t=zn?e-zn:0;if(zn=e,Bn){if(Vn=!Vn,Vn)return;e>=Un&&(Bn=!1,Hn=0)}else t>22?Hn?e-Hn>500&&(Bn=!0,Vn=!1,Un=e+4e3):Hn=e:Hn=0;e-Rn<14.666666666666668||(Rn=e,In.forEach(t=>{var n;let{el:r,config:i,source:a,s:o}=t,s=i.paused;if(s&&t.paintedConfig===i)return;let c=s?0:o.lastTs?Math.min(.05,(e-o.lastTs)/1e3):1/60;o.lastTs=e,o.t+=c;let l=o.t;if(!s)if(t.analyser)lr(t,ur);else{let e=a.getLevel?Kn(a.getLevel()):0;ur.level=e,ur.bands[0]=e,ur.bands[1]=e*(.72+.28*Math.sin(l*9.1)),ur.bands[2]=e*(.6+.4*Math.sin(l*13.7+2))}let u=Yn(ur.level,i.threshold);o.level=Xn(o.level,u,c,i.attack,i.release);for(let e=0;e<3;e++){let t=Yn(ur.bands[e],i.threshold*.6);o.bands[e]=Xn(o.bands[e],t,c,i.attack,i.release*1.15)}let d=Sn*i.lobeSpacing;i.processing&&o.scanA<.001&&o.scanT===0&&(o.scanT=Math.max(.05,i.processingDuration)/2);let f=Math.max(.05,i.processingEase);o.scanA=Xn(o.scanA,i.processing?1:0,c,f*.9,f*.8),i.processing?o.scanT+=c:o.scanA<.001&&(o.scanT=0);let p=o.scanA*o.scanA*(3-2*o.scanA),m=r.clientWidth,h=r.clientHeight,g=d/2*i.processingTravel,_=o.scanT/Math.max(.05,i.processingDuration),v=Math.floor(_),y=_-v,b=Math.max(1,i.processingCurve),x=y<.5?.5*(2*y)**b:1-.5*(2-2*y)**b,S=i.reducedMotion?0:v%2==0?2*x-1:1-2*x,C=p*g*S,w=1-p*.6,T=1-p*.45,E=1+p*.3*(1-S*S),ee=i.reducedMotion?.5:.5+.5*Math.sin(Wn*l/i.breatheDuration),te=o.level+(1-o.level)*i.idle*ee,D=Math.max(0,Math.min(1,(p-.25)/.75)),O=D*D*(3-2*D),k=Math.max(te,i.processingLevel*O),ne=.15+.85*k,A=.5+i.reach*k,j=(.85+i.spread*k)*E;i.flow!==0&&!i.reducedMotion&&(o.phase=((o.phase+i.flow*k*c)%d+d)%d),r.style.setProperty(`--vb-level-${i.id}`,o.level.toFixed(3)),r.style.setProperty(`--vb-cx-${i.id}`,`${C.toFixed(1)}px`),r.style.setProperty(`--vb-mw-${i.id}`,T.toFixed(3));let re=i.bend*k;r.style.setProperty(`--vb-bh-${i.id}`,`${Math.max(0,re).toFixed(1)}px`);let ie=i.bend>0?Math.min(1,re/i.bend):0;r.style.setProperty(`--vb-bendA-${i.id}`,ie.toFixed(3));let M={cx:C,w:j,h:A,mw:T,lift:re,strength:ie,level:o.level,corner:p},N=m/2+C*j,P=30*i.scale*j,ae=nr(i.radius,m,h),oe=p*i.cornerFollow;r.style.setProperty(`--vb-cy-${i.id}`,`${(-rr(N,m,ae,P*1.4)*oe).toFixed(1)}px`),o.warp=Xn(o.warp,i.processing?0:1,c,.35,.06);let se=o.warp,ce=t.displace!=null&&se<.03;if(ce!==t.warpOff&&(t.warpOff=ce,ce?r.setAttribute(`data-voice-warp`,`off`):r.removeAttribute(`data-voice-warp`)),m&&h&&(t.ctx||t.displace)){let e=ir(i,M,m,h);(t.displace&&!ce||i.coreLight>0)&&ar(r,i.id,e,m,h),t.filter&&!ce&&Zn&&or(t,e,h),t.ctx&&sr(t,M,e)}if(t.displace&&!ce){let e=i.reducedMotion?0:i.distortion*120*i.scale*(.15+.85*k)*se;t.displace.scale.baseVal=e,t.noiseShift&&(t.noiseShift.dx.baseVal=8*i.scale*Math.sin(l*.9),t.noiseShift.dy.baseVal=4*i.scale*Math.sin(l*.6+1.3))}r.style.setProperty(`--vb-glow-${i.id}`,ne.toFixed(3)),r.style.setProperty(`--vb-h-${i.id}`,A.toFixed(3)),r.style.setProperty(`--vb-w-${i.id}`,j.toFixed(3));for(let e=0;e<xn.length;e++){let t=xn[e],n=qn(t.x*i.lobeSpacing+o.phase,d),a=i.bands?.6+.7*o.bands[t.band]:1;r.style.setProperty(`--vb-x${e}-${i.id}`,`${(n*w).toFixed(1)}px`),r.style.setProperty(`--vb-l${e}-${i.id}`,(a*Jn(n,d)).toFixed(3));let s=m/2+(C+n*w)*j;r.style.setProperty(`--vb-y${e}-${i.id}`,`${(-rr(s,m,ae,P)*oe).toFixed(1)}px`)}let le=i.staticColors||i.reducedMotion||i.hueRange===0?0:-i.hueRange+2*i.hueRange*cr(l/i.hueDuration);r.style.setProperty(`--vb-hue-${i.id}`,`${le.toFixed(2)}deg`),(n=t.onLevel)==null||n.call(t,o.level),t.paintedConfig=i}))}function fr(){Ln??=(Rn=0,zn=0,Hn=0,requestAnimationFrame(dr))}function pr(){In.size===0&&Ln!=null&&(cancelAnimationFrame(Ln),Ln=null)}function mr(e,t,n,r){let i={el:e,config:t,source:n,onLevel:r,analyser:null,releaseAnalyser:null,time:null,freq:null,canvas:null,ctx:null,haloCanvas:null,haloCtx:null,displace:null,noiseShift:null,filter:null,filterTop:-1,s:Fn(e),paintedConfig:null,cssBlur:null,warpOff:e.hasAttribute(`data-voice-warp`)};t.distortion>0&&(i.displace=e.querySelector(`:scope > svg feDisplacementMap`),i.noiseShift=e.querySelector(`:scope > svg feOffset`),i.filter=e.querySelector(`:scope > svg filter`));let a=e.querySelector(`:scope > [data-voice-beam-band]`);if(a){i.canvas=a,i.ctx=a.getContext(`2d`);let t=e.querySelector(`:scope > [data-voice-beam-band-halo]`);t&&(i.haloCanvas=t,i.haloCtx=t.getContext(`2d`))}if(i.s.lastTs=0,n.stream){let e=Nn(n.stream);e&&(i.analyser=e.analyser,i.releaseAnalyser=e.release,i.time=new Float32Array(e.analyser.fftSize),i.freq=new Uint8Array(e.analyser.frequencyBinCount))}return In.add(i),fr(),()=>{var e;In.delete(i),(e=i.releaseAnalyser)==null||e.call(i),pr()}}const hr={scale:1,glowSize:1,processingDuration:1.1,processingLevel:.55,processingTravel:1.55,processingCurve:2.1,cornerFollow:.45,strokeOpacity:1,innerOpacity:1,bloomOpacity:1,idle:.18,reach:1.2,spread:1.05,flow:48,bend:60,bandStrength:1.55,bandWidth:2.15,bandPosition:.35,bandCurve:1.75,bandSpread:.87,bandSkew:.12,bandOffset:-27,bandTail:.59,bandTailPosition:.67,bandTailCurve:2.4,bandTailOverflow:15,bandAberration:.89,distortion:.62,distortionDetail:2.3,glowWidth:.65,glowHeight:1.25,lobeSpacing:.85,rangeWidth:.75,rangeHeight:1,softness:1.07,coreSize:1,coreLight:0,coreLightWidth:1,coreLightHeight:1,strokeScale:1,innerScale:1,innerHeight:1,bloomScale:1,bloomHeight:1},gr={default:{},pill:{scale:.45,glowSize:.95,strokeOpacity:1.2,innerOpacity:.85,reach:1.35,spread:1.1,flow:0,bend:23,bandStrength:1.55,bandWidth:1.85,bandCurve:1.95,bandSpread:.38,bandOffset:-16,bandTail:0,processingTravel:2,cornerFollow:0,distortion:.45,distortionDetail:3,glowWidth:.65,glowHeight:.95,lobeSpacing:.45,rangeWidth:.8,rangeHeight:.7,softness:.88,coreSize:.25,strokeScale:1.25,innerScale:.95,bloomScale:1.05,bloomHeight:2.25},mobile:{scale:1.25,spread:.45,reach:3,flow:60,bend:70,bandWidth:2.4,bandCurve:1.55,bandSpread:.9,bandOffset:-50,bandTail:.62,bandTailPosition:.42,bandTailCurve:2.7,bandTailOverflow:22,processingDuration:1.05,processingLevel:.35,processingTravel:1,cornerFollow:.4,bandStrength:1.8,distortionDetail:2,glowWidth:1.15,glowHeight:2.1,lobeSpacing:1.35,rangeWidth:1.25,rangeHeight:1.2,softness:1.1}},_r={default:{brightness:1.15},pill:{brightness:1.35,saturation:1.5},mobile:{strength:1,brightness:1.2,saturation:1.5}},vr={default:{},pill:{},mobile:{strength:1}};function yr(e=`default`,t=`dark`){return(t===`light`?vr[e]:void 0)??_r[e]}const br={default:{bandStrength:1.7},pill:{bandStrength:2},mobile:{bandStrength:1.7}};function xr(e=`default`,t=`dark`){let n=gr[e],r={};return t===`light`&&(n.reach===void 0&&(r.reach=1.8),n.spread===void 0&&(r.spread=.8),n.coreLight===void 0&&(r.coreLight=1.8)),{...hr,...r,...n,...t===`light`?br[e]:void 0}}const Sr={dark:{core:`255, 255, 255`,above:`255, 70, 80`,mid:`90, 255, 150`,below:`80, 140, 255`},light:{core:`197, 139, 255`,above:`255, 122, 182`,mid:`126, 196, 255`,below:`45, 255, 171`}},Cr=typeof navigator<`u`&&/AppleWebKit/.test(navigator.userAgent)&&!/Chrome\/|Chromium\/|Edg\/|OPR\//.test(navigator.userAgent),wr=(()=>{if(typeof document>`u`)return!0;let e=document.createElement(`canvas`).getContext(`2d`);return!!e&&typeof e.filter==`string`})();function Tr(){let[e,t]=jt(()=>typeof window>`u`||window.matchMedia(`(prefers-color-scheme: dark)`).matches?`dark`:`light`);return Nt(()=>{if(typeof window>`u`)return;let e=window.matchMedia(`(prefers-color-scheme: dark)`),n=e=>t(e.matches?`dark`:`light`);return e.addEventListener(`change`,n),()=>e.removeEventListener(`change`,n)},[]),e}function Er(){let[e,t]=jt(()=>typeof window>`u`||!window.matchMedia?!1:window.matchMedia(`(prefers-reduced-motion: reduce)`).matches);return Nt(()=>{if(typeof window>`u`||!window.matchMedia)return;let e=window.matchMedia(`(prefers-reduced-motion: reduce)`),n=e=>t(e.matches);return e.addEventListener(`change`,n),()=>e.removeEventListener(`change`,n)},[]),e}function Dr(e,t){return e===`auto`?t:e}const Or=Yt(function({children:e,type:t=`default`,scale:n,stream:r=null,level:i=0,sensitivity:a=3.1,threshold:o=.015,attack:s=.325,release:c=.86,idle:l,breatheDuration:u=5.2,reach:d,spread:f,bands:p=!0,flow:m,processing:h=!1,processingDuration:g,processingLevel:_,processingTravel:v,processingCurve:y,cornerFollow:b,processingEase:x=.6,colorVariant:S=`colorful`,colors:C,bandColors:w,theme:T=`dark`,staticColors:E=!1,hueRange:ee,hueDuration:te,active:D=!0,paused:O=!1,borderRadius:k,brightness:ne,saturation:A,glowSize:j,strokeOpacity:re,innerOpacity:ie,bloomOpacity:M,bend:N,bandStrength:P,bandWidth:ae,bandPosition:oe,bandCurve:se,bandSpread:ce,bandSkew:le,bandOffset:ue,bandTail:de,bandTailPosition:fe,bandTailCurve:F,bandTailOverflow:pe,bandAberration:me,distortion:he,distortionDetail:ge,glowWidth:_e,glowHeight:ve,lobeSpacing:ye,rangeWidth:be,rangeHeight:xe,softness:Se,coreSize:Ce,coreLight:we,coreLightWidth:I,coreLightHeight:Te,strokeScale:Ee,innerScale:De,innerHeight:Oe,bloomScale:ke,bloomHeight:Ae,strength:je,className:Me,style:Ne,css:Pe,onLevel:Fe,onActivate:L,onDeactivate:Ie,onAnimationEnd:R,...Le},Re){let z=Lt().replace(/:/g,`-`),B=Dr(T,Tr()),ze=C?C.join(`|`):``,Be=w?[w.core,w.above,w.mid,w.below].join(`|`):``,V=xr(t,B),H=Math.max(.05,n??V.scale),Ve=j??V.glowSize,He=re??V.strokeOpacity,Ue=ie??V.innerOpacity,We=M??V.bloomOpacity,Ge=g??V.processingDuration,Ke=_??V.processingLevel,U=v??V.processingTravel,qe=y??V.processingCurve,Je=b??V.cornerFollow,Ye=l??V.idle,W=d??V.reach,Ze=f??V.spread,Qe=(m??V.flow)*H,$e=(N??V.bend)*H,et=P??V.bandStrength,tt=(ae??V.bandWidth)*H,nt=oe??V.bandPosition,rt=se??V.bandCurve,it=ce??V.bandSpread,at=le??V.bandSkew,ot=(ue??V.bandOffset)*H,st=de??V.bandTail,ct=fe??V.bandTailPosition,lt=F??V.bandTailCurve,ut=(pe??V.bandTailOverflow)*H,dt=me??V.bandAberration,ft=he??V.distortion,pt=(ge??V.distortionDetail)/H,mt=(_e??V.glowWidth)*H,ht=(ve??V.glowHeight)*H,gt=(ye??V.lobeSpacing)*H,_t=(be??V.rangeWidth)*H,vt=(xe??V.rangeHeight)*H,yt=Se??V.softness,G=(Ce??V.coreSize)*H,bt=Math.max(0,Math.min(3,we??V.coreLight)),xt=I??V.coreLightWidth,St=Te??V.coreLightHeight,Ct=Ee??V.strokeScale,K=De??V.innerScale,wt=Oe??V.innerHeight,Tt=ke??V.bloomScale,Et=Ae??V.bloomHeight,Dt=Er(),Ot=Pt(null),[kt,At]=jt(D),[Mt,Rt]=jt(!1),[zt,Bt]=jt(!0),[Vt,Ht]=jt(null),[Ut,Wt]=jt(0);Nt(()=>{if(!Cr)return;let e=Ot.current;if(!e)return;let t=()=>Wt(e.clientWidth*e.clientHeight);if(t(),typeof ResizeObserver>`u`)return;let n=new ResizeObserver(t);return n.observe(e),()=>n.disconnect()},[]);let Gt=Cr&&Ut>6e4?0:ft;Nt(()=>{if(k!=null)return;let e=Ot.current;if(!e)return;let t=()=>{let t=e.firstElementChild;if(!t)return;let n=getComputedStyle(t),r=parseFloat(n.borderTopLeftRadius);!isNaN(r)&&r>0&&Ht(r)};t();let n=new MutationObserver(t);return n.observe(e,{childList:!0,subtree:!1}),()=>n.disconnect()},[k,e]),Nt(()=>{D&&!kt&&!Mt?At(!0):!D&&kt&&!Mt&&Rt(!0)},[D,kt,Mt]),Nt(()=>{let e=Ot.current;if(!e||typeof IntersectionObserver>`u`)return;let t=new IntersectionObserver(e=>{for(let t of e)Bt(t.isIntersecting)},{rootMargin:`256px`});return t.observe(e),()=>t.disconnect()},[]);let Kt=It(e=>{let t=e.animationName;t.includes(`fade-out`)?(At(!1),Rt(!1),Ie?.()):t.includes(`fade-in`)&&L?.(),R?.(e)},[L,Ie,R]),q=bn[B],qt=k??Vt??16,Jt=yr(t,B),Yt=je??Jt.strength??q.strength??1,Xt=ee??q.hueRange??24,Zt=te??q.hueDuration??12,Qt=ne??Jt.brightness??q.brightness,$t=A??Jt.saturation??q.saturation,en=Ft(()=>On({id:z,borderRadius:qt,borderWidth:1,strokeOpacity:q.strokeOpacity*He,innerOpacity:q.innerOpacity*Ue,bloomOpacity:q.bloomOpacity*We,innerShadow:q.innerShadow,colorVariant:S,colors:C,brightness:Qt,saturation:$t,theme:B,hueBase:q.hueBase??0,glowSize:Ve*H,glowWidth:mt,glowHeight:ht,strokeScale:Ct,innerScale:K,innerHeight:wt,bloomScale:Tt,bloomHeight:Et,coreSize:G,coreLight:bt,coreLightWidth:xt,coreLightHeight:St,rangeWidth:_t,rangeHeight:vt,softness:yt,distortion:Gt>0,scale:H}),[z,qt,q,S,ze,Qt,$t,B,V,Ve,He,Ue,We,H,mt,ht,Ct,K,wt,Tt,Et,G,bt,xt,St,_t,vt,yt,Gt>0]),tn=Ft(()=>({id:z,sensitivity:Math.max(0,a),threshold:Math.max(0,Math.min(.95,o)),attack:Math.max(0,s),release:Math.max(0,c),idle:Math.max(0,Math.min(1,Ye)),breatheDuration:Math.max(.2,u),reach:Math.max(0,W),spread:Math.max(0,Ze),bands:p,flow:Qe,lobeSpacing:Math.max(.1,gt),bend:Math.max(0,$e),bandStrength:Math.max(0,et),bandWidth:Math.max(0,tt),bandPosition:Math.max(0,nt),bandCurve:Math.max(.3,rt),bandSpread:Math.max(.05,it),bandSkew:Math.max(-.9,Math.min(.9,at)),bandOffset:ot,bandTail:Math.max(0,Math.min(1.5,st)),bandTailPosition:Math.max(0,Math.min(.98,ct)),bandTailCurve:Math.max(.5,lt),bandTailOverflow:Math.max(0,ut),bandAberration:Math.max(0,Math.min(1,dt)),rangeWidth:_t,rangeHeight:vt,theme:B,bandColors:{core:w?.core&&yn(w.core)||Sr[B].core,above:w?.above&&yn(w.above)||Sr[B].above,mid:w?.mid&&yn(w.mid)||Sr[B].mid,below:w?.below&&yn(w.below)||Sr[B].below},distortion:Math.max(0,Math.min(1,Gt)),coreLight:bt,scale:H,radius:qt,processing:h,processingDuration:Math.max(.05,Ge),processingLevel:Math.max(0,Math.min(1,Ke)),processingEase:Math.max(.05,x),processingTravel:Math.max(0,U),processingCurve:Math.max(1,qe),cornerFollow:Math.max(0,Math.min(1,Je)),hueRange:Math.max(0,Xt),hueDuration:Math.max(.5,Zt),staticColors:S===`mono`?!0:E,reducedMotion:Dt,paused:O}),[z,a,o,s,c,Ye,u,W,Ze,p,Qe,gt,$e,et,tt,nt,rt,it,at,ot,st,ct,lt,ut,dt,_t,vt,B,Be,Gt,bt,H,qt,h,Ge,Ke,x,U,qe,Je,Xt,Zt,E,S,Dt,O]),nn=Pt(i);nn.current=i;let rn=Pt(Fe);rn.current=Fe,Nt(()=>{if(!(kt||Mt)||!zt)return;let e=Ot.current;return e?mr(e,tn,{stream:r,getLevel:()=>{let e=nn.current;return typeof e==`function`?e():e}},e=>rn.current?.call(rn,e)):void 0},[tn,r,kt,Mt,zt]);let an=It(e=>{Ot.current=e,typeof Re==`function`?Re(e):Re&&(Re.current=e)},[Re]),on={...Ne??{},"--voice-strength":Math.max(0,Math.min(1,Yt))};return J(Xe,{children:[J(`style`,{children:Pe?`${en}
|
|
295
295
|
${Pe.split(`{id}`).join(z)}`:en}),J(`div`,{...Le,ref:an,"data-voice-beam":z,"data-voice-type":t,"data-voice-halfres":``,"data-active":kt&&!Mt?``:void 0,"data-fading":Mt?``:void 0,"data-paused":kt&&!Mt&&(!zt||O)?``:void 0,"data-listening":r?``:void 0,"data-processing":h?``:void 0,className:Me,style:on,onAnimationEnd:Kt,children:[e,J(`div`,{"data-voice-beam-bloom":!0}),Gt>0&&J(Xe,{children:[J(`div`,{"data-voice-beam-warp":`inner`}),J(`div`,{"data-voice-beam-warp":`bloom`})]}),!wr&&J(`canvas`,{"data-voice-beam-band-halo":!0,"aria-hidden":`true`}),J(`canvas`,{"data-voice-beam-band":!0,"aria-hidden":`true`}),bt>0&&J(`div`,{"data-voice-beam-core":!0,children:J(`div`,{})}),Gt>0&&J(`svg`,{"aria-hidden":`true`,width:`0`,height:`0`,style:{position:`absolute`,pointerEvents:`none`},children:J(`filter`,{id:`vb-distort-${z}`,x:`-20%`,y:`-20%`,width:`140%`,height:`140%`,colorInterpolationFilters:`sRGB`,children:[J(`feTurbulence`,{type:`fractalNoise`,baseFrequency:`${(.012*pt).toFixed(4)} ${(.05*pt).toFixed(4)}`,numOctaves:2,seed:7,result:`noise`}),J(`feOffset`,{in:`noise`,dx:`0`,dy:`0`,result:`moved`}),J(`feColorMatrix`,{in:`moved`,type:`matrix`,values:`1 0 0 0 0 0 0 0 0 0.5 0 0 0 0 0 0 0 0 0 1`,result:`map`}),J(`feDisplacementMap`,{in:`SourceGraphic`,in2:`map`,scale:0,xChannelSelector:`R`,yChannelSelector:`G`})]})})]})]})}),kr=`http://www.w3.org/2000/svg`,Y=Math.PI*2,X=21.5,Ar=Math.sqrt(12)*X,jr=154-Ar,Z=Gr(),Mr=jr+Z.length,Nr=.56*Y*X/2,Pr=.75,Fr=.35,Ir=.55,Lr=22.5,Rr=Jr(.65,0,.35,1),zr=Jr(.4,0,.2,1),Br=Jr(.34,1.56,.64,1),Vr=Jr(.2,0,0,1);var Hr=class{element;lines=[];ripple;track;middle;top;bottom;seal;check;motion=matchMedia(`(prefers-reduced-motion: reduce)`);phase=`idle`;stage={kind:`line`};settleSuccess=null;successBegun=null;frame=0;previousTime=0;position=0;target=0;level=0;stopped=!1;constructor(e,t=`ring`){this.checking=t,this.element=e.createElementNS(kr,`svg`),this.element.classList.add(`seams-voiceid-ribbon`),this.element.setAttribute(`viewBox`,`0 0 308 64`),this.element.setAttribute(`aria-hidden`,`true`),this.ripple=this.append(e,`circle`,`1.5`),this.track=this.append(e,`circle`,`2`),this.middle=this.append(e,`path`,`1`),this.top=this.append(e,`path`,`2`),this.bottom=this.append(e,`path`,`2`),this.seal=this.append(e,`circle`,`0`),this.seal.setAttribute(`fill`,`currentColor`),this.seal.setAttribute(`stroke`,`none`),this.check=this.append(e,`path`,`2.6`),this.check.classList.add(`seams-voiceid-ribbon-check`),this.check.setAttribute(`d`,`M161 26.8 151.4 36.3 147.1 32`),this.check.setAttribute(`stroke-linejoin`,`round`),this.check.setAttribute(`pathLength`,`1`),this.check.setAttribute(`stroke-dasharray`,`1`);for(let e of[this.ripple,this.track,this.seal])e.setAttribute(`cx`,`154`),e.setAttribute(`cy`,`32`);if(this.track.setAttribute(`r`,`21.5`),t===`segments`){this.element.dataset.seamsProgressLine=``;for(let[e,t]of[this.top,this.middle,this.bottom].entries())t.dataset.seamsProgressSegment=String(e)}for(let t=3;t>=0;--t)this.lines.push(this.append(e,`path`,t===0?`1`:`0.65`));this.paint(performance.now())}readLevel=()=>this.level;setPhase(e){if(e===`processing`&&this.stage.kind===`line`){let e=Math.max(this.level,this.idleAmplitude(performance.now()));this.stage={kind:this.checking===`segments`?`segments`:`capture`,startedAt:performance.now(),amplitude:e}}else e!==`processing`&&(this.stage={kind:`line`},this.settle());this.phase=e,this.target=0,this.element.dataset.phase=e,this.wake()}succeed(e){if(this.stopped||this.stage.kind===`sealed`)return Promise.resolve();this.stage.kind===`line`&&this.setPhase(`processing`);let t=new Promise(this.awaitSuccess);return this.successBegun=e,this.stage.kind===`spin`&&this.beginSuccess(performance.now()),this.wake(),t}add(e){if(this.phase!==`listening`||this.stopped)return;let t=Math.max(0,e.rms-.003);this.target=(t/(t+.055))**.65*(e.speech?1:.15),this.element.dataset.speech=String(e.speech),this.wake()}dispose(){this.stopped=!0,cancelAnimationFrame(this.frame),this.frame=0,this.level=0,this.target=0,this.settle()}awaitSuccess=e=>{this.settle(),this.settleSuccess=e};settle(){let e=this.settleSuccess;this.settleSuccess=null,this.successBegun=null,e?.()}append(e,t,n){let r=e.createElementNS(kr,t);return r.setAttribute(`fill`,`none`),r.setAttribute(`stroke`,`currentColor`),r.setAttribute(`stroke-width`,n),r.setAttribute(`stroke-linecap`,`round`),r.setAttribute(`vector-effect`,`non-scaling-stroke`),r.setAttribute(`opacity`,`0`),this.element.append(r),r}wake(){!this.stopped&&this.frame===0&&(this.previousTime=performance.now(),this.frame=requestAnimationFrame(this.draw))}draw=e=>{if(this.frame=0,this.stopped)return;let t=Math.min(50,Math.max(0,e-this.previousTime));this.previousTime=e,this.level+=(this.target-this.level)*(1-Math.exp(-t/(this.target>this.level?55:200))),this.motion.matches||(this.position+=t*(.0012+this.level*.003)),this.paint(e),!this.element.isConnected||this.stage.kind===`sealed`||this.stage.kind===`line`&&this.phase===`idle`&&this.level<=.001||(this.frame=requestAnimationFrame(this.draw))};idleAmplitude(e){return this.phase!==`listening`||this.motion.matches?0:.085*(.72+.28*Math.sin(e/2600*Y))}paint(e){for(let e of[this.ripple,this.track,this.middle,this.top,this.bottom,this.seal,this.check])e.setAttribute(`opacity`,`0`);for(let e of this.lines)e.setAttribute(`opacity`,`0`);switch(this.stage.kind){case`line`:this.paintLine(Math.max(this.level,this.idleAmplitude(e)));return;case`capture`:this.paintCapture(e,this.stage);return;case`segments`:this.paintSegments(e,this.stage);return;case`spin`:this.paintArc(this.spinnerArc(e,this.stage),1);return;case`success`:this.paintSuccess(e,this.stage);return;case`sealed`:this.paintSeal({start:0,sweep:Y},1,1);return}}paintLine(e){for(let t=0;t<this.lines.length;t+=1){let n=3-t;this.lines[t].setAttribute(`d`,this.linePath(n,e,0,308,1)),this.lines[t].setAttribute(`opacity`,String(n===0?Ir+e*.4:.1+e*.1))}}paintSegments(e,t){let n=e-t.startedAt;if(!this.motion.matches&&n<200){this.paintLine(t.amplitude*(1-Vr(n/200)));return}let r=n-200,i=8*(this.motion.matches?1:Vr(Q(r/200))),a=(308-2*i)/3;for(let[e,t]of[this.top,this.middle,this.bottom].entries()){let n=e*(a+i);t.setAttribute(`d`,`M${n.toFixed(2)} 32H${(n+a).toFixed(2)}`),t.setAttribute(`stroke-width`,`1`),t.setAttribute(`opacity`,this.segmentOpacity(r,e))}}segmentOpacity(e,t){if(this.motion.matches)return`0.8`;let n=.5+.5*Math.cos(Y*(e-t*150)/900);return $(Ir,Fr+(1-Fr)*n,Vr(Q(e/200))).toFixed(3)}paintCapture(e,t){let n=this.motion.matches?920:e-t.startedAt;if(n>=560){this.paintJoin(e,Math.min(n-560,360));return}let r=t.amplitude,i=n/560,a=1-Vr(Q(n/150)),o=Rr(Q(i/.6)),s=Ur(!1)*X*560,c=qr(i,Mr,s),l=jr+qr(i,Mr+Nr-jr,s),u=Ir+r*.4;for(let[e,t]of[[this.top,!1],[this.bottom,!0]])e.setAttribute(`d`,this.halfPath(c,l,t,r,a)),e.setAttribute(`stroke-width`,$(1,2,o).toFixed(2)),e.setAttribute(`opacity`,$(u,1,o).toFixed(3));this.middle.setAttribute(`d`,this.linePath(0,r,jr,308-jr,a)),this.middle.setAttribute(`opacity`,(u*(1-Vr(Q(n/180)))).toFixed(3));for(let e=0;e<3;e+=1){let t=3-e;this.lines[e].setAttribute(`d`,this.linePath(t,r,0,308,a)),this.lines[e].setAttribute(`opacity`,((.1+r*.1)*(1-Q(n/200))).toFixed(3))}this.track.setAttribute(`opacity`,(.1*Q((i-.4)/.6)).toFixed(3))}paintJoin(e,t){let n=(1-Math.cos(Math.PI*t/360))/2,r=-Math.PI/2+Ur(!1)*t,i=Nr/X,a=Math.PI-i,o=this.motion.matches?-Math.PI/2:r+Pr*a*n;if(this.motion.matches||t>=360){this.stage={kind:`spin`,startedAt:e,base:o-Y*.14},this.settleSuccess&&this.beginSuccess(e),this.paint(e);return}this.track.setAttribute(`opacity`,`0.1`);for(let[e,t]of[[this.top,o],[this.bottom,r+Math.PI-(1-Pr)*a*n]])e.setAttribute(`d`,Kr({start:t,sweep:i})),e.setAttribute(`stroke-width`,`2`),e.setAttribute(`opacity`,`1`)}spinnerArc(e,t){let n=e-t.startedAt,r=this.motion.matches?2600:1500,i=(n+r/2)%r/r,a=i<.5,o=zr(a?i/.5:(i-.5)/.5),s=a?$(1,56,o):$(56,1,o),c=a?$(0,-14,o):$(-14,-99,o);return{start:t.base+Ur(this.motion.matches)*n-Y*c/100,sweep:Y*s/100}}beginSuccess(e){if(this.stage.kind!==`spin`)return;this.stage={kind:`success`,startedAt:e,from:this.spinnerArc(e,this.stage)};let t=this.successBegun;this.successBegun=null,t?.()}paintSuccess(e,t){let n=e-t.startedAt;if(n>=1140){this.stage={kind:`sealed`},this.settle(),this.paint(e);return}let r=Q(n/650),i=this.motion.matches?0:Ur(!1)*650*(r-r*r/2),a=Rr(Q((n-150)/500));this.paintSeal({start:t.from.start+i,sweep:$(t.from.sweep,Y,a)},Br(Q((n-600)/420)),Rr(Q((n-820)/320)));let o=Q((n-700)/700);if(!this.motion.matches&&o>0&&o<1){let e=Vr(o);this.ripple.setAttribute(`r`,$(Lr,34,e).toFixed(2)),this.ripple.setAttribute(`opacity`,((1-e)*.45).toFixed(3))}}paintSeal(e,t,n){this.paintArc(e,1),this.seal.setAttribute(`r`,(Lr*Math.max(0,t)).toFixed(2)),this.seal.setAttribute(`opacity`,t>0?`1`:`0`),this.check.setAttribute(`stroke-dashoffset`,(1-n).toFixed(3)),this.check.setAttribute(`opacity`,n>0?`1`:`0`)}paintArc(e,t){this.track.setAttribute(`opacity`,String(.1*t)),this.top.setAttribute(`d`,Kr(e)),this.top.setAttribute(`stroke-width`,`2`),this.top.setAttribute(`opacity`,`1`)}displacement(e,t,n){let r=n/308,i=Math.sin(Math.PI*r)**1.7;if(this.motion.matches)return t*5*i;let a=Math.sin(r*Math.PI*4-this.position+e*.5)*.7+Math.sin(r*Math.PI*7+this.position*.7+e)*.3;return t*(26-e*4)*i*a}linePath(e,t,n,r,i){let a=``,o=Math.max(2,Math.ceil((r-n)/2));for(let s=0;s<=o;s+=1){let c=n+(r-n)*s/o,l=32+this.displacement(e,t,c)*i;a+=`${s===0?`M`:`L`}${c.toFixed(2)},${l.toFixed(2)} `}return a}halfPath(e,t,n,r,i){let a=``,o=Math.max(2,Math.ceil((t-e)/1.5));for(let s=0;s<=o;s+=1){let c=Wr(e+(t-e)*s/o),l=n?308-c.x:c.x,u=n?64-c.y:c.y;c.onLine&&(u+=this.displacement(0,r,l)*i),a+=`${s===0?`M`:`L`}${l.toFixed(2)},${u.toFixed(2)} `}return a}};function Ur(e){return Y/(e?3200:1800)}function Wr(e){if(e<=jr)return{x:e,y:32,onLine:!0};if(e<Mr){let t=e-jr,n=0,r=Z.lengths.length-1;for(;r-n>1;){let e=n+r>>1;Z.lengths[e]<t?n=e:r=e}let i=(t-Z.lengths[n])/(Z.lengths[r]-Z.lengths[n]||1);return{x:$(Z.points[n][0],Z.points[r][0],i),y:$(Z.points[n][1],Z.points[r][1],i),onLine:!1}}let t=-Math.PI/2+(e-Mr)/X;return{x:154+X*Math.cos(t),y:32+X*Math.sin(t),onLine:!1}}function Gr(){let e=[[jr,32]],t=[0],n=0;for(let r=1;r<=240;r+=1){let i=r/240,a=[jr+Ar*i,32-X*(4*i**3-3*i**4)],o=e[e.length-1];n+=Math.hypot(a[0]-o[0],a[1]-o[1]),e.push(a),t.push(n)}return{points:e,lengths:t,length:n}}function Kr(e){let t=Math.max(2,Math.ceil(80*e.sweep/Y)),n=``;for(let r=0;r<=t;r+=1){let i=e.start+e.sweep*r/t,a=154+X*Math.cos(i),o=32+X*Math.sin(i);n+=`${r===0?`M`:`L`}${a.toFixed(2)},${o.toFixed(2)} `}return n}function qr(e,t,n){let r=e*e;return t*(3*r-2*r*e)+n*(r*e-r)}function Jr(e,t,n,r){let i=(e,t,n)=>((1-3*n+3*t)*e+(3*n-6*t))*e*e+3*t*e,a=(e,t,n)=>3*(1-3*n+3*t)*e*e+2*(3*n-6*t)*e+3*t;return o=>{if(o<=0)return 0;if(o>=1)return 1;let s=o;for(let t=0;t<6;t+=1){let t=a(s,e,n);if(t===0)break;s-=(i(s,e,n)-o)/t}return i(Q(s),t,r)}}function Q(e){return e<0?0:e>1?1:e}function $(e,t,n){return e+(t-e)*n}const Yr=Or;var Xr=class{element;glow;ribbon;prompt;themeObserver;phase=`idle`;disposed=!1;constructor(e,t,r){this.prompt=t,this.ribbon=new Hr(e,r),this.element=this.ribbon.element,this.glow=e.createElement(`div`),this.glow.className=`seams-voiceid-glow`,this.glow.setAttribute(`aria-hidden`,`true`),this.render();let i=n();if(i)for(let e of this.glow.querySelectorAll(`style`))e.nonce=i;this.themeObserver=new MutationObserver(this.render),this.themeObserver.observe(e.documentElement,{attributes:!0,attributeFilter:[`data-theme`]}),this.themeObserver.observe(e.body,{attributes:!0,attributeFilter:[`data-theme`]})}listen(){this.setPhase(`listening`)}add(e){this.ribbon.add(e)}checking(){this.setPhase(`processing`)}accept(){this.setPhase(`idle`)}ready(){this.setPhase(`idle`)}succeed(e){return this.disposed?Promise.resolve():(this.phase=`idle`,this.render(),this.ribbon.succeed(e))}stop(){this.disposed||(this.disposed=!0,this.themeObserver.disconnect(),this.ribbon.dispose(),vt(null,this.glow))}setPhase(e){this.disposed||(this.phase=e,this.ribbon.setPhase(e),this.render())}render=()=>{this.disposed||vt(Je(Yr,{className:`seams-voiceid-beam`,theme:(this.prompt.closest(`[data-theme]`)?.getAttribute(`data-theme`)??this.prompt.ownerDocument.documentElement.getAttribute(`data-theme`))===`light`?`light`:`dark`,level:this.ribbon.readLevel,processing:this.phase===`processing`,active:this.phase!==`idle`,staticColors:!0,colorVariant:`ocean`,borderRadius:Number.parseFloat(getComputedStyle(this.prompt).borderRadius)||16,children:null}),this.glow)}};const Zr=new WeakMap,Qr=new Map([[`if you panic panic early`,`if you panic, panic early`],[`life is short go long to hedge`,`life is short, go long to hedge`]]);var $r=class{element;title;phrase;status;record;cancel;progress;microphone;microphoneRequested=!1;visual;disposed=!1;constructor(e,r,i,a=`ring`){let o=Zr.get(e);o||(o=t({doc:e,baseCss:`
|
|
296
296
|
.seams-voiceid-activation-surface { width: min(100%, 26.25rem); margin: 0 auto; background: transparent; }
|
|
297
|
+
/* Inside an operation's card the card is the frame: the prompt fills it edge to edge. */
|
|
298
|
+
.seams-voiceid-activation-surface.seams-voiceid-in-card { width: 100%; }
|
|
299
|
+
.seams-voiceid-in-card .seams-voiceid-prompt {
|
|
300
|
+
width: 100%;
|
|
301
|
+
padding-top: 0.75rem;
|
|
302
|
+
border: 0;
|
|
303
|
+
border-radius: 0;
|
|
304
|
+
background: transparent;
|
|
305
|
+
}
|
|
297
306
|
|
|
298
307
|
.seams-voiceid-prompt {
|
|
299
308
|
box-sizing: border-box;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{s as e}from"./prompt-BMATEY7H.js";import{c as t,r as n,s as r}from"./deviceBridge-DTN7sn5D.js";async function i(e,n,i,o){let s=await e.prepareUnlock(n),c=s.scope;if(!await r(c))throw Error(`Unlock with a passkey, then open Manage voice to import or record your enrollment.`);await t(i,n,o),n.throwIfAborted();let l=await s.challenge(n),u={challenge:l,initiation:e.mountCapture?`hosted_menu`:`sdk_request`};return n.throwIfAborted(),{kind:`recording`,expiresAtMs:l.expiresAtMs,action:a.bind(null,o,u)}}async function a(t,r,i,a,s){switch(r.initiation){case`sdk_request`:e();break;case`hosted_menu`:break;default:return o(r.initiation)}return r.challenge.complete(n.bind(null,t,{onCapture:a,phrase:s}),i)}function o(e){throw Error(`Unexpected VoiceID initiation: ${String(e)}`)}export{i as prepareUnlockSurface};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { VoiceIdTranscriptionModel } from '@seams/wallet/voiceid-host';
|
|
2
2
|
import type { VoiceCaptureObserver } from '../browser/microphone';
|
|
3
3
|
import { type SpokenPhrase } from '../browser/phrase';
|
|
4
|
-
import type { VoiceIdActivationCapture, VoiceIdUnlockCapture } from '@seams/wallet/voiceid-host';
|
|
4
|
+
import type { VoiceIdActivationCapture, VoiceIdOperationCapture, VoiceIdUnlockCapture } from '@seams/wallet/voiceid-host';
|
|
5
5
|
type VoiceCapturePresentation = Readonly<{
|
|
6
6
|
onCapture: VoiceCaptureObserver;
|
|
7
7
|
phrase: SpokenPhrase;
|
|
@@ -10,5 +10,6 @@ export declare function captureVoiceIdActivation(model: VoiceIdTranscriptionMode
|
|
|
10
10
|
parent: HTMLElement;
|
|
11
11
|
}>, input: Parameters<VoiceIdActivationCapture>[0]): ReturnType<VoiceIdActivationCapture>;
|
|
12
12
|
export declare function captureVoiceIdUnlock(model: VoiceIdTranscriptionModel, presentation: VoiceCapturePresentation, input: Parameters<VoiceIdUnlockCapture>[0]): ReturnType<VoiceIdUnlockCapture>;
|
|
13
|
+
export declare function captureVoiceIdOperation(model: VoiceIdTranscriptionModel, presentation: VoiceCapturePresentation, input: Parameters<VoiceIdOperationCapture>[0]): ReturnType<VoiceIdOperationCapture>;
|
|
13
14
|
export {};
|
|
14
15
|
//# sourceMappingURL=deviceBridge.d.ts.map
|
|
@@ -18,13 +18,16 @@ export type VoiceCaptureElements = Readonly<{
|
|
|
18
18
|
progress: HTMLElement;
|
|
19
19
|
}>;
|
|
20
20
|
type CapturePreparation<T> = (signal: AbortSignal, elements: VoiceCaptureElements) => Promise<PreparedVoiceCapture<T>>;
|
|
21
|
+
type VoiceCapturePurpose = 'activation' | 'unlock' | 'export';
|
|
22
|
+
type VoiceUnlockSuccess = 'show' | 'skip';
|
|
21
23
|
export declare class VoiceIdCaptureCancelledError extends Error {
|
|
22
24
|
constructor();
|
|
23
25
|
}
|
|
24
26
|
export declare function showVoiceIdCaptureSurface<T>(input: {
|
|
25
27
|
readonly prepare: CapturePreparation<T>;
|
|
26
|
-
readonly purpose:
|
|
28
|
+
readonly purpose: VoiceCapturePurpose;
|
|
27
29
|
readonly measurement: UiConfirmSurfaceMeasurementBinding;
|
|
30
|
+
readonly unlockSuccess?: VoiceUnlockSuccess;
|
|
28
31
|
readonly mountCapture?: AuthMethodCaptureMount;
|
|
29
32
|
}): Promise<T>;
|
|
30
33
|
export {};
|
package/dist/types/host.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { WalletAuthMethodHostPlugin } from '@seams/wallet/voiceid-host';
|
|
2
2
|
import type { VoiceIdTranscriptionModel } from '@seams/wallet/voiceid-host';
|
|
3
|
-
export declare const hostApiVersion =
|
|
3
|
+
export declare const hostApiVersion = 8;
|
|
4
4
|
export declare function createVoiceIdHostPlugin(model: VoiceIdTranscriptionModel): WalletAuthMethodHostPlugin;
|
|
5
5
|
//# sourceMappingURL=host.d.ts.map
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { VoiceIdTranscriptionModel, VoiceIdOperationProof, WalletAuthMethodHostPlugin } from '@seams/wallet/voiceid-host';
|
|
2
|
+
import type { PreparedVoiceCapture } from '../capture/surface';
|
|
3
|
+
export declare function prepareOperationSurface(input: Parameters<WalletAuthMethodHostPlugin['confirmOperation']>[0], signal: AbortSignal, parent: HTMLElement, model: VoiceIdTranscriptionModel): Promise<PreparedVoiceCapture<VoiceIdOperationProof>>;
|
|
4
|
+
//# sourceMappingURL=operation.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seams/voiceid",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.46.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Optional browser VoiceID authentication for Seams Wallet",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"voice-glow": "0.2.1"
|
|
51
51
|
},
|
|
52
52
|
"peerDependencies": {
|
|
53
|
-
"@seams/wallet": "0.
|
|
53
|
+
"@seams/wallet": "0.46.0",
|
|
54
54
|
"react": ">=19.0.0",
|
|
55
55
|
"react-dom": ">=19.0.0"
|
|
56
56
|
},
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import"./prompt-DsRKGfyb.js";import{a as e,i as t,o as n,r,t as i}from"./deviceBridge-vf25pKzp.js";import{WorkerDeferred as a,prepareVoiceOwner as o,toError as s}from"../voiceid-host.js";const c=`http://www.w3.org/2000/svg`;async function l(e,t,n,r,i){let a=new u(e,t,n,r,i);try{await a.result}finally{a.dispose()}}var u=class{completion=new a;result=this.completion.promise;document;element;enrollment;enrollmentValue;enrollmentSummary;startOver;status;actions;busy=!1;closed=!1;constructor(e,t,n,r,i){this.parent=e,this.confirmChange=t,this.scope=n,this.signal=r,this.model=i,this.document=e.ownerDocument,this.element=this.document.createElement(`div`),this.enrollment=this.document.createElement(`div`),this.enrollmentValue=this.document.createElement(`span`),this.enrollmentSummary=this.document.createElement(`span`),this.startOver=this.document.createElement(`p`),this.status=this.document.createElement(`p`),this.element.className=`seams-voiceid-prompt seams-voiceid-management`;let a=this.document.createElement(`div`);a.className=`seams-voiceid-management-header`;let o=this.document.createElement(`button`);o.type=`button`,o.className=`seams-voiceid-management-back`,o.setAttribute(`aria-label`,`Back`),o.append(d(this.document,`M15 6l-6 6 6 6`,20)),o.addEventListener(`click`,this.cancel);let s=this.document.createElement(`h2`);s.textContent=`Manage voice`,a.append(o,s);let c=this.document.createElement(`p`);c.className=`seams-voiceid-management-intro`,c.textContent=`Voice unlock on this device. Each change asks for your passkey.`,this.element.append(a,c,this.enrollmentRow()),this.actions={reset:this.resetAction(),improve:this.action(`improve`,`Improve recognition`,!0),import:this.action(`import`,`Use saved enrollment`,!1),replace:this.startOverAction()},this.status.setAttribute(`role`,`status`),this.element.append(this.status),this.enrollmentValue.textContent=`Checking…`,this.actions.import.button.hidden=!0,this.render(null,!1,!1),this.parent.replaceChildren(this.element),this.signal.addEventListener(`abort`,this.cancel,{once:!0}),this.refresh(),o.focus()}enrollmentRow(){this.enrollment.className=`seams-voiceid-management-enrollment`;let e=this.document.createElement(`span`);return e.textContent=`Enrollment`,this.enrollmentValue.className=`seams-voiceid-management-value`,this.enrollmentSummary.className=`seams-voiceid-management-summary`,this.enrollmentSummary.append(this.enrollmentValue),this.enrollment.append(e,this.enrollmentSummary),this.enrollment}resetAction(){let e=this.document.createElement(`button`);e.type=`button`,e.className=`seams-voiceid-management-reset`,e.textContent=`Reset`,e.setAttribute(`aria-label`,`Reset improvements`),e.addEventListener(`click`,this.begin.bind(this,`reset`));let t=this.document.createElement(`span`);return t.className=`seams-voiceid-management-enrollment-detail`,this.enrollmentSummary.append(t),this.enrollment.append(e),{button:e,title:e,detail:t,frame:this.enrollment}}startOverAction(){return this.startOver.className=`seams-voiceid-management-section`,this.startOver.textContent=`Start over`,this.element.append(this.startOver),this.action(`replace`,`Record voice again`,!1)}action(e,t,n){let r=this.document.createElement(`button`);r.type=`button`,r.className=`seams-voiceid-management-action`;let i=this.document.createElement(`span`),a=this.document.createElement(`span`);a.className=`seams-voiceid-management-action-heading`;let o=this.document.createElement(`span`);o.id=`seams-voiceid-management-${e}-title`,o.textContent=t,a.append(o);let s=[];if(n){let t=this.document.createElement(`span`);t.id=`seams-voiceid-management-${e}-chip`,t.className=`seams-voiceid-management-chip`,t.textContent=`Experimental`,a.append(t),s.push(t.id)}let c=this.document.createElement(`span`);return c.id=`seams-voiceid-management-${e}-detail`,c.className=`seams-voiceid-management-action-detail`,s.push(c.id),i.append(a,c),r.append(i,d(this.document,`M9 6l6 6-6 6`,16)),r.setAttribute(`aria-labelledby`,o.id),r.setAttribute(`aria-describedby`,s.join(` `)),r.disabled=!0,r.addEventListener(`click`,this.begin.bind(this,e)),this.element.append(r),{button:r,title:o,detail:c,frame:r}}async refresh(){try{let t=await n(this.scope),r=t?null:await e();if(this.closed)return;this.render(t,r!==null,!0)}catch(e){this.completion.reject(s(e))}}render(e,t,n){let r=e?.adaptation??null,{improve:i,reset:a,import:o,replace:s}=this.actions;n&&(this.enrollment.dataset.enrollment=r?.kind??`missing`,this.enrollmentValue.textContent=r===null?`Not on this device`:r.kind===`adapted`?`Improved`:`Original`,i.button.hidden=e===null,o.button.hidden=!t),a.button.hidden=r?.kind!==`adapted`,a.detail.textContent=r?.kind===`adapted`?`Saved on this device`:``,i.title.textContent=r?.kind===`adapted`?`Improve again`:`Improve recognition`,i.detail.textContent=r?.kind===`adapted`?`Replace the added samples. Your original enrollment stays.`:`Add three samples. They stay until you replace or reset them.`,o.detail.textContent=`Import the voice enrollment saved in this browser.`,s.detail.textContent=r?.kind===`adapted`?`Replace your enrollment and remove improvements.`:`Replace your enrollment with three new samples.`,this.startOver.hidden=i.button.hidden&&o.button.hidden;for(let e of Object.values(this.actions))delete e.frame.dataset.state,e.button.disabled=!n;this.status.textContent=``,delete this.status.dataset.placement}show(e,t,n){let r=this.actions[e];if(this.status.textContent=n,r.button.hidden){this.status.dataset.placement=`dialog`;return}r.frame.dataset.state=t,r.detail.textContent=n}begin(e){if(!(this.busy||this.closed)){this.busy=!0;for(let e of Object.values(this.actions))e.button.disabled=!0;this.show(e,`pending`,`Confirm with your passkey to continue.`),this.perform(e)}}async perform(e){try{let i=await o(this.scope,`enrolled`),a=await n(this.scope),s=await f(e,i,a?{kind:`present`,enrollment:a}:{kind:`missing`},this.signal),c=await this.confirmChange(s);switch(this.signal.throwIfAborted(),s.kind){case`improve`:await r(this.parent,{kind:`improve`,scope:this.scope,guard:s.guard,snapshot:s.snapshot,confirmation:c},this.signal,this.model);break;case`replace`:await r(this.parent,{kind:`replace`,scope:this.scope,guard:s.guard,snapshot:s.snapshot,confirmation:c},this.signal,this.model);break;case`reset`:await t({kind:`reset`,scope:this.scope,guard:s.guard,snapshot:s.snapshot,confirmation:c,signal:this.signal});break;case`import`:await t({kind:`import`,scope:this.scope,guard:s.guard,snapshot:s.snapshot,baseline:s.baseline,confirmation:c,signal:this.signal});break;default:return p(s)}this.closed||this.completion.resolve()}catch(t){if(this.closed)return;this.parent.replaceChildren(this.element),await this.refresh(),this.closed||this.show(e,`error`,t instanceof Error?t.message:`VoiceID could not be updated.`)}finally{this.busy=!1}}cancel=()=>{this.closed||(this.closed=!0,this.parent.dispatchEvent(new Event(`cancel`,{bubbles:!0})),this.completion.reject(Error(`VoiceID management was cancelled.`)))};dispose(){this.closed=!0,this.signal.removeEventListener(`abort`,this.cancel),this.element.remove()}};function d(e,t,n){let r=e.createElementNS(c,`svg`);r.setAttribute(`viewBox`,`0 0 24 24`),r.setAttribute(`width`,String(n)),r.setAttribute(`height`,String(n)),r.setAttribute(`aria-hidden`,`true`);let i=e.createElementNS(c,`path`);return i.setAttribute(`d`,t),i.setAttribute(`fill`,`none`),i.setAttribute(`stroke`,`currentColor`),i.setAttribute(`stroke-width`,`1.75`),i.setAttribute(`stroke-linecap`,`round`),i.setAttribute(`stroke-linejoin`,`round`),r.append(i),r}async function f(t,n,r,i){switch(t){case`replace`:return{kind:t,guard:n,snapshot:r,signal:i};case`import`:{if(r.kind!==`missing`)throw Error(`The previous enrollment is unavailable.`);let a=await e();if(!a)throw Error(`The previous enrollment is unavailable.`);return{kind:t,guard:n,snapshot:r,signal:i,baseline:a}}case`improve`:case`reset`:if(r.kind!==`present`)throw Error(`Record or import your original voice first.`);return{kind:t,guard:n,snapshot:r,signal:i};default:return p(t)}}function p(e){throw Error(`Unsupported VoiceID enrollment management action.`)}async function m(e,t,n,r){t.throwIfAborted();let i=await e.prepareActivation();return t.throwIfAborted(),i.kind===`enroll_existing`?{kind:`management`,action:h.bind(null,r,i,n)}:{kind:`recording`,action:g.bind(null,r,i,n),expiresAtMs:null}}async function h(e,t,n,r){return await l(n,t.confirmChange,t.scope,r,e),r.throwIfAborted(),{kind:`activated`,walletId:t.scope.walletId,walletAuthMethodId:t.scope.walletAuthMethodId}}function g(e,t,n,r,a,o){return t.activate(i.bind(null,e,{parent:n,onCapture:a,phrase:o}),r)}export{m as prepareActivationSurface};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{_ as e,a as t,c as n,d as r,f as i,g as a,h as o,i as s,m as c,o as l,p as u,s as d,t as f,u as p,v as m}from"./prompt-DsRKGfyb.js";import{WorkerDeferred as h,assertVoiceOwner as g,base64UrlEncode as _,createBrowserVoiceDevice as v,isFiniteNumber as ee,openBrowserVoiceFactor as y,parseVoiceIdDeviceAssertion as b,prepareVoiceOwner as x,readBrowserVoiceDevice as S,requireRecord as C,resolveActivatingVoiceEnrollmentScope as w,resolveVoiceEnrollmentScope as T,toError as E,voiceEnrollmentStorage as D,voiceIdWalletSessionChallengeBytes as O}from"../voiceid-host.js";const k=`e04dd7a6a1e23fc7b89e47682ea9d0a3946cf7bc59d07922c3db3efc52ae4269`,A=`redimnet-b1:${k}`,j=new o({path:`/sdk/voiceid/redimnet-b1.onnx`,sha256:k,bytes:8859593,label:`Speaker verification`});async function M(e){let t=await j.prepare(),n=new(await(import(`./ort.wasm.bundle.min-7y-hlRN8.js`))).Tensor(`float32`,e,[1,e.length]);try{let e=await t.run({samples:n});try{let t=e.embedding;if(!t||!(t.data instanceof Float32Array))throw Error(`VoiceID model returned an invalid embedding.`);return N(Array.from(t.data))}finally{for(let t of Object.values(e))t.dispose()}}finally{n.dispose()}}function N(e){if(e.length!==192)throw Error(`VoiceID template dimensions are invalid.`);let t=0;for(let n of e){if(!Number.isFinite(n))throw Error(`VoiceID template is invalid.`);t+=n*n}if(t<1e-12)throw Error(`VoiceID template contains no signal.`);let n=Math.sqrt(t),r=[];for(let t of e)r.push(t/n);return r}function P(e,t){if(e.length!==192||t.length!==192)throw Error(`VoiceID templates are incompatible.`);let n=0;for(let r=0;r<e.length;r+=1)n+=e[r]*t[r];return n}function F(e){return e.asset}function I(e,t){return e+t.size}var L=class{element=document.createElement(`section`);status=document.createElement(`p`);meter=document.createElement(`progress`);retryButton=document.createElement(`button`);retry=null;cancelled=new h;reveal;received=new Map;models;assets;total;constructor(t,n,r){this.parent=t,this.signal=n,this.models=[j,u(r),p],this.assets=[e,...this.models.map(F)],this.total=this.assets.reduce(I,0),this.element.className=`seams-voiceid-model-download`,this.status.setAttribute(`role`,`status`),this.status.setAttribute(`aria-live`,`polite`),this.meter.setAttribute(`aria-label`,`VoiceID download`),this.meter.style.width=`100%`,this.retryButton.type=`button`,this.retryButton.className=`seams-voiceid-primary`,this.retryButton.textContent=`Retry loading`,this.retryButton.hidden=!0,this.retryButton.addEventListener(`click`,this.retryLoading),this.element.append(this.status,this.meter,this.retryButton),this.status.textContent=`Loading saved VoiceID…`,this.reveal=setTimeout(t.append.bind(t,this.element),300),n.addEventListener(`abort`,this.abort,{once:!0})}settle=()=>{clearTimeout(this.reveal),this.signal.removeEventListener(`abort`,this.abort),this.retryButton.removeEventListener(`click`,this.retryLoading)};abort=()=>{let e=new DOMException(`VoiceID preparation was cancelled.`,`AbortError`);this.cancelled.reject(e),this.retry?.reject(e)};retryLoading=()=>{this.retry?.resolve(),this.retry=null};async prepare(){this.signal.throwIfAborted(),await Promise.race([this.prepareUntilReady(),this.cancelled.promise])}async prepareUntilReady(){for(;;){this.signal.throwIfAborted(),this.retryButton.hidden=!0,this.meter.hidden=!1;try{for(let e of this.assets)await e.download(this.update.bind(this,e)),this.signal.throwIfAborted();this.preparing();for(let e of this.models)await e.prepare(),this.signal.throwIfAborted();this.ready();return}catch(e){if(this.signal.throwIfAborted(),!(e instanceof a))throw e;clearTimeout(this.reveal),this.parent.append(this.element),this.element.dataset.state=`failed`,this.meter.hidden=!0,this.status.textContent=e.message,this.retry=new h,this.retryButton.hidden=!1,this.retryButton.focus(),await this.retry.promise}}}update=(e,t)=>{switch(t.kind){case`checking_cache`:return;case`downloading`:this.received.set(e,t.received),this.element.dataset.state=`downloading`;break;case`ready`:this.received.set(e,e.size);break;default:}if(this.element.dataset.state!==`downloading`)return;let n=0;for(let e of this.received.values())n+=e;this.meter.max=this.total,this.meter.value=n,this.status.textContent=`Downloading VoiceID: ${(n/1e6).toFixed(1)} of ${(this.total/1e6).toFixed(1)} MB · ${Math.floor(n/this.total*100)}%`};preparing(){this.element.dataset.state=`preparing`,this.meter.removeAttribute(`value`),this.status.textContent=`Preparing VoiceID…`}ready(){this.element.dataset.state=`ready`,this.meter.hidden=!0,this.status.textContent=`VoiceID is ready.`}};async function R(e,t,n){let r=new L(e,t,n);try{await r.prepare()}finally{r.settle()}}const z=.2,B=D({model:A,parseEnrollment:H});function V(e){if(!Array.isArray(e)||!e.every(ee))throw Error(`VoiceID template is invalid.`);let t=N(e);for(let n=0;n<e.length;n+=1)if(Math.abs(e[n]-t[n])>1e-6)throw Error(`VoiceID template is not normalized.`);return e.slice()}function H(e,t){if(e===void 0)return null;let n=C(e,`VoiceID enrollment`),r=C(n.scope,`VoiceID enrollment scope`);if(n.kind!==`browser_voiceid_enrollment_v2`||r.walletId!==t.walletId||r.authorityId!==t.authorityId||r.walletAuthMethodId!==t.walletAuthMethodId||r.deviceKeyId!==t.deviceKeyId||typeof n.generation!=`string`||!n.generation||typeof n.revision!=`number`||!Number.isSafeInteger(n.revision)||n.revision<0)throw Error(`VoiceID enrollment identity is invalid.`);if(n.model!==A)return null;let i=V(n.baseline),a={kind:`baseline`};try{let e=C(n.adaptation,`VoiceID improvements`);if(e.kind===`adapted`&&Array.isArray(e.samples)&&e.samples.length===3){let t=e.samples.map(V);W(i,t),a={kind:`adapted`,samples:t}}}catch{a={kind:`baseline`}}return{kind:`browser_voiceid_enrollment_v2`,scope:t,model:A,generation:n.generation,revision:n.revision,baseline:i,adaptation:a}}function U(e,t){let n=Array(192).fill(0);for(let e of t)for(let r=0;r<n.length;r+=1)n[r]+=e[r]/t.length;let r=N(n);for(let t=0;t<n.length;t+=1)n[t]=(1-z)*e[t]+z*r[t];return N(n)}function W(e,t){if(t.length!==3)throw Error(`Record three samples before saving voice improvements.`);for(let n of t)if(P(e,n)<.45)throw Error(`This sample differs from your original voice. Try again or re-record your enrollment.`);if(P(e,U(e,t))<.98)throw Error(`These samples differ too much from your original voice. Re-record your enrollment instead.`)}function G(e){return B.read(e)}async function K(e,t){let n=await B.readTemplate(e,t),r=n.adaptation;return{template:r.kind===`adapted`?U(n.baseline,r.samples):[...n.baseline],baseline:[...n.baseline],kind:r.kind}}async function q(){let e=await B.readImportable();if(e===void 0)return null;let t=C(e,`Previous VoiceID enrollment`);return t.kind!==`browser_voiceid_enrollment_v1`||t.model!==A?null:V(t.template)}async function J(e){let{scope:t,signal:n}=e;switch(e.kind){case`activate`:return B.commit({kind:`activate`,scope:t,signal:n,guard:e.guard,snapshot:e.snapshot,baseline:V(e.baseline)});case`import`:return B.commit({kind:`import`,scope:t,signal:n,guard:e.guard,snapshot:e.snapshot,confirmation:e.confirmation,baseline:V(e.baseline)});case`replace`:return B.commit({kind:`replace`,scope:t,signal:n,guard:e.guard,snapshot:e.snapshot,confirmation:e.confirmation,baseline:V(e.baseline)});case`improve`:return W(e.snapshot.enrollment.baseline,e.samples),B.commit({kind:`improve`,scope:t,signal:n,guard:e.guard,snapshot:e.snapshot,confirmation:e.confirmation,samples:e.samples});case`reset`:return B.commit({kind:`reset`,scope:t,signal:n,guard:e.guard,snapshot:e.snapshot,confirmation:e.confirmation});default:return Y(e)}}function Y(e){throw Error(`Unsupported VoiceID enrollment change.`)}async function X(e,t,n,r){await R(e,n,r),n.throwIfAborted();let i=new Z(e,t,n,r);try{await i.result}finally{i.dispose()}}var Z=class{completion=new h;result=this.completion.promise;status;prompt;phrase=c(null);record;cancel;samples=[];phase=`ready`;get closed(){return this.phase===`closed`}controller=new AbortController;guardTimer;checkingGuard=!1;constructor(e,t,n,r){this.plan=t,this.signal=n,this.model=r,this.prompt=new f(e.ownerDocument,`Enroll your voice in this browser`,this.phrase),this.prompt.title.textContent=`Read aloud · 0 of 3 accepted`,this.status=this.prompt.status,this.record=this.prompt.record,this.cancel=this.prompt.cancel,this.record.textContent=`Record sample 1`,this.record.addEventListener(`click`,this.capture),this.cancel.setAttribute(`aria-label`,`Cancel enrollment`),this.cancel.addEventListener(`click`,this.cancelled),this.prompt.ready(t.kind===`improve`?`Read naturally. Your original enrollment stays unchanged.`:`Read the full phrase at your normal pace.`),e.replaceChildren(this.prompt.element),n.addEventListener(`abort`,this.cancelled,{once:!0}),this.guardTimer=setInterval(this.checkGuard,250),n.aborted?this.cancelled():this.record.focus()}capture=()=>{this.collect()};async collect(){if(this.phase!==`ready`)return;let e=this.samples.length+1;try{d(),this.phase=`recording`,this.record.disabled=!0,this.status.textContent=`Opening microphone…`;let e=await t(this.controller.signal,this.prompt.capture);if(this.signal.aborted||this.closed){e.kind===`captured`&&e.samples.fill(0);return}if(e.kind===`insufficient_audio`){this.status.textContent=n(e.quality);return}if(this.plan.kind===`improve`&&e.quality.noise!==`normal`){e.samples.fill(0),this.status.textContent=`Use a quiet place to improve your voice enrollment.`;return}let a;try{if(await g(this.plan.scope,this.plan.guard),this.status.textContent=`Checking your voice…`,(await i(e.samples,this.phrase,this.model)).kind===`mismatch`)throw new r;a=await M(e.samples)}finally{e.samples.fill(0)}if(this.signal.aborted||this.closed){a.fill(0);return}if(this.plan.kind===`improve`&&P(this.plan.snapshot.enrollment.baseline,a)<.45)throw a.fill(0),Error(`Your voice did not match the original enrollment. To replace it, return to Manage voice and choose Record voice again.`);for(let e of this.samples)if(P(e,a)<.45)throw a.fill(0),Error(`This sample differs from the earlier samples. Use the same microphone and try again.`);if(this.samples.push(a),this.samples.length<3){this.prompt.accepted(),this.status.textContent=`Sample ${this.samples.length} accepted. Record the next sample.`,this.record.textContent=`Record sample ${this.samples.length+1}`;return}let o=Array(192).fill(0);for(let e of this.samples)for(let t=0;t<o.length;t+=1)o[t]+=e[t]/3;this.phase=`committing`,this.prompt.title.textContent=`3 of 3 accepted`,this.status.textContent=`Saving voice enrollment…`;let s=this.plan;switch(s.kind){case`activate`:await J({kind:`activate`,scope:s.scope,guard:s.guard,snapshot:s.snapshot,baseline:N(o),signal:this.controller.signal});break;case`replace`:await J({kind:`replace`,scope:s.scope,guard:s.guard,snapshot:s.snapshot,baseline:N(o),confirmation:s.confirmation,signal:this.controller.signal});break;case`improve`:await J({kind:`improve`,scope:s.scope,guard:s.guard,snapshot:s.snapshot,samples:this.samples,confirmation:s.confirmation,signal:this.controller.signal});break;default:return Q(s)}if(this.signal.aborted||this.closed)return;this.phase=`closed`,this.prompt.accepted(),this.status.textContent=`Voice enrollment saved.`,this.completion.resolve()}catch(e){if(!this.closed&&this.phase===`committing`){this.phase=`closed`,this.controller.abort(),this.completion.reject(E(e));return}!this.closed&&this.samples.length===3&&this.samples.pop()?.fill(0),this.closed||(this.status.textContent=e instanceof Error?e.message:`VoiceID enrollment failed.`)}finally{this.closed||(this.samples.length<e&&(this.record.textContent=`Retry sample ${e}`,this.status.textContent=`Sample ${e} was not accepted. ${this.status.textContent??``}`),this.phrase=c(this.phrase),this.prompt.setPhrase(this.phrase),this.prompt.title.textContent=`Read aloud · ${this.samples.length} of 3 accepted`,this.prompt.ready(this.status.textContent??``),this.phase=`ready`,this.record.disabled=!1)}}cancelled=()=>{this.closed||(this.phase=`closed`,this.controller.abort(),this.completion.reject(Error(`VoiceID enrollment was cancelled.`)))};checkGuard=()=>{this.closed||this.checkingGuard||(this.checkingGuard=!0,this.validateGuard())};async validateGuard(){try{await g(this.plan.scope,this.plan.guard)}catch(e){this.closed||(this.phase=`closed`,this.controller.abort(),this.completion.reject(E(e)))}finally{this.checkingGuard=!1}}dispose(){this.phase=`closed`,this.controller.abort(),clearInterval(this.guardTimer),this.signal.removeEventListener(`abort`,this.cancelled),this.prompt.dispose(),this.record.removeEventListener(`click`,this.capture),this.cancel.removeEventListener(`click`,this.cancelled);for(let e of this.samples)e.fill(0)}};function Q(e){throw Error(`Unsupported VoiceID enrollment capture.`)}async function te(e,n,r,a,o){let s=await t(n,r);if(s.kind===`insufficient_audio`)return n.throwIfAborted(),s;try{n.throwIfAborted();let t=await i(s.samples,a,o),r=await M(s.samples),c;try{n.throwIfAborted();let t=await K(e,n);try{c=P(r,t.template)}finally{t.template.fill(0),t.baseline.fill(0)}}finally{r.fill(0)}return c<.45?{kind:`mismatch`,quality:s.quality}:t.kind===`matched`?{kind:`matched`}:{kind:`phrase_mismatch`}}finally{s.samples.fill(0)}}async function ne(e,t,n){d();let r=await v(n.walletId,n.walletAuthMethodId),i=await w(r);if(await G(i))await $({kind:`activation`,scope:i,owner:await x(i,`activating`)},n.signal,t.onCapture,t.phrase,e);else{let r=await x(i,`activating`);await X(t.parent,{kind:`activate`,scope:i,guard:r,snapshot:{kind:`missing`}},n.signal,e)}n.signal.throwIfAborted();let a=await y(r);if(n.signal.aborted)throw a.fill(0),Error(`VoiceID activation was cancelled.`);return{kind:`activated`,publicKeyB64u:r.publicKeyB64u,deviceKeyId:r.deviceKeyId,factorSecret32:a}}async function re(e,t,n){l();let{challenge:r}=n;if(r.requestOrigin!==location.origin||r.expiresAtMs<=Date.now())throw Error(`VoiceID challenge is expired or belongs to another Wallet origin.`);let i=await S(r.walletId,r.walletAuthMethodId);if(!i||i.deviceKeyId!==r.deviceKeyId)throw Error(`VoiceID device key is unavailable in this browser.`);if(await $({kind:`active`,scope:await T(r.walletId,r.walletAuthMethodId)},n.signal,t.onCapture,t.phrase,e),n.signal.throwIfAborted(),r.expiresAtMs<=Date.now())throw Error(`VoiceID challenge expired. Start unlock again.`);let a=await crypto.subtle.sign(`Ed25519`,i.privateKey,O(r)),o=await y(i);if(n.signal.aborted||r.expiresAtMs<=Date.now())throw o.fill(0),Error(`VoiceID unlock expired or was cancelled.`);return{kind:`unlocked`,assertion:b({kind:`voiceid_device_assertion_v1`,challenge:r,signatureB64u:_(new Uint8Array(a))}),factorSecret32:o}}async function $(e,t,n,i,a){let o=await te(e,t,n,i,a);switch(o.kind){case`matched`:return;case`insufficient_audio`:throw new s(o.quality);case`mismatch`:throw new m(o.quality);case`phrase_mismatch`:throw new r;default:return ie(o)}}function ie(e){throw Error(`Unexpected voice result: ${String(e)}`)}export{q as a,J as i,re as n,G as o,X as r,R as s,ne as t};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{s as e}from"./prompt-DsRKGfyb.js";import{n as t,o as n,s as r}from"./deviceBridge-vf25pKzp.js";async function i(e,t,i,o){let s=await e.prepareUnlock(t),c=s.scope;if(!await n(c))throw Error(`Unlock with a passkey, then open Manage voice to import or record your enrollment.`);await r(i,t,o),t.throwIfAborted();let l=await s.challenge(t),u={challenge:l,initiation:e.mountCapture?`hosted_menu`:`sdk_request`};return t.throwIfAborted(),{kind:`recording`,expiresAtMs:l.expiresAtMs,action:a.bind(null,o,u)}}async function a(n,r,i,a,s){switch(r.initiation){case`sdk_request`:e();break;case`hosted_menu`:break;default:return o(r.initiation)}return r.challenge.complete(t.bind(null,n,{onCapture:a,phrase:s}),i)}function o(e){throw Error(`Unexpected VoiceID initiation: ${String(e)}`)}export{i as prepareUnlockSurface};
|