virtual-human-cf 1.2.0 → 1.4.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.
@@ -1 +1,6 @@
1
- (function(f,n){typeof exports=="object"&&typeof module<"u"?n(exports,require("vue")):typeof define=="function"&&define.amd?define(["exports","vue"],n):(f=typeof globalThis<"u"?globalThis:f||self,n(f.VirtualHumanCf={},f.Vue))})(this,function(f,n){"use strict";const H=["src","muted"],U=((r,b)=>{const e=r.__vccOpts||r;for(const[a,o]of b)e[a]=o;return e})(n.defineComponent({__name:"VirtualHumanPersona",props:{videoSrc:{type:String,required:!0},visible:{type:Boolean,default:!1},isPlaying:{type:Boolean,default:!1},muted:{type:Boolean,default:!0},isDark:{type:Boolean,default:!1},screenClientId:{type:String,required:!1},wsUrl:{type:String,required:!1},styles:{type:Object,default:()=>({width:"400px",height:"500px",left:"16px",bottom:"16px"})}},emits:["update:isPlaying","ended","update:visible"],setup(r,{emit:b}){const e=r,a=b,o=n.ref(null),C=n.ref(null),t=n.ref(null),p=n.ref(!1),m=()=>{if(t.value&&t.value.close(),!(!e.wsUrl||!e.screenClientId))try{const c=new URL(e.wsUrl);c.searchParams.append("sessionId",e.screenClientId+"-persona"),t.value=new WebSocket(c.toString()),t.value.onopen=()=>{p.value=!0,console.log(`[VirtualHumanPersona] Connected to ${e.wsUrl} for session ${e.screenClientId}-persona`)},t.value.onmessage=u=>{try{const d=JSON.parse(u.data);w(d)}catch(d){console.error("[VirtualHumanPersona] Failed to parse message:",u.data,d)}},t.value.onerror=u=>{console.error("[VirtualHumanPersona] WebSocket error:",u)},t.value.onclose=()=>{p.value=!1,console.log("[VirtualHumanPersona] WebSocket disconnected")}}catch(c){console.error("[VirtualHumanPersona] Failed to initialize WebSocket:",c)}},w=c=>{const{type:u,action:d}=c;u==="control"&&(d==="play"||d==="resume"?(a("update:isPlaying",!0),a("update:visible",!0)):d==="pause"?(a("update:isPlaying",!1),a("update:visible",!0)):d==="stop"&&(a("update:isPlaying",!1),a("update:visible",!1),o.value&&(o.value.currentTime=0)))};n.watch(()=>e.screenClientId,()=>{e.screenClientId&&e.wsUrl&&m()}),n.watch(()=>e.wsUrl,()=>{e.screenClientId&&e.wsUrl&&m()}),n.watch(()=>e.isPlaying,c=>{o.value&&(c?o.value.play().catch(u=>console.error("Video play failed:",u)):o.value.pause())});const g=()=>{e.isPlaying||a("update:isPlaying",!0)},S=()=>{e.isPlaying&&a("update:isPlaying",!1)},k=()=>{a("update:isPlaying",!1),a("ended")};return n.onMounted(()=>{e.isPlaying&&o.value&&o.value.play().catch(c=>console.error("Video play failed:",c)),e.screenClientId&&e.wsUrl&&m()}),n.onUnmounted(()=>{t.value&&t.value.close()}),(c,u)=>(n.openBlock(),n.createBlock(n.Transition,{name:"fade"},{default:n.withCtx(()=>[r.visible?(n.openBlock(),n.createElementBlock("div",{key:0,class:n.normalizeClass(["virtual-human-container",{"is-dark":r.isDark}]),style:n.normalizeStyle(r.styles)},[n.createElementVNode("div",{class:"video-wrapper",ref_key:"wrapperRef",ref:C},[n.createElementVNode("video",{ref_key:"videoRef",ref:o,src:r.videoSrc,class:"persona-video",muted:r.muted,playsinline:"",loop:"",autoPlay:"",disablePictureInPicture:"",onPlay:g,onPause:S,onEnded:k},null,40,H)],512)],6)):n.createCommentVNode("",!0)]),_:1}))}}),[["__scopeId","data-v-bf23f155"]]),A=n.defineComponent({__name:"VirtualHumanEventAdapter",props:{screenClientId:{type:String,required:!0},wsUrl:{type:String,required:!0}},emits:["eventNotifaction","controlEvent","end","pause","connected","error","playComplete"],setup(r,{emit:b}){const e=r,a=b,o=n.ref(null),C=n.ref(!1);let t=null,p=0,m=!1,w=0,g=!1;const S=()=>{t||(t=new(window.AudioContext||window.webkitAudioContext)({sampleRate:24e3})),t.state==="suspended"&&!g&&t.resume()},k=()=>{m&&w===0&&(a("playComplete",e.screenClientId),m=!1)},c=s=>{if(S(),!!t)try{const l=window.atob(s),i=l.length,v=new Uint8Array(i);for(let y=0;y<i;y++)v[y]=l.charCodeAt(y);const h=new Int16Array(v.buffer),V=new Float32Array(h.length);for(let y=0;y<h.length;y++)V[y]=h[y]/32768;const I=t.createBuffer(1,V.length,24e3);I.getChannelData(0).set(V);const P=t.createBufferSource();P.buffer=I,P.connect(t.destination),p<t.currentTime&&(p=t.currentTime),P.start(p),p+=I.duration,w++,P.onended=()=>{w--,k()}}catch(l){console.error("[VirtualHumanEventAdapter] Failed to decode and play audio:",l)}},u=s=>{switch(s){case"play":m=!1,w=0,p=0,g=!1,t&&t.state==="suspended"&&t.resume();break;case"resume":g=!1,t&&t.state==="suspended"&&t.resume();break;case"pause":g=!0,t&&t.state==="running"&&t.suspend();break;case"stop":g=!1,t&&(t.close(),t=null),p=0,m=!1,w=0;break;case"tts_complete":m=!0,k();break;default:console.warn(`[VirtualHumanEventAdapter] Unknown control action: ${s}`)}},d=()=>{o.value&&o.value.close();try{const s=new URL(e.wsUrl);s.searchParams.append("sessionId",e.screenClientId+"-event"),o.value=new WebSocket(s.toString()),o.value.onopen=()=>{C.value=!0,a("connected"),console.log(`[VirtualHumanEventAdapter] Connected to ${e.wsUrl} for session ${e.screenClientId}-event`)},o.value.onmessage=l=>{try{const i=JSON.parse(l.data);E(i)}catch(i){console.error("[VirtualHumanEventAdapter] Failed to parse message:",l.data,i)}},o.value.onerror=l=>{console.error("[VirtualHumanEventAdapter] WebSocket error:",l),a("error",l)},o.value.onclose=()=>{C.value=!1,console.log("[VirtualHumanEventAdapter] WebSocket disconnected")}}catch(s){console.error("[VirtualHumanEventAdapter] Failed to initialize WebSocket:",s),a("error",s)}},E=s=>{const{type:l,payload:i,action:v}=s;switch(l){case"audio":const h=(i==null?void 0:i.data)||s.data;h&&c(h);break;case"send_event":s.event&&(console.log("adapter send_event:",s),a("eventNotifaction",s));break;case"control":v&&(console.log("adapter control:",v),a("controlEvent",v),u(v));break;case"end":console.log("adapter end:",i),a("end",i);break;case"pause":console.log("adapter pause:",i),a("pause",i);break;default:console.warn(`[VirtualHumanEventAdapter] Unknown message type: ${l}`)}};return n.watch(()=>e.screenClientId,()=>{e.screenClientId&&e.wsUrl&&d()}),n.watch(()=>e.wsUrl,()=>{e.screenClientId&&e.wsUrl&&d()}),n.onMounted(()=>{e.screenClientId&&e.wsUrl&&d()}),n.onUnmounted(()=>{o.value&&o.value.close(),t&&t.close()}),(s,l)=>n.renderSlot(s.$slots,"default")}}),_={install:r=>{r.component("VirtualHumanPersona",U),r.component("VirtualHumanEventAdapter",A)}};f.VirtualHumanEventAdapter=A,f.VirtualHumanPersona=U,f.default=_,Object.defineProperties(f,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
1
+ (function(q,g){typeof exports=="object"&&typeof module<"u"?g(exports,require("vue")):typeof define=="function"&&define.amd?define(["exports","vue"],g):(q=typeof globalThis<"u"?globalThis:q||self,g(q.VirtualHumanCf={},q.Vue))})(this,function(q,g){"use strict";const Rt=["src","muted"],Fe=((e,t)=>{const n=e.__vccOpts||e;for(const[r,s]of t)n[r]=s;return n})(g.defineComponent({__name:"VirtualHumanPersona",props:{videoSrc:{type:String,required:!0},visible:{type:Boolean,default:!1},isPlaying:{type:Boolean,default:!1},muted:{type:Boolean,default:!0},isDark:{type:Boolean,default:!1},screenClientId:{type:String,required:!1},wsUrl:{type:String,required:!1},styles:{type:Object,default:()=>({width:"400px",height:"500px",left:"16px",bottom:"16px"})}},emits:["update:isPlaying","ended","update:visible"],setup(e,{emit:t}){const n=e,r=t,s=g.ref(null),i=g.ref(null),o=g.ref(null),a=g.ref(!1),d=()=>{if(o.value&&o.value.close(),!(!n.wsUrl||!n.screenClientId))try{const E=new URL(n.wsUrl);E.searchParams.append("sessionId",n.screenClientId+"-persona"),o.value=new WebSocket(E.toString()),o.value.onopen=()=>{a.value=!0,console.log(`[VirtualHumanPersona] Connected to ${n.wsUrl} for session ${n.screenClientId}-persona`)},o.value.onmessage=c=>{try{const p=JSON.parse(c.data);f(p)}catch(p){console.error("[VirtualHumanPersona] Failed to parse message:",c.data,p)}},o.value.onerror=c=>{console.error("[VirtualHumanPersona] WebSocket error:",c)},o.value.onclose=()=>{a.value=!1,console.log("[VirtualHumanPersona] WebSocket disconnected")}}catch(E){console.error("[VirtualHumanPersona] Failed to initialize WebSocket:",E)}},f=E=>{const{type:c,action:p}=E;c==="control"&&(p==="play"||p==="resume"?(r("update:isPlaying",!0),r("update:visible",!0)):p==="pause"?(s.value&&s.value.pause(),r("update:isPlaying",!1),r("update:visible",!0)):p==="stop"&&(r("update:isPlaying",!1),r("update:visible",!1),s.value&&(s.value.currentTime=0)))};g.watch(()=>n.screenClientId,()=>{n.screenClientId&&n.wsUrl&&d()}),g.watch(()=>n.wsUrl,()=>{n.screenClientId&&n.wsUrl&&d()}),g.watch(()=>n.isPlaying,E=>{s.value&&(E?s.value.play().catch(c=>console.error("Video play failed:",c)):s.value.pause())});const u=()=>{n.isPlaying||r("update:isPlaying",!0)},m=()=>{n.isPlaying&&r("update:isPlaying",!1)},w=()=>{r("update:isPlaying",!1),r("ended")};return g.onMounted(()=>{n.isPlaying&&s.value&&s.value.play().catch(E=>console.error("Video play failed:",E)),n.screenClientId&&n.wsUrl&&d()}),g.onUnmounted(()=>{o.value&&o.value.close()}),(E,c)=>(g.openBlock(),g.createBlock(g.Transition,{name:"fade"},{default:g.withCtx(()=>[e.visible?(g.openBlock(),g.createElementBlock("div",{key:0,class:g.normalizeClass(["virtual-human-container",{"is-dark":e.isDark}]),style:g.normalizeStyle(e.styles)},[g.createElementVNode("div",{class:"video-wrapper",ref_key:"wrapperRef",ref:i},[g.createElementVNode("video",{ref_key:"videoRef",ref:s,src:e.videoSrc,class:"persona-video",muted:e.muted,playsinline:"",loop:"",autoPlay:"",disablePictureInPicture:"",onPlay:u,onPause:m,onEnded:w},null,40,Rt)],512)],6)):g.createCommentVNode("",!0)]),_:1}))}}),[["__scopeId","data-v-02ec3645"]]);function Be(e,t){return function(){return e.apply(t,arguments)}}const{toString:St}=Object.prototype,{getPrototypeOf:ge}=Object,{iterator:le,toStringTag:Ie}=Symbol,ce=(e=>t=>{const n=St.call(t);return e[n]||(e[n]=n.slice(8,-1).toLowerCase())})(Object.create(null)),D=e=>(e=e.toLowerCase(),t=>ce(t)===e),ue=e=>t=>typeof t===e,{isArray:Q}=Array,Z=ue("undefined");function te(e){return e!==null&&!Z(e)&&e.constructor!==null&&!Z(e.constructor)&&N(e.constructor.isBuffer)&&e.constructor.isBuffer(e)}const Le=D("ArrayBuffer");function Ot(e){let t;return typeof ArrayBuffer<"u"&&ArrayBuffer.isView?t=ArrayBuffer.isView(e):t=e&&e.buffer&&Le(e.buffer),t}const At=ue("string"),N=ue("function"),De=ue("number"),ne=e=>e!==null&&typeof e=="object",Tt=e=>e===!0||e===!1,fe=e=>{if(ce(e)!=="object")return!1;const t=ge(e);return(t===null||t===Object.prototype||Object.getPrototypeOf(t)===null)&&!(Ie in e)&&!(le in e)},Ct=e=>{if(!ne(e)||te(e))return!1;try{return Object.keys(e).length===0&&Object.getPrototypeOf(e)===Object.prototype}catch{return!1}},Pt=D("Date"),xt=D("File"),_t=e=>!!(e&&typeof e.uri<"u"),Nt=e=>e&&typeof e.getParts<"u",Ut=D("Blob"),kt=D("FileList"),Ft=e=>ne(e)&&N(e.pipe);function Bt(){return typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{}}const je=Bt(),ve=typeof je.FormData<"u"?je.FormData:void 0,It=e=>{let t;return e&&(ve&&e instanceof ve||N(e.append)&&((t=ce(e))==="formdata"||t==="object"&&N(e.toString)&&e.toString()==="[object FormData]"))},Lt=D("URLSearchParams"),[Dt,jt,vt,Ht]=["ReadableStream","Request","Response","Headers"].map(D),qt=e=>e.trim?e.trim():e.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"");function re(e,t,{allOwnKeys:n=!1}={}){if(e===null||typeof e>"u")return;let r,s;if(typeof e!="object"&&(e=[e]),Q(e))for(r=0,s=e.length;r<s;r++)t.call(null,e[r],r,e);else{if(te(e))return;const i=n?Object.getOwnPropertyNames(e):Object.keys(e),o=i.length;let a;for(r=0;r<o;r++)a=i[r],t.call(null,e[a],a,e)}}function He(e,t){if(te(e))return null;t=t.toLowerCase();const n=Object.keys(e);let r=n.length,s;for(;r-- >0;)if(s=n[r],t===s.toLowerCase())return s;return null}const J=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:global,qe=e=>!Z(e)&&e!==J;function Ee(){const{caseless:e,skipUndefined:t}=qe(this)&&this||{},n={},r=(s,i)=>{if(i==="__proto__"||i==="constructor"||i==="prototype")return;const o=e&&He(n,i)||i;fe(n[o])&&fe(s)?n[o]=Ee(n[o],s):fe(s)?n[o]=Ee({},s):Q(s)?n[o]=s.slice():(!t||!Z(s))&&(n[o]=s)};for(let s=0,i=arguments.length;s<i;s++)arguments[s]&&re(arguments[s],r);return n}const Mt=(e,t,n,{allOwnKeys:r}={})=>(re(t,(s,i)=>{n&&N(s)?Object.defineProperty(e,i,{value:Be(s,n),writable:!0,enumerable:!0,configurable:!0}):Object.defineProperty(e,i,{value:s,writable:!0,enumerable:!0,configurable:!0})},{allOwnKeys:r}),e),$t=e=>(e.charCodeAt(0)===65279&&(e=e.slice(1)),e),Vt=(e,t,n,r)=>{e.prototype=Object.create(t.prototype,r),Object.defineProperty(e.prototype,"constructor",{value:e,writable:!0,enumerable:!1,configurable:!0}),Object.defineProperty(e,"super",{value:t.prototype}),n&&Object.assign(e.prototype,n)},zt=(e,t,n,r)=>{let s,i,o;const a={};if(t=t||{},e==null)return t;do{for(s=Object.getOwnPropertyNames(e),i=s.length;i-- >0;)o=s[i],(!r||r(o,e,t))&&!a[o]&&(t[o]=e[o],a[o]=!0);e=n!==!1&&ge(e)}while(e&&(!n||n(e,t))&&e!==Object.prototype);return t},Wt=(e,t,n)=>{e=String(e),(n===void 0||n>e.length)&&(n=e.length),n-=t.length;const r=e.indexOf(t,n);return r!==-1&&r===n},Jt=e=>{if(!e)return null;if(Q(e))return e;let t=e.length;if(!De(t))return null;const n=new Array(t);for(;t-- >0;)n[t]=e[t];return n},Kt=(e=>t=>e&&t instanceof e)(typeof Uint8Array<"u"&&ge(Uint8Array)),Xt=(e,t)=>{const r=(e&&e[le]).call(e);let s;for(;(s=r.next())&&!s.done;){const i=s.value;t.call(e,i[0],i[1])}},Gt=(e,t)=>{let n;const r=[];for(;(n=e.exec(t))!==null;)r.push(n);return r},Qt=D("HTMLFormElement"),Zt=e=>e.toLowerCase().replace(/[-_\s]([a-z\d])(\w*)/g,function(n,r,s){return r.toUpperCase()+s}),Me=(({hasOwnProperty:e})=>(t,n)=>e.call(t,n))(Object.prototype),Yt=D("RegExp"),$e=(e,t)=>{const n=Object.getOwnPropertyDescriptors(e),r={};re(n,(s,i)=>{let o;(o=t(s,i,e))!==!1&&(r[i]=o||s)}),Object.defineProperties(e,r)},en=e=>{$e(e,(t,n)=>{if(N(e)&&["arguments","caller","callee"].indexOf(n)!==-1)return!1;const r=e[n];if(N(r)){if(t.enumerable=!1,"writable"in t){t.writable=!1;return}t.set||(t.set=()=>{throw Error("Can not rewrite read-only method '"+n+"'")})}})},tn=(e,t)=>{const n={},r=s=>{s.forEach(i=>{n[i]=!0})};return Q(e)?r(e):r(String(e).split(t)),n},nn=()=>{},rn=(e,t)=>e!=null&&Number.isFinite(e=+e)?e:t;function sn(e){return!!(e&&N(e.append)&&e[Ie]==="FormData"&&e[le])}const on=e=>{const t=new Array(10),n=(r,s)=>{if(ne(r)){if(t.indexOf(r)>=0)return;if(te(r))return r;if(!("toJSON"in r)){t[s]=r;const i=Q(r)?[]:{};return re(r,(o,a)=>{const d=n(o,s+1);!Z(d)&&(i[a]=d)}),t[s]=void 0,i}}return r};return n(e,0)},an=D("AsyncFunction"),ln=e=>e&&(ne(e)||N(e))&&N(e.then)&&N(e.catch),Ve=((e,t)=>e?setImmediate:t?((n,r)=>(J.addEventListener("message",({source:s,data:i})=>{s===J&&i===n&&r.length&&r.shift()()},!1),s=>{r.push(s),J.postMessage(n,"*")}))(`axios@${Math.random()}`,[]):n=>setTimeout(n))(typeof setImmediate=="function",N(J.postMessage)),cn=typeof queueMicrotask<"u"?queueMicrotask.bind(J):typeof process<"u"&&process.nextTick||Ve,l={isArray:Q,isArrayBuffer:Le,isBuffer:te,isFormData:It,isArrayBufferView:Ot,isString:At,isNumber:De,isBoolean:Tt,isObject:ne,isPlainObject:fe,isEmptyObject:Ct,isReadableStream:Dt,isRequest:jt,isResponse:vt,isHeaders:Ht,isUndefined:Z,isDate:Pt,isFile:xt,isReactNativeBlob:_t,isReactNative:Nt,isBlob:Ut,isRegExp:Yt,isFunction:N,isStream:Ft,isURLSearchParams:Lt,isTypedArray:Kt,isFileList:kt,forEach:re,merge:Ee,extend:Mt,trim:qt,stripBOM:$t,inherits:Vt,toFlatObject:zt,kindOf:ce,kindOfTest:D,endsWith:Wt,toArray:Jt,forEachEntry:Xt,matchAll:Gt,isHTMLForm:Qt,hasOwnProperty:Me,hasOwnProp:Me,reduceDescriptors:$e,freezeMethods:en,toObjectSet:tn,toCamelCase:Zt,noop:nn,toFiniteNumber:rn,findKey:He,global:J,isContextDefined:qe,isSpecCompliantForm:sn,toJSONObject:on,isAsyncFn:an,isThenable:ln,setImmediate:Ve,asap:cn,isIterable:e=>e!=null&&N(e[le])};let y=class gt extends Error{static from(t,n,r,s,i,o){const a=new gt(t.message,n||t.code,r,s,i);return a.cause=t,a.name=t.name,t.status!=null&&a.status==null&&(a.status=t.status),o&&Object.assign(a,o),a}constructor(t,n,r,s,i){super(t),Object.defineProperty(this,"message",{value:t,enumerable:!0,writable:!0,configurable:!0}),this.name="AxiosError",this.isAxiosError=!0,n&&(this.code=n),r&&(this.config=r),s&&(this.request=s),i&&(this.response=i,this.status=i.status)}toJSON(){return{message:this.message,name:this.name,description:this.description,number:this.number,fileName:this.fileName,lineNumber:this.lineNumber,columnNumber:this.columnNumber,stack:this.stack,config:l.toJSONObject(this.config),code:this.code,status:this.status}}};y.ERR_BAD_OPTION_VALUE="ERR_BAD_OPTION_VALUE",y.ERR_BAD_OPTION="ERR_BAD_OPTION",y.ECONNABORTED="ECONNABORTED",y.ETIMEDOUT="ETIMEDOUT",y.ERR_NETWORK="ERR_NETWORK",y.ERR_FR_TOO_MANY_REDIRECTS="ERR_FR_TOO_MANY_REDIRECTS",y.ERR_DEPRECATED="ERR_DEPRECATED",y.ERR_BAD_RESPONSE="ERR_BAD_RESPONSE",y.ERR_BAD_REQUEST="ERR_BAD_REQUEST",y.ERR_CANCELED="ERR_CANCELED",y.ERR_NOT_SUPPORT="ERR_NOT_SUPPORT",y.ERR_INVALID_URL="ERR_INVALID_URL";const un=null;function Re(e){return l.isPlainObject(e)||l.isArray(e)}function ze(e){return l.endsWith(e,"[]")?e.slice(0,-2):e}function Se(e,t,n){return e?e.concat(t).map(function(s,i){return s=ze(s),!n&&i?"["+s+"]":s}).join(n?".":""):t}function fn(e){return l.isArray(e)&&!e.some(Re)}const dn=l.toFlatObject(l,{},null,function(t){return/^is[A-Z]/.test(t)});function de(e,t,n){if(!l.isObject(e))throw new TypeError("target must be an object");t=t||new FormData,n=l.toFlatObject(n,{metaTokens:!0,dots:!1,indexes:!1},!1,function(p,h){return!l.isUndefined(h[p])});const r=n.metaTokens,s=n.visitor||u,i=n.dots,o=n.indexes,d=(n.Blob||typeof Blob<"u"&&Blob)&&l.isSpecCompliantForm(t);if(!l.isFunction(s))throw new TypeError("visitor must be a function");function f(c){if(c===null)return"";if(l.isDate(c))return c.toISOString();if(l.isBoolean(c))return c.toString();if(!d&&l.isBlob(c))throw new y("Blob is not supported. Use a Buffer instead.");return l.isArrayBuffer(c)||l.isTypedArray(c)?d&&typeof Blob=="function"?new Blob([c]):Buffer.from(c):c}function u(c,p,h){let A=c;if(l.isReactNative(t)&&l.isReactNativeBlob(c))return t.append(Se(h,p,i),f(c)),!1;if(c&&!h&&typeof c=="object"){if(l.endsWith(p,"{}"))p=r?p:p.slice(0,-2),c=JSON.stringify(c);else if(l.isArray(c)&&fn(c)||(l.isFileList(c)||l.endsWith(p,"[]"))&&(A=l.toArray(c)))return p=ze(p),A.forEach(function(T,C){!(l.isUndefined(T)||T===null)&&t.append(o===!0?Se([p],C,i):o===null?p:p+"[]",f(T))}),!1}return Re(c)?!0:(t.append(Se(h,p,i),f(c)),!1)}const m=[],w=Object.assign(dn,{defaultVisitor:u,convertValue:f,isVisitable:Re});function E(c,p){if(!l.isUndefined(c)){if(m.indexOf(c)!==-1)throw Error("Circular reference detected in "+p.join("."));m.push(c),l.forEach(c,function(A,F){(!(l.isUndefined(A)||A===null)&&s.call(t,A,l.isString(F)?F.trim():F,p,w))===!0&&E(A,p?p.concat(F):[F])}),m.pop()}}if(!l.isObject(e))throw new TypeError("data must be an object");return E(e),t}function We(e){const t={"!":"%21","'":"%27","(":"%28",")":"%29","~":"%7E","%20":"+","%00":"\0"};return encodeURIComponent(e).replace(/[!'()~]|%20|%00/g,function(r){return t[r]})}function Oe(e,t){this._pairs=[],e&&de(e,this,t)}const Je=Oe.prototype;Je.append=function(t,n){this._pairs.push([t,n])},Je.toString=function(t){const n=t?function(r){return t.call(this,r,We)}:We;return this._pairs.map(function(s){return n(s[0])+"="+n(s[1])},"").join("&")};function pn(e){return encodeURIComponent(e).replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+")}function Ke(e,t,n){if(!t)return e;const r=n&&n.encode||pn,s=l.isFunction(n)?{serialize:n}:n,i=s&&s.serialize;let o;if(i?o=i(t,s):o=l.isURLSearchParams(t)?t.toString():new Oe(t,s).toString(r),o){const a=e.indexOf("#");a!==-1&&(e=e.slice(0,a)),e+=(e.indexOf("?")===-1?"?":"&")+o}return e}class Xe{constructor(){this.handlers=[]}use(t,n,r){return this.handlers.push({fulfilled:t,rejected:n,synchronous:r?r.synchronous:!1,runWhen:r?r.runWhen:null}),this.handlers.length-1}eject(t){this.handlers[t]&&(this.handlers[t]=null)}clear(){this.handlers&&(this.handlers=[])}forEach(t){l.forEach(this.handlers,function(r){r!==null&&t(r)})}}const Ae={silentJSONParsing:!0,forcedJSONParsing:!0,clarifyTimeoutError:!1,legacyInterceptorReqResOrdering:!0},hn={isBrowser:!0,classes:{URLSearchParams:typeof URLSearchParams<"u"?URLSearchParams:Oe,FormData:typeof FormData<"u"?FormData:null,Blob:typeof Blob<"u"?Blob:null},protocols:["http","https","file","blob","url","data"]},Te=typeof window<"u"&&typeof document<"u",Ce=typeof navigator=="object"&&navigator||void 0,mn=Te&&(!Ce||["ReactNative","NativeScript","NS"].indexOf(Ce.product)<0),yn=typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope&&typeof self.importScripts=="function",bn=Te&&window.location.href||"http://localhost",x={...Object.freeze(Object.defineProperty({__proto__:null,hasBrowserEnv:Te,hasStandardBrowserEnv:mn,hasStandardBrowserWebWorkerEnv:yn,navigator:Ce,origin:bn},Symbol.toStringTag,{value:"Module"})),...hn};function wn(e,t){return de(e,new x.classes.URLSearchParams,{visitor:function(n,r,s,i){return x.isNode&&l.isBuffer(n)?(this.append(r,n.toString("base64")),!1):i.defaultVisitor.apply(this,arguments)},...t})}function gn(e){return l.matchAll(/\w+|\[(\w*)]/g,e).map(t=>t[0]==="[]"?"":t[1]||t[0])}function En(e){const t={},n=Object.keys(e);let r;const s=n.length;let i;for(r=0;r<s;r++)i=n[r],t[i]=e[i];return t}function Ge(e){function t(n,r,s,i){let o=n[i++];if(o==="__proto__")return!0;const a=Number.isFinite(+o),d=i>=n.length;return o=!o&&l.isArray(s)?s.length:o,d?(l.hasOwnProp(s,o)?s[o]=[s[o],r]:s[o]=r,!a):((!s[o]||!l.isObject(s[o]))&&(s[o]=[]),t(n,r,s[o],i)&&l.isArray(s[o])&&(s[o]=En(s[o])),!a)}if(l.isFormData(e)&&l.isFunction(e.entries)){const n={};return l.forEachEntry(e,(r,s)=>{t(gn(r),s,n,0)}),n}return null}function Rn(e,t,n){if(l.isString(e))try{return(t||JSON.parse)(e),l.trim(e)}catch(r){if(r.name!=="SyntaxError")throw r}return(n||JSON.stringify)(e)}const se={transitional:Ae,adapter:["xhr","http","fetch"],transformRequest:[function(t,n){const r=n.getContentType()||"",s=r.indexOf("application/json")>-1,i=l.isObject(t);if(i&&l.isHTMLForm(t)&&(t=new FormData(t)),l.isFormData(t))return s?JSON.stringify(Ge(t)):t;if(l.isArrayBuffer(t)||l.isBuffer(t)||l.isStream(t)||l.isFile(t)||l.isBlob(t)||l.isReadableStream(t))return t;if(l.isArrayBufferView(t))return t.buffer;if(l.isURLSearchParams(t))return n.setContentType("application/x-www-form-urlencoded;charset=utf-8",!1),t.toString();let a;if(i){if(r.indexOf("application/x-www-form-urlencoded")>-1)return wn(t,this.formSerializer).toString();if((a=l.isFileList(t))||r.indexOf("multipart/form-data")>-1){const d=this.env&&this.env.FormData;return de(a?{"files[]":t}:t,d&&new d,this.formSerializer)}}return i||s?(n.setContentType("application/json",!1),Rn(t)):t}],transformResponse:[function(t){const n=this.transitional||se.transitional,r=n&&n.forcedJSONParsing,s=this.responseType==="json";if(l.isResponse(t)||l.isReadableStream(t))return t;if(t&&l.isString(t)&&(r&&!this.responseType||s)){const o=!(n&&n.silentJSONParsing)&&s;try{return JSON.parse(t,this.parseReviver)}catch(a){if(o)throw a.name==="SyntaxError"?y.from(a,y.ERR_BAD_RESPONSE,this,null,this.response):a}}return t}],timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,maxBodyLength:-1,env:{FormData:x.classes.FormData,Blob:x.classes.Blob},validateStatus:function(t){return t>=200&&t<300},headers:{common:{Accept:"application/json, text/plain, */*","Content-Type":void 0}}};l.forEach(["delete","get","head","post","put","patch"],e=>{se.headers[e]={}});const Sn=l.toObjectSet(["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"]),On=e=>{const t={};let n,r,s;return e&&e.split(`
2
+ `).forEach(function(o){s=o.indexOf(":"),n=o.substring(0,s).trim().toLowerCase(),r=o.substring(s+1).trim(),!(!n||t[n]&&Sn[n])&&(n==="set-cookie"?t[n]?t[n].push(r):t[n]=[r]:t[n]=t[n]?t[n]+", "+r:r)}),t},Qe=Symbol("internals");function oe(e){return e&&String(e).trim().toLowerCase()}function pe(e){return e===!1||e==null?e:l.isArray(e)?e.map(pe):String(e).replace(/[\r\n]+$/,"")}function An(e){const t=Object.create(null),n=/([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g;let r;for(;r=n.exec(e);)t[r[1]]=r[2];return t}const Tn=e=>/^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(e.trim());function Pe(e,t,n,r,s){if(l.isFunction(r))return r.call(this,t,n);if(s&&(t=n),!!l.isString(t)){if(l.isString(r))return t.indexOf(r)!==-1;if(l.isRegExp(r))return r.test(t)}}function Cn(e){return e.trim().toLowerCase().replace(/([a-z\d])(\w*)/g,(t,n,r)=>n.toUpperCase()+r)}function Pn(e,t){const n=l.toCamelCase(" "+t);["get","set","has"].forEach(r=>{Object.defineProperty(e,r+n,{value:function(s,i,o){return this[r].call(this,t,s,i,o)},configurable:!0})})}let U=class{constructor(t){t&&this.set(t)}set(t,n,r){const s=this;function i(a,d,f){const u=oe(d);if(!u)throw new Error("header name must be a non-empty string");const m=l.findKey(s,u);(!m||s[m]===void 0||f===!0||f===void 0&&s[m]!==!1)&&(s[m||d]=pe(a))}const o=(a,d)=>l.forEach(a,(f,u)=>i(f,u,d));if(l.isPlainObject(t)||t instanceof this.constructor)o(t,n);else if(l.isString(t)&&(t=t.trim())&&!Tn(t))o(On(t),n);else if(l.isObject(t)&&l.isIterable(t)){let a={},d,f;for(const u of t){if(!l.isArray(u))throw TypeError("Object iterator must return a key-value pair");a[f=u[0]]=(d=a[f])?l.isArray(d)?[...d,u[1]]:[d,u[1]]:u[1]}o(a,n)}else t!=null&&i(n,t,r);return this}get(t,n){if(t=oe(t),t){const r=l.findKey(this,t);if(r){const s=this[r];if(!n)return s;if(n===!0)return An(s);if(l.isFunction(n))return n.call(this,s,r);if(l.isRegExp(n))return n.exec(s);throw new TypeError("parser must be boolean|regexp|function")}}}has(t,n){if(t=oe(t),t){const r=l.findKey(this,t);return!!(r&&this[r]!==void 0&&(!n||Pe(this,this[r],r,n)))}return!1}delete(t,n){const r=this;let s=!1;function i(o){if(o=oe(o),o){const a=l.findKey(r,o);a&&(!n||Pe(r,r[a],a,n))&&(delete r[a],s=!0)}}return l.isArray(t)?t.forEach(i):i(t),s}clear(t){const n=Object.keys(this);let r=n.length,s=!1;for(;r--;){const i=n[r];(!t||Pe(this,this[i],i,t,!0))&&(delete this[i],s=!0)}return s}normalize(t){const n=this,r={};return l.forEach(this,(s,i)=>{const o=l.findKey(r,i);if(o){n[o]=pe(s),delete n[i];return}const a=t?Cn(i):String(i).trim();a!==i&&delete n[i],n[a]=pe(s),r[a]=!0}),this}concat(...t){return this.constructor.concat(this,...t)}toJSON(t){const n=Object.create(null);return l.forEach(this,(r,s)=>{r!=null&&r!==!1&&(n[s]=t&&l.isArray(r)?r.join(", "):r)}),n}[Symbol.iterator](){return Object.entries(this.toJSON())[Symbol.iterator]()}toString(){return Object.entries(this.toJSON()).map(([t,n])=>t+": "+n).join(`
3
+ `)}getSetCookie(){return this.get("set-cookie")||[]}get[Symbol.toStringTag](){return"AxiosHeaders"}static from(t){return t instanceof this?t:new this(t)}static concat(t,...n){const r=new this(t);return n.forEach(s=>r.set(s)),r}static accessor(t){const r=(this[Qe]=this[Qe]={accessors:{}}).accessors,s=this.prototype;function i(o){const a=oe(o);r[a]||(Pn(s,o),r[a]=!0)}return l.isArray(t)?t.forEach(i):i(t),this}};U.accessor(["Content-Type","Content-Length","Accept","Accept-Encoding","User-Agent","Authorization"]),l.reduceDescriptors(U.prototype,({value:e},t)=>{let n=t[0].toUpperCase()+t.slice(1);return{get:()=>e,set(r){this[n]=r}}}),l.freezeMethods(U);function xe(e,t){const n=this||se,r=t||n,s=U.from(r.headers);let i=r.data;return l.forEach(e,function(a){i=a.call(n,i,s.normalize(),t?t.status:void 0)}),s.normalize(),i}function Ze(e){return!!(e&&e.__CANCEL__)}let ie=class extends y{constructor(t,n,r){super(t??"canceled",y.ERR_CANCELED,n,r),this.name="CanceledError",this.__CANCEL__=!0}};function Ye(e,t,n){const r=n.config.validateStatus;!n.status||!r||r(n.status)?e(n):t(new y("Request failed with status code "+n.status,[y.ERR_BAD_REQUEST,y.ERR_BAD_RESPONSE][Math.floor(n.status/100)-4],n.config,n.request,n))}function xn(e){const t=/^([-+\w]{1,25})(:?\/\/|:)/.exec(e);return t&&t[1]||""}function _n(e,t){e=e||10;const n=new Array(e),r=new Array(e);let s=0,i=0,o;return t=t!==void 0?t:1e3,function(d){const f=Date.now(),u=r[i];o||(o=f),n[s]=d,r[s]=f;let m=i,w=0;for(;m!==s;)w+=n[m++],m=m%e;if(s=(s+1)%e,s===i&&(i=(i+1)%e),f-o<t)return;const E=u&&f-u;return E?Math.round(w*1e3/E):void 0}}function Nn(e,t){let n=0,r=1e3/t,s,i;const o=(f,u=Date.now())=>{n=u,s=null,i&&(clearTimeout(i),i=null),e(...f)};return[(...f)=>{const u=Date.now(),m=u-n;m>=r?o(f,u):(s=f,i||(i=setTimeout(()=>{i=null,o(s)},r-m)))},()=>s&&o(s)]}const he=(e,t,n=3)=>{let r=0;const s=_n(50,250);return Nn(i=>{const o=i.loaded,a=i.lengthComputable?i.total:void 0,d=o-r,f=s(d),u=o<=a;r=o;const m={loaded:o,total:a,progress:a?o/a:void 0,bytes:d,rate:f||void 0,estimated:f&&a&&u?(a-o)/f:void 0,event:i,lengthComputable:a!=null,[t?"download":"upload"]:!0};e(m)},n)},et=(e,t)=>{const n=e!=null;return[r=>t[0]({lengthComputable:n,total:e,loaded:r}),t[1]]},tt=e=>(...t)=>l.asap(()=>e(...t)),Un=x.hasStandardBrowserEnv?((e,t)=>n=>(n=new URL(n,x.origin),e.protocol===n.protocol&&e.host===n.host&&(t||e.port===n.port)))(new URL(x.origin),x.navigator&&/(msie|trident)/i.test(x.navigator.userAgent)):()=>!0,kn=x.hasStandardBrowserEnv?{write(e,t,n,r,s,i,o){if(typeof document>"u")return;const a=[`${e}=${encodeURIComponent(t)}`];l.isNumber(n)&&a.push(`expires=${new Date(n).toUTCString()}`),l.isString(r)&&a.push(`path=${r}`),l.isString(s)&&a.push(`domain=${s}`),i===!0&&a.push("secure"),l.isString(o)&&a.push(`SameSite=${o}`),document.cookie=a.join("; ")},read(e){if(typeof document>"u")return null;const t=document.cookie.match(new RegExp("(?:^|; )"+e+"=([^;]*)"));return t?decodeURIComponent(t[1]):null},remove(e){this.write(e,"",Date.now()-864e5,"/")}}:{write(){},read(){return null},remove(){}};function Fn(e){return typeof e!="string"?!1:/^([a-z][a-z\d+\-.]*:)?\/\//i.test(e)}function Bn(e,t){return t?e.replace(/\/?\/$/,"")+"/"+t.replace(/^\/+/,""):e}function nt(e,t,n){let r=!Fn(t);return e&&(r||n==!1)?Bn(e,t):t}const rt=e=>e instanceof U?{...e}:e;function K(e,t){t=t||{};const n={};function r(f,u,m,w){return l.isPlainObject(f)&&l.isPlainObject(u)?l.merge.call({caseless:w},f,u):l.isPlainObject(u)?l.merge({},u):l.isArray(u)?u.slice():u}function s(f,u,m,w){if(l.isUndefined(u)){if(!l.isUndefined(f))return r(void 0,f,m,w)}else return r(f,u,m,w)}function i(f,u){if(!l.isUndefined(u))return r(void 0,u)}function o(f,u){if(l.isUndefined(u)){if(!l.isUndefined(f))return r(void 0,f)}else return r(void 0,u)}function a(f,u,m){if(m in t)return r(f,u);if(m in e)return r(void 0,f)}const d={url:i,method:i,data:i,baseURL:o,transformRequest:o,transformResponse:o,paramsSerializer:o,timeout:o,timeoutMessage:o,withCredentials:o,withXSRFToken:o,adapter:o,responseType:o,xsrfCookieName:o,xsrfHeaderName:o,onUploadProgress:o,onDownloadProgress:o,decompress:o,maxContentLength:o,maxBodyLength:o,beforeRedirect:o,transport:o,httpAgent:o,httpsAgent:o,cancelToken:o,socketPath:o,responseEncoding:o,validateStatus:a,headers:(f,u,m)=>s(rt(f),rt(u),m,!0)};return l.forEach(Object.keys({...e,...t}),function(u){if(u==="__proto__"||u==="constructor"||u==="prototype")return;const m=l.hasOwnProp(d,u)?d[u]:s,w=m(e[u],t[u],u);l.isUndefined(w)&&m!==a||(n[u]=w)}),n}const st=e=>{const t=K({},e);let{data:n,withXSRFToken:r,xsrfHeaderName:s,xsrfCookieName:i,headers:o,auth:a}=t;if(t.headers=o=U.from(o),t.url=Ke(nt(t.baseURL,t.url,t.allowAbsoluteUrls),e.params,e.paramsSerializer),a&&o.set("Authorization","Basic "+btoa((a.username||"")+":"+(a.password?unescape(encodeURIComponent(a.password)):""))),l.isFormData(n)){if(x.hasStandardBrowserEnv||x.hasStandardBrowserWebWorkerEnv)o.setContentType(void 0);else if(l.isFunction(n.getHeaders)){const d=n.getHeaders(),f=["content-type","content-length"];Object.entries(d).forEach(([u,m])=>{f.includes(u.toLowerCase())&&o.set(u,m)})}}if(x.hasStandardBrowserEnv&&(r&&l.isFunction(r)&&(r=r(t)),r||r!==!1&&Un(t.url))){const d=s&&i&&kn.read(i);d&&o.set(s,d)}return t},In=typeof XMLHttpRequest<"u"&&function(e){return new Promise(function(n,r){const s=st(e);let i=s.data;const o=U.from(s.headers).normalize();let{responseType:a,onUploadProgress:d,onDownloadProgress:f}=s,u,m,w,E,c;function p(){E&&E(),c&&c(),s.cancelToken&&s.cancelToken.unsubscribe(u),s.signal&&s.signal.removeEventListener("abort",u)}let h=new XMLHttpRequest;h.open(s.method.toUpperCase(),s.url,!0),h.timeout=s.timeout;function A(){if(!h)return;const T=U.from("getAllResponseHeaders"in h&&h.getAllResponseHeaders()),k={data:!a||a==="text"||a==="json"?h.responseText:h.response,status:h.status,statusText:h.statusText,headers:T,config:e,request:h};Ye(function(P){n(P),p()},function(P){r(P),p()},k),h=null}"onloadend"in h?h.onloadend=A:h.onreadystatechange=function(){!h||h.readyState!==4||h.status===0&&!(h.responseURL&&h.responseURL.indexOf("file:")===0)||setTimeout(A)},h.onabort=function(){h&&(r(new y("Request aborted",y.ECONNABORTED,e,h)),h=null)},h.onerror=function(C){const k=C&&C.message?C.message:"Network Error",j=new y(k,y.ERR_NETWORK,e,h);j.event=C||null,r(j),h=null},h.ontimeout=function(){let C=s.timeout?"timeout of "+s.timeout+"ms exceeded":"timeout exceeded";const k=s.transitional||Ae;s.timeoutErrorMessage&&(C=s.timeoutErrorMessage),r(new y(C,k.clarifyTimeoutError?y.ETIMEDOUT:y.ECONNABORTED,e,h)),h=null},i===void 0&&o.setContentType(null),"setRequestHeader"in h&&l.forEach(o.toJSON(),function(C,k){h.setRequestHeader(k,C)}),l.isUndefined(s.withCredentials)||(h.withCredentials=!!s.withCredentials),a&&a!=="json"&&(h.responseType=s.responseType),f&&([w,c]=he(f,!0),h.addEventListener("progress",w)),d&&h.upload&&([m,E]=he(d),h.upload.addEventListener("progress",m),h.upload.addEventListener("loadend",E)),(s.cancelToken||s.signal)&&(u=T=>{h&&(r(!T||T.type?new ie(null,e,h):T),h.abort(),h=null)},s.cancelToken&&s.cancelToken.subscribe(u),s.signal&&(s.signal.aborted?u():s.signal.addEventListener("abort",u)));const F=xn(s.url);if(F&&x.protocols.indexOf(F)===-1){r(new y("Unsupported protocol "+F+":",y.ERR_BAD_REQUEST,e));return}h.send(i||null)})},Ln=(e,t)=>{const{length:n}=e=e?e.filter(Boolean):[];if(t||n){let r=new AbortController,s;const i=function(f){if(!s){s=!0,a();const u=f instanceof Error?f:this.reason;r.abort(u instanceof y?u:new ie(u instanceof Error?u.message:u))}};let o=t&&setTimeout(()=>{o=null,i(new y(`timeout of ${t}ms exceeded`,y.ETIMEDOUT))},t);const a=()=>{e&&(o&&clearTimeout(o),o=null,e.forEach(f=>{f.unsubscribe?f.unsubscribe(i):f.removeEventListener("abort",i)}),e=null)};e.forEach(f=>f.addEventListener("abort",i));const{signal:d}=r;return d.unsubscribe=()=>l.asap(a),d}},Dn=function*(e,t){let n=e.byteLength;if(n<t){yield e;return}let r=0,s;for(;r<n;)s=r+t,yield e.slice(r,s),r=s},jn=async function*(e,t){for await(const n of vn(e))yield*Dn(n,t)},vn=async function*(e){if(e[Symbol.asyncIterator]){yield*e;return}const t=e.getReader();try{for(;;){const{done:n,value:r}=await t.read();if(n)break;yield r}}finally{await t.cancel()}},ot=(e,t,n,r)=>{const s=jn(e,t);let i=0,o,a=d=>{o||(o=!0,r&&r(d))};return new ReadableStream({async pull(d){try{const{done:f,value:u}=await s.next();if(f){a(),d.close();return}let m=u.byteLength;if(n){let w=i+=m;n(w)}d.enqueue(new Uint8Array(u))}catch(f){throw a(f),f}},cancel(d){return a(d),s.return()}},{highWaterMark:2})},it=64*1024,{isFunction:me}=l,Hn=(({Request:e,Response:t})=>({Request:e,Response:t}))(l.global),{ReadableStream:at,TextEncoder:lt}=l.global,ct=(e,...t)=>{try{return!!e(...t)}catch{return!1}},qn=e=>{e=l.merge.call({skipUndefined:!0},Hn,e);const{fetch:t,Request:n,Response:r}=e,s=t?me(t):typeof fetch=="function",i=me(n),o=me(r);if(!s)return!1;const a=s&&me(at),d=s&&(typeof lt=="function"?(c=>p=>c.encode(p))(new lt):async c=>new Uint8Array(await new n(c).arrayBuffer())),f=i&&a&&ct(()=>{let c=!1;const p=new at,h=new n(x.origin,{body:p,method:"POST",get duplex(){return c=!0,"half"}}).headers.has("Content-Type");return p.cancel(),c&&!h}),u=o&&a&&ct(()=>l.isReadableStream(new r("").body)),m={stream:u&&(c=>c.body)};s&&["text","arrayBuffer","blob","formData","stream"].forEach(c=>{!m[c]&&(m[c]=(p,h)=>{let A=p&&p[c];if(A)return A.call(p);throw new y(`Response type '${c}' is not supported`,y.ERR_NOT_SUPPORT,h)})});const w=async c=>{if(c==null)return 0;if(l.isBlob(c))return c.size;if(l.isSpecCompliantForm(c))return(await new n(x.origin,{method:"POST",body:c}).arrayBuffer()).byteLength;if(l.isArrayBufferView(c)||l.isArrayBuffer(c))return c.byteLength;if(l.isURLSearchParams(c)&&(c=c+""),l.isString(c))return(await d(c)).byteLength},E=async(c,p)=>{const h=l.toFiniteNumber(c.getContentLength());return h??w(p)};return async c=>{let{url:p,method:h,data:A,signal:F,cancelToken:T,timeout:C,onDownloadProgress:k,onUploadProgress:j,responseType:P,headers:G,withCredentials:Y="same-origin",fetchOptions:ae}=st(c),we=t||fetch;P=P?(P+"").toLowerCase():"text";let ee=Ln([F,T&&T.toAbortSignal()],C),M=null;const $=ee&&ee.unsubscribe&&(()=>{ee.unsubscribe()});let b;try{if(j&&f&&h!=="get"&&h!=="head"&&(b=await E(G,A))!==0){let I=new n(p,{method:"POST",body:A,duplex:"half"}),H;if(l.isFormData(A)&&(H=I.headers.get("content-type"))&&G.setContentType(H),I.body){const[z,W]=et(b,he(tt(j)));A=ot(I.body,it,z,W)}}l.isString(Y)||(Y=Y?"include":"omit");const R=i&&"credentials"in n.prototype,S={...ae,signal:ee,method:h.toUpperCase(),headers:G.normalize().toJSON(),body:A,duplex:"half",credentials:R?Y:void 0};M=i&&new n(p,S);let _=await(i?we(M,ae):we(p,S));const V=u&&(P==="stream"||P==="response");if(u&&(k||V&&$)){const I={};["status","statusText","headers"].forEach(L=>{I[L]=_[L]});const H=l.toFiniteNumber(_.headers.get("content-length")),[z,W]=k&&et(H,he(tt(k),!0))||[];_=new r(ot(_.body,it,z,()=>{W&&W(),$&&$()}),I)}P=P||"text";let v=await m[l.findKey(m,P)||"text"](_,c);return!V&&$&&$(),await new Promise((I,H)=>{Ye(I,H,{data:v,headers:U.from(_.headers),status:_.status,statusText:_.statusText,config:c,request:M})})}catch(R){throw $&&$(),R&&R.name==="TypeError"&&/Load failed|fetch/i.test(R.message)?Object.assign(new y("Network Error",y.ERR_NETWORK,c,M,R&&R.response),{cause:R.cause||R}):y.from(R,R&&R.code,c,M,R&&R.response)}}},Mn=new Map,ut=e=>{let t=e&&e.env||{};const{fetch:n,Request:r,Response:s}=t,i=[r,s,n];let o=i.length,a=o,d,f,u=Mn;for(;a--;)d=i[a],f=u.get(d),f===void 0&&u.set(d,f=a?new Map:qn(t)),u=f;return f};ut();const _e={http:un,xhr:In,fetch:{get:ut}};l.forEach(_e,(e,t)=>{if(e){try{Object.defineProperty(e,"name",{value:t})}catch{}Object.defineProperty(e,"adapterName",{value:t})}});const ft=e=>`- ${e}`,$n=e=>l.isFunction(e)||e===null||e===!1;function Vn(e,t){e=l.isArray(e)?e:[e];const{length:n}=e;let r,s;const i={};for(let o=0;o<n;o++){r=e[o];let a;if(s=r,!$n(r)&&(s=_e[(a=String(r)).toLowerCase()],s===void 0))throw new y(`Unknown adapter '${a}'`);if(s&&(l.isFunction(s)||(s=s.get(t))))break;i[a||"#"+o]=s}if(!s){const o=Object.entries(i).map(([d,f])=>`adapter ${d} `+(f===!1?"is not supported by the environment":"is not available in the build"));let a=n?o.length>1?`since :
4
+ `+o.map(ft).join(`
5
+ `):" "+ft(o[0]):"as no adapter specified";throw new y("There is no suitable adapter to dispatch the request "+a,"ERR_NOT_SUPPORT")}return s}const dt={getAdapter:Vn,adapters:_e};function Ne(e){if(e.cancelToken&&e.cancelToken.throwIfRequested(),e.signal&&e.signal.aborted)throw new ie(null,e)}function pt(e){return Ne(e),e.headers=U.from(e.headers),e.data=xe.call(e,e.transformRequest),["post","put","patch"].indexOf(e.method)!==-1&&e.headers.setContentType("application/x-www-form-urlencoded",!1),dt.getAdapter(e.adapter||se.adapter,e)(e).then(function(r){return Ne(e),r.data=xe.call(e,e.transformResponse,r),r.headers=U.from(r.headers),r},function(r){return Ze(r)||(Ne(e),r&&r.response&&(r.response.data=xe.call(e,e.transformResponse,r.response),r.response.headers=U.from(r.response.headers))),Promise.reject(r)})}const ht="1.14.0",ye={};["object","boolean","number","function","string","symbol"].forEach((e,t)=>{ye[e]=function(r){return typeof r===e||"a"+(t<1?"n ":" ")+e}});const mt={};ye.transitional=function(t,n,r){function s(i,o){return"[Axios v"+ht+"] Transitional option '"+i+"'"+o+(r?". "+r:"")}return(i,o,a)=>{if(t===!1)throw new y(s(o," has been removed"+(n?" in "+n:"")),y.ERR_DEPRECATED);return n&&!mt[o]&&(mt[o]=!0,console.warn(s(o," has been deprecated since v"+n+" and will be removed in the near future"))),t?t(i,o,a):!0}},ye.spelling=function(t){return(n,r)=>(console.warn(`${r} is likely a misspelling of ${t}`),!0)};function zn(e,t,n){if(typeof e!="object")throw new y("options must be an object",y.ERR_BAD_OPTION_VALUE);const r=Object.keys(e);let s=r.length;for(;s-- >0;){const i=r[s],o=t[i];if(o){const a=e[i],d=a===void 0||o(a,i,e);if(d!==!0)throw new y("option "+i+" must be "+d,y.ERR_BAD_OPTION_VALUE);continue}if(n!==!0)throw new y("Unknown option "+i,y.ERR_BAD_OPTION)}}const be={assertOptions:zn,validators:ye},B=be.validators;let X=class{constructor(t){this.defaults=t||{},this.interceptors={request:new Xe,response:new Xe}}async request(t,n){try{return await this._request(t,n)}catch(r){if(r instanceof Error){let s={};Error.captureStackTrace?Error.captureStackTrace(s):s=new Error;const i=s.stack?s.stack.replace(/^.+\n/,""):"";try{r.stack?i&&!String(r.stack).endsWith(i.replace(/^.+\n.+\n/,""))&&(r.stack+=`
6
+ `+i):r.stack=i}catch{}}throw r}}_request(t,n){typeof t=="string"?(n=n||{},n.url=t):n=t||{},n=K(this.defaults,n);const{transitional:r,paramsSerializer:s,headers:i}=n;r!==void 0&&be.assertOptions(r,{silentJSONParsing:B.transitional(B.boolean),forcedJSONParsing:B.transitional(B.boolean),clarifyTimeoutError:B.transitional(B.boolean),legacyInterceptorReqResOrdering:B.transitional(B.boolean)},!1),s!=null&&(l.isFunction(s)?n.paramsSerializer={serialize:s}:be.assertOptions(s,{encode:B.function,serialize:B.function},!0)),n.allowAbsoluteUrls!==void 0||(this.defaults.allowAbsoluteUrls!==void 0?n.allowAbsoluteUrls=this.defaults.allowAbsoluteUrls:n.allowAbsoluteUrls=!0),be.assertOptions(n,{baseUrl:B.spelling("baseURL"),withXsrfToken:B.spelling("withXSRFToken")},!0),n.method=(n.method||this.defaults.method||"get").toLowerCase();let o=i&&l.merge(i.common,i[n.method]);i&&l.forEach(["delete","get","head","post","put","patch","common"],c=>{delete i[c]}),n.headers=U.concat(o,i);const a=[];let d=!0;this.interceptors.request.forEach(function(p){if(typeof p.runWhen=="function"&&p.runWhen(n)===!1)return;d=d&&p.synchronous;const h=n.transitional||Ae;h&&h.legacyInterceptorReqResOrdering?a.unshift(p.fulfilled,p.rejected):a.push(p.fulfilled,p.rejected)});const f=[];this.interceptors.response.forEach(function(p){f.push(p.fulfilled,p.rejected)});let u,m=0,w;if(!d){const c=[pt.bind(this),void 0];for(c.unshift(...a),c.push(...f),w=c.length,u=Promise.resolve(n);m<w;)u=u.then(c[m++],c[m++]);return u}w=a.length;let E=n;for(;m<w;){const c=a[m++],p=a[m++];try{E=c(E)}catch(h){p.call(this,h);break}}try{u=pt.call(this,E)}catch(c){return Promise.reject(c)}for(m=0,w=f.length;m<w;)u=u.then(f[m++],f[m++]);return u}getUri(t){t=K(this.defaults,t);const n=nt(t.baseURL,t.url,t.allowAbsoluteUrls);return Ke(n,t.params,t.paramsSerializer)}};l.forEach(["delete","get","head","options"],function(t){X.prototype[t]=function(n,r){return this.request(K(r||{},{method:t,url:n,data:(r||{}).data}))}}),l.forEach(["post","put","patch"],function(t){function n(r){return function(i,o,a){return this.request(K(a||{},{method:t,headers:r?{"Content-Type":"multipart/form-data"}:{},url:i,data:o}))}}X.prototype[t]=n(),X.prototype[t+"Form"]=n(!0)});let Wn=class Et{constructor(t){if(typeof t!="function")throw new TypeError("executor must be a function.");let n;this.promise=new Promise(function(i){n=i});const r=this;this.promise.then(s=>{if(!r._listeners)return;let i=r._listeners.length;for(;i-- >0;)r._listeners[i](s);r._listeners=null}),this.promise.then=s=>{let i;const o=new Promise(a=>{r.subscribe(a),i=a}).then(s);return o.cancel=function(){r.unsubscribe(i)},o},t(function(i,o,a){r.reason||(r.reason=new ie(i,o,a),n(r.reason))})}throwIfRequested(){if(this.reason)throw this.reason}subscribe(t){if(this.reason){t(this.reason);return}this._listeners?this._listeners.push(t):this._listeners=[t]}unsubscribe(t){if(!this._listeners)return;const n=this._listeners.indexOf(t);n!==-1&&this._listeners.splice(n,1)}toAbortSignal(){const t=new AbortController,n=r=>{t.abort(r)};return this.subscribe(n),t.signal.unsubscribe=()=>this.unsubscribe(n),t.signal}static source(){let t;return{token:new Et(function(s){t=s}),cancel:t}}};function Jn(e){return function(n){return e.apply(null,n)}}function Kn(e){return l.isObject(e)&&e.isAxiosError===!0}const Ue={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511,WebServerIsDown:521,ConnectionTimedOut:522,OriginIsUnreachable:523,TimeoutOccurred:524,SslHandshakeFailed:525,InvalidSslCertificate:526};Object.entries(Ue).forEach(([e,t])=>{Ue[t]=e});function yt(e){const t=new X(e),n=Be(X.prototype.request,t);return l.extend(n,X.prototype,t,{allOwnKeys:!0}),l.extend(n,t,null,{allOwnKeys:!0}),n.create=function(s){return yt(K(e,s))},n}const O=yt(se);O.Axios=X,O.CanceledError=ie,O.CancelToken=Wn,O.isCancel=Ze,O.VERSION=ht,O.toFormData=de,O.AxiosError=y,O.Cancel=O.CanceledError,O.all=function(t){return Promise.all(t)},O.spread=Jn,O.isAxiosError=Kn,O.mergeConfig=K,O.AxiosHeaders=U,O.formToJSON=e=>Ge(l.isHTMLForm(e)?new FormData(e):e),O.getAdapter=dt.getAdapter,O.HttpStatusCode=Ue,O.default=O;const{Axios:sr,AxiosError:or,CanceledError:ir,isCancel:ar,CancelToken:lr,VERSION:cr,all:ur,Cancel:fr,isAxiosError:dr,spread:pr,toFormData:hr,AxiosHeaders:mr,HttpStatusCode:yr,formToJSON:br,getAdapter:wr,mergeConfig:gr}=O,bt=O.create({baseURL:"http://t1.lingganai.cyou:90",timeout:1e4});bt.interceptors.response.use(e=>{const t=e.data;return t.code===200?t.data:Promise.reject(new Error(t.message||"Error"))},e=>Promise.reject(e));const ke=(e,t)=>bt.post("/api/screen/control",{screenClientId:e,action:t}),wt=g.defineComponent({__name:"VirtualHumanEventAdapter",props:{screenClientId:{type:String,required:!0},wsUrl:{type:String,required:!0}},emits:["eventNotifaction","controlEvent","end","pause","connected","error","playComplete"],setup(e,{expose:t,emit:n}){const r=e,s=n,i=g.ref(null),o=g.ref(!1);let a=null,d=0,f=!1,u=0,m=!1;const w=new Map,E=new Set,c=new Map;let p=null;t({pause:()=>o.value?ke(r.screenClientId,"pause").then(()=>Promise.resolve(!0)).catch(()=>Promise.reject(!1)):Promise.reject(!1),resume:()=>o.value?ke(r.screenClientId,"resume").then(()=>Promise.resolve(!0)).catch(()=>Promise.reject(!1)):Promise.reject(!1),stop:()=>o.value?ke(r.screenClientId,"stop").then(()=>Promise.resolve(!0)).catch(()=>Promise.reject(!1)):Promise.reject(!1)});const T=b=>{if(typeof b=="number"&&Number.isFinite(b))return b;if(typeof b=="string"&&b.trim()!==""){const R=Number(b);if(Number.isFinite(R))return R}return null},C=()=>{p!==null&&(window.clearInterval(p),p=null)},k=()=>{C(),w.clear(),E.clear(),c.clear()},j=()=>{for(const[b]of w)if(!E.has(b)&&c.has(b))return!0;return!1},P=()=>{if(!(!a||a.state!=="running")){for(const[b,R]of c){if(E.has(b))continue;const S=w.get(b);S&&a.currentTime+.005>=R&&(E.add(b),w.delete(b),s("eventNotifaction",S))}j()||C()}},G=()=>{p===null&&j()&&(p=window.setInterval(()=>{P()},30))},Y=()=>{a||(a=new(window.AudioContext||window.webkitAudioContext)({sampleRate:24e3})),a.state==="suspended"&&!m&&a.resume()},ae=()=>{f&&u===0&&(s("playComplete",r.screenClientId),f=!1)},we=(b,R)=>{if(Y(),!!a)try{const S=window.atob(b),_=S.length,V=new Uint8Array(_);for(let L=0;L<_;L++)V[L]=S.charCodeAt(L);const v=new Int16Array(V.buffer),I=new Float32Array(v.length);for(let L=0;L<v.length;L++)I[L]=v[L]/32768;const H=a.createBuffer(1,I.length,24e3);H.getChannelData(0).set(I);const z=a.createBufferSource();z.buffer=H,z.connect(a.destination);const W=d<a.currentTime?a.currentTime:d;R!==null&&!c.has(R)&&(c.set(R,W),P(),G()),z.start(W),d=W+H.duration,u++,z.onended=()=>{u--,ae()}}catch(S){console.error("[VirtualHumanEventAdapter] Failed to decode and play audio:",S)}},ee=b=>{switch(b){case"play":k(),f=!1,u=0,d=0,m=!1,a&&a.state==="suspended"&&a.resume();break;case"resume":m=!1,a&&a.state==="suspended"&&a.resume(),P(),G();break;case"pause":m=!0,a&&a.state==="running"&&a.suspend();break;case"stop":k(),m=!1,a&&(a.close(),a=null),d=0,f=!1,u=0;break;case"tts_complete":f=!0,ae();break;default:console.warn(`[VirtualHumanEventAdapter] Unknown control action: ${b}`)}},M=()=>{i.value&&i.value.close();try{const b=new URL(r.wsUrl);b.searchParams.append("sessionId",r.screenClientId+"-event"),i.value=new WebSocket(b.toString()),i.value.onopen=()=>{o.value=!0,s("connected"),console.log(`[VirtualHumanEventAdapter] Connected to ${r.wsUrl} for session ${r.screenClientId}-event`)},i.value.onmessage=R=>{try{const S=JSON.parse(R.data);$(S)}catch(S){console.error("[VirtualHumanEventAdapter] Failed to parse message:",R.data,S)}},i.value.onerror=R=>{console.error("[VirtualHumanEventAdapter] WebSocket error:",R),s("error",R)},i.value.onclose=()=>{o.value=!1,console.log("[VirtualHumanEventAdapter] WebSocket disconnected")}}catch(b){console.error("[VirtualHumanEventAdapter] Failed to initialize WebSocket:",b),s("error",b)}},$=b=>{const{type:R,payload:S,action:_}=b;switch(R){case"audio":const V=(S==null?void 0:S.data)||b.data;if(V){const v=T((S==null?void 0:S.index)??b.index);we(V,v)}break;case"send_event":if(b.event){console.log("adapter send_event:",b);const v=T(b.index);if(v===null){s("eventNotifaction",b);break}w.set(v,b),P(),G()}break;case"control":_&&(console.log("adapter control:",_),s("controlEvent",_),ee(_));break;case"end":console.log("adapter end:",S),s("end",S);break;case"pause":console.log("adapter pause:",S),s("pause",S);break;default:console.warn(`[VirtualHumanEventAdapter] Unknown message type: ${R}`)}};return g.watch(()=>r.screenClientId,()=>{r.screenClientId&&r.wsUrl&&M()}),g.watch(()=>r.wsUrl,()=>{r.screenClientId&&r.wsUrl&&M()}),g.onMounted(()=>{r.screenClientId&&r.wsUrl&&M()}),g.onUnmounted(()=>{i.value&&i.value.close(),a&&a.close()}),(b,R)=>g.renderSlot(b.$slots,"default")}}),Xn={install:e=>{e.component("VirtualHumanPersona",Fe),e.component("VirtualHumanEventAdapter",wt)}};q.VirtualHumanEventAdapter=wt,q.VirtualHumanPersona=Fe,q.default=Xn,Object.defineProperties(q,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "virtual-human-cf",
3
- "version": "1.2.0",
3
+ "version": "1.4.0",
4
4
  "description": "Vue3 Digital Human Component Package by cf ",
5
5
  "main": "dist/virtual-human-cf.umd.js",
6
6
  "module": "dist/virtual-human-cf.es.js",
@@ -34,5 +34,9 @@
34
34
  "component"
35
35
  ],
36
36
  "author": "cuihan",
37
- "license": "MIT"
37
+ "license": "MIT",
38
+ "dependencies": {
39
+ "axios": "^1.14.0",
40
+ "path": "^0.12.7"
41
+ }
38
42
  }
@@ -0,0 +1,22 @@
1
+ import axios from 'axios';
2
+
3
+ const request = axios.create({
4
+ baseURL: 'http://t1.lingganai.cyou:90', // Assuming backend runs on 8080
5
+ timeout: 10000,
6
+ });
7
+
8
+ request.interceptors.response.use(
9
+ (response) => {
10
+ const res = response.data;
11
+ if (res.code === 200) {
12
+ return res.data;
13
+ } else {
14
+ return Promise.reject(new Error(res.message || 'Error'));
15
+ }
16
+ },
17
+ (error) => {
18
+ return Promise.reject(error);
19
+ }
20
+ );
21
+
22
+ export default request;
@@ -0,0 +1,36 @@
1
+ import request from './request';
2
+
3
+ export interface ScreenConfig {
4
+ id?: number;
5
+ name: string;
6
+ screenClientId: string;
7
+ createTime?: string;
8
+ updateTime?: string;
9
+ }
10
+
11
+ export const getScreenList = () => {
12
+ return request.get<any, ScreenConfig[]>('/api/screen-configs');
13
+ };
14
+
15
+ export const getScreenById = (id: number) => {
16
+ return request.get<any, ScreenConfig>(`/api/screen-configs/${id}`);
17
+ };
18
+
19
+ export const createScreen = (data: ScreenConfig) => {
20
+ return request.post<any, boolean>('/api/screen-configs', data);
21
+ };
22
+
23
+ export const updateScreen = (id: number, data: ScreenConfig) => {
24
+ return request.put<any, boolean>(`/api/screen-configs/${id}`, data);
25
+ };
26
+
27
+ export const deleteScreen = (id: number) => {
28
+ return request.delete<any, boolean>(`/api/screen-configs/${id}`);
29
+ };
30
+
31
+ export const controlScreen = (screenClientId: string, action: 'play' | 'pause' | 'stop' | 'resume') => {
32
+ return request.post<any, boolean>('/api/screen/control', {
33
+ screenClientId,
34
+ action
35
+ });
36
+ };
@@ -4,6 +4,7 @@
4
4
 
5
5
  <script setup lang="ts">
6
6
  import { ref, watch, onMounted, onUnmounted } from 'vue';
7
+ import { controlScreen as controlScreenApi } from '@/api/screen';
7
8
 
8
9
  const props = defineProps({
9
10
  // 屏幕客户端ID
@@ -29,6 +30,90 @@ let nextStartTime = 0;
29
30
  let isTtsComplete = false;
30
31
  let activeSources = 0;
31
32
  let isIntentionallyPaused = false;
33
+ const pendingEventByIndex = new Map<number, any>();
34
+ const firedEventIndexSet = new Set<number>();
35
+ const plannedStartTimeByIndex = new Map<number, number>();
36
+ let eventSchedulerTimer: number | null = null;
37
+
38
+ // 定义控制方法
39
+ const pause = () => {
40
+ if (!isConnected.value) return Promise.reject(false);
41
+ return controlScreenApi(props.screenClientId, 'pause').then(() => Promise.resolve(true)).catch(() => Promise.reject(false));
42
+ };
43
+
44
+ const resume = () => {
45
+ if (!isConnected.value) return Promise.reject(false);
46
+ return controlScreenApi(props.screenClientId, 'resume').then(() => Promise.resolve(true)).catch(() => Promise.reject(false));
47
+ };
48
+
49
+ const stop = () => {
50
+ if (!isConnected.value) return Promise.reject(false);
51
+ return controlScreenApi(props.screenClientId, 'stop').then(() => Promise.resolve(true)).catch(() => Promise.reject(false));
52
+ };
53
+
54
+ // 暴露方法给父组件
55
+ defineExpose({
56
+ pause,
57
+ resume,
58
+ stop
59
+ });
60
+
61
+ const normalizeIndex = (value: unknown): number | null => {
62
+ if (typeof value === 'number' && Number.isFinite(value)) return value;
63
+ if (typeof value === 'string' && value.trim() !== '') {
64
+ const n = Number(value);
65
+ if (Number.isFinite(n)) return n;
66
+ }
67
+ return null;
68
+ };
69
+
70
+ const stopEventScheduler = () => {
71
+ if (eventSchedulerTimer !== null) {
72
+ window.clearInterval(eventSchedulerTimer);
73
+ eventSchedulerTimer = null;
74
+ }
75
+ };
76
+
77
+ const clearEventState = () => {
78
+ stopEventScheduler();
79
+ pendingEventByIndex.clear();
80
+ firedEventIndexSet.clear();
81
+ plannedStartTimeByIndex.clear();
82
+ };
83
+
84
+ const hasSchedulableEvent = () => {
85
+ for (const [index] of pendingEventByIndex) {
86
+ if (!firedEventIndexSet.has(index) && plannedStartTimeByIndex.has(index)) return true;
87
+ }
88
+ return false;
89
+ };
90
+
91
+ const tickEventScheduler = () => {
92
+ if (!audioContext || audioContext.state !== 'running') return;
93
+
94
+ for (const [index, plannedStartTime] of plannedStartTimeByIndex) {
95
+ if (firedEventIndexSet.has(index)) continue;
96
+ const pendingEvent = pendingEventByIndex.get(index);
97
+ if (!pendingEvent) continue;
98
+
99
+ if (audioContext.currentTime + 0.005 >= plannedStartTime) {
100
+ firedEventIndexSet.add(index);
101
+ pendingEventByIndex.delete(index);
102
+ emit('eventNotifaction', pendingEvent);
103
+ }
104
+ }
105
+
106
+ if (!hasSchedulableEvent()) stopEventScheduler();
107
+ };
108
+
109
+ const ensureEventScheduler = () => {
110
+ if (eventSchedulerTimer !== null) return;
111
+ if (!hasSchedulableEvent()) return;
112
+
113
+ eventSchedulerTimer = window.setInterval(() => {
114
+ tickEventScheduler();
115
+ }, 30);
116
+ };
32
117
 
33
118
  const initAudioContext = () => {
34
119
  if (!audioContext) {
@@ -48,7 +133,7 @@ const checkPlayComplete = () => {
48
133
  }
49
134
  };
50
135
 
51
- const handleAudioMessage = (base64Data: string) => {
136
+ const handleAudioMessage = (base64Data: string, index: number | null) => {
52
137
  initAudioContext();
53
138
  if (!audioContext) return;
54
139
 
@@ -75,11 +160,15 @@ const handleAudioMessage = (base64Data: string) => {
75
160
  source.connect(audioContext.destination);
76
161
 
77
162
  // Keep track of the start time for seamless playback
78
- if (nextStartTime < audioContext.currentTime) {
79
- nextStartTime = audioContext.currentTime;
163
+ const startAt = nextStartTime < audioContext.currentTime ? audioContext.currentTime : nextStartTime;
164
+ if (index !== null && !plannedStartTimeByIndex.has(index)) {
165
+ plannedStartTimeByIndex.set(index, startAt);
166
+ tickEventScheduler();
167
+ ensureEventScheduler();
80
168
  }
81
- source.start(nextStartTime);
82
- nextStartTime += audioBuffer.duration;
169
+
170
+ source.start(startAt);
171
+ nextStartTime = startAt + audioBuffer.duration;
83
172
 
84
173
  activeSources++;
85
174
  source.onended = () => {
@@ -94,6 +183,7 @@ const handleAudioMessage = (base64Data: string) => {
94
183
  const handleControlMessage = (action: string) => {
95
184
  switch (action) {
96
185
  case 'play':
186
+ clearEventState();
97
187
  isTtsComplete = false;
98
188
  activeSources = 0;
99
189
  nextStartTime = 0;
@@ -107,6 +197,8 @@ const handleControlMessage = (action: string) => {
107
197
  if (audioContext && audioContext.state === 'suspended') {
108
198
  audioContext.resume();
109
199
  }
200
+ tickEventScheduler();
201
+ ensureEventScheduler();
110
202
  break;
111
203
  case 'pause':
112
204
  isIntentionallyPaused = true;
@@ -115,6 +207,7 @@ const handleControlMessage = (action: string) => {
115
207
  }
116
208
  break;
117
209
  case 'stop':
210
+ clearEventState();
118
211
  isIntentionallyPaused = false;
119
212
  if (audioContext) {
120
213
  audioContext.close();
@@ -181,14 +274,23 @@ const handleMessage = (msg: any) => {
181
274
  case 'audio':
182
275
  const base64Data = payload?.data || msg.data;
183
276
  if (base64Data) {
184
- handleAudioMessage(base64Data);
277
+ const index = normalizeIndex(payload?.index ?? msg.index);
278
+ handleAudioMessage(base64Data, index);
185
279
  }
186
280
  break;
187
281
  // 接收事件通知
188
282
  case 'send_event':
189
283
  if (msg.event) {
190
284
  console.log("adapter send_event:",msg)
191
- emit('eventNotifaction', msg);
285
+ const index = normalizeIndex(msg.index);
286
+ if (index === null) {
287
+ emit('eventNotifaction', msg);
288
+ break;
289
+ }
290
+
291
+ pendingEventByIndex.set(index, msg);
292
+ tickEventScheduler();
293
+ ensureEventScheduler();
192
294
  }
193
295
  break;
194
296
  // 控制指令接口
@@ -130,6 +130,9 @@ const handleMessage = (msg: any) => {
130
130
  emit('update:isPlaying', true);
131
131
  emit('update:visible', true);
132
132
  } else if (action === 'pause') {
133
+ if (videoRef.value) {
134
+ videoRef.value.pause();
135
+ }
133
136
  emit('update:isPlaying', false);
134
137
  // 暂停时不隐藏视频
135
138
  emit('update:visible', true);
package/tsconfig.json CHANGED
@@ -14,8 +14,12 @@
14
14
  "noEmit": true,
15
15
  "declaration": true,
16
16
  "declarationDir": "dist",
17
- "outDir": "dist"
17
+ "outDir": "dist",
18
+ "baseUrl": ".",
19
+ "paths": {
20
+ "@/*": ["./src/*"]
21
+ }
18
22
  },
19
23
  "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
20
24
  "references": [{ "path": "./tsconfig.node.json" }]
21
- }
25
+ }
package/vite.config.ts CHANGED
@@ -11,6 +11,11 @@ export default defineConfig({
11
11
  include: ['src/**/*.ts', 'src/**/*.vue'],
12
12
  }),
13
13
  ],
14
+ resolve: {
15
+ alias: {
16
+ '@': resolve(__dirname, './src')
17
+ }
18
+ },
14
19
  build: {
15
20
  lib: {
16
21
  entry: resolve(__dirname, 'src/index.ts'),
@@ -31,4 +36,4 @@ export default defineConfig({
31
36
  },
32
37
  },
33
38
  },
34
- });
39
+ });