@degreesign/chat 1.1.0 → 1.2.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,16 +1,28 @@
1
- import type { EngineChunk, EngineMessage, LitertMessage, LitertSettings, LitertSettingsParams, LlmEngine, StartLlmParams, StreamLitertParams } from '../types';
1
+ import { loadLitert } from './litertLoader';
2
+ import type { EngineChunk, EngineMessage, GpuDevice, GpuThrottleParams, LitertMessage, LitertSettings, LitertSettingsParams, LlmEngine, StartLlmParams, StreamLitertParams } from '../types';
2
3
  declare const
3
- /** Smallest Gemma 4 vision budget in tokens */
4
- visionTokens = 70;
5
- /** Fetch one model file into the cache, once per URL */
4
+ /** Smallest Gemma 4 vision budget */
5
+ visionTokens = 70,
6
+ /** GPU busy share of time */
7
+ gpuShare = 0.7,
8
+ /** Most rest per readback */
9
+ maxRestMs = 40;
10
+ declare const
11
+ /** Rest owed for busy interval */
12
+ restFor: (busyMs: number) => number;
13
+ /** WebGPU device resting after readback */
14
+ declare const throttledDevice: ({ device, pace, }: GpuThrottleParams) => GpuDevice;
15
+ /** Drop device and wasm module */
16
+ declare const releaseDevice: (mod: Awaited<ReturnType<typeof loadLitert>>) => void;
17
+ /** Cache one file per URL */
6
18
  declare const cacheModel: (url: string, cache: Cache, signal: AbortSignal | undefined, onProgress: StartLlmParams[`onProgress`]) => Promise<void>;
7
- /** Map built messages to LiteRT turns */
19
+ /** Map messages to LiteRT turns */
8
20
  declare const toLitertMessages: (messages: EngineMessage[], keepMedia?: boolean) => Promise<LitertMessage[]>;
9
- /** Whether the live conversation already holds the incoming history */
21
+ /** Whether conversation holds incoming history */
10
22
  declare const continuesHistory: (sent: EngineMessage[], history: EngineMessage[]) => boolean;
11
- /** Stream one LiteRT reply as engine chunks */
23
+ /** Stream LiteRT reply as chunks */
12
24
  declare const streamLitert: ({ engine, mod, params, messages, session, }: StreamLitertParams) => AsyncGenerator<EngineChunk>;
13
- /** Build one engine settings object with the small vision budget */
14
- declare const litertSettings: ({ model, limits, source, mod, }: LitertSettingsParams) => LitertSettings;
25
+ /** Engine settings with vision budget */
26
+ declare const litertSettings: ({ model, limits, contextSize, source, mod, }: LitertSettingsParams) => LitertSettings;
15
27
  declare const litertEngine: LlmEngine;
16
- export { cacheModel, continuesHistory, litertEngine, litertSettings, streamLitert, toLitertMessages, visionTokens, };
28
+ export { cacheModel, continuesHistory, gpuShare, litertEngine, litertSettings, maxRestMs, releaseDevice, restFor, streamLitert, throttledDevice, toLitertMessages, visionTokens, };
@@ -1,11 +1,11 @@
1
1
  import type { ModelStore, ResumePlan, StoredFilePart, StoredPart } from '../types';
2
2
  declare const
3
- /** Contiguous parts from offset zero, stopping at the first gap */
3
+ /** Contiguous parts until first gap */
4
4
  chainParts: (parts: StoredFilePart[]) => StoredFilePart[],
5
- /** Where one response continues the parts, undefined restarts them */
5
+ /** Where response continues parts */
6
6
  resumePlan: (response: Response, part: StoredPart) => ResumePlan | undefined,
7
- /** Whether a failed store write means this host cannot use a file store */
7
+ /** Whether store failure disables storage */
8
8
  isStoreError: (error: unknown) => boolean;
9
- /** Create the resumable file store of one engine */
9
+ /** Create engine resumable file store */
10
10
  declare const createModelStore: (dirName: string) => ModelStore;
11
11
  export { chainParts, createModelStore, isStoreError, resumePlan, };
@@ -1,3 +1,3 @@
1
- /** Logical cores minus a fifth, one kept free for the page */
1
+ /** Reserve one fifth for page */
2
2
  declare const heuristicThreads: (cores: number) => number;
3
3
  export { heuristicThreads };
@@ -8,19 +8,19 @@ declare const visionLimits: (model: ChatModel) => {
8
8
  image_max_tokens?: undefined;
9
9
  };
10
10
  declare const
11
- /** Every CPU file of one model, its name and remote URL */
11
+ /** CPU file names and URLs */
12
12
  cpuFiles: (model: ChatModel) => Array<{
13
13
  name: string;
14
14
  url: string;
15
15
  }>,
16
- /** Every CPU file as a Blob, from the store or a resumable download */
16
+ /** CPU files as stored blobs */
17
17
  storedBlobs: ({ model, signal, onProgress, }: {
18
18
  model: ChatModel;
19
19
  signal?: AbortSignal;
20
20
  onProgress: StartLlmParams[`onProgress`];
21
21
  }) => Promise<Blob[] | undefined>,
22
- /** Map built messages to wllama turns */
22
+ /** Map messages to wllama turns */
23
23
  toWllamaMessages: (messages: EngineMessage[]) => Promise<WllamaMessage[]>,
24
- /** Start the CPU runtime, the unified engine entry */
24
+ /** Start CPU runtime engine entry */
25
25
  startLLM: ({ model, limits, onProgress, signal, logging, assets: overrides, }: StartLlmParams) => Promise<LlmRuntime>, wllamaEngine: LlmEngine;
26
26
  export { cpuFiles, startLLM, storedBlobs, toWllamaMessages, visionLimits, wllamaEngine, };
package/dist/enums.d.ts CHANGED
@@ -1,10 +1,10 @@
1
- /** Who a chat message is from */
1
+ /** Author of a chat message */
2
2
  declare enum LlmRole {
3
3
  system = "system",
4
4
  user = "user",
5
5
  assistant = "assistant"
6
6
  }
7
- /** Assistant availability derived from the engine */
7
+ /** Assistant availability from engine */
8
8
  declare enum ChatStatus {
9
9
  online = 0,
10
10
  away = 1,
@@ -18,18 +18,18 @@ declare enum LlmStatus {
18
18
  error = 3,
19
19
  unsupported = 4
20
20
  }
21
- /** Which engine runs the model on this device */
21
+ /** Engine running the model */
22
22
  declare enum LlmBackend {
23
23
  cpu = "cpu",
24
24
  gpu = "gpu",
25
25
  none = "none"
26
26
  }
27
- /** Download or load-into-memory phase of a model load */
27
+ /** Download or load phase */
28
28
  declare enum LlmPhase {
29
29
  download = "download",
30
30
  load = "load"
31
31
  }
32
- /** Catalog ids of the on-device models */
32
+ /** Catalog ids of on-device models */
33
33
  declare enum ChatModelId {
34
34
  qwen3_vl_2b = "qwen3-vl-2b",
35
35
  qwen3_vl_2b_instruct = "qwen3-vl-2b-instruct",
@@ -43,7 +43,7 @@ declare enum BuiltinTool {
43
43
  calculate = "calculate",
44
44
  currency = "currency"
45
45
  }
46
- /** Search provider behind the websearch tool */
46
+ /** Provider behind the websearch tool */
47
47
  declare enum WebSearchProvider {
48
48
  wikipedia = "wikipedia",
49
49
  duckduckgo = "duckduckgo"
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { clearModelCache, createChat, preloadModel } from './chat';
2
- export { describeImages, describeModelId, describeTranslated } from './describe';
2
+ export { describeImages, describeModelId, describeTranslated, imageReplyTokens } from './describe';
3
3
  export { builtinTools, calculateTool, currencyTool, webSearchTool, } from './tools';
4
4
  export { LlmRole, ChatStatus, LlmStatus, LlmBackend, LlmPhase, ChatModelId, BuiltinTool, WebSearchProvider, } from './enums';
5
5
  export type { ChatMessage, LlmLimits, ChatStatusSnapshot, ChatInput, ChatPreloadInput, CancelChat, DescribeImagesInput, DescribeTranslatedInput, ImageDescription, WllamaAssets, ChatTool, ChatToolCall, ChatToolResult, ChatToolSchema, ChatToolValue, WebSearchConfig, WebSearchResult, } from './types';
package/dist/log.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- /** Write one package log line when logging is on */
1
+ /** Write log line when enabled */
2
2
  declare const log: (logging: boolean | undefined, ...args: unknown[]) => void;
3
3
  export { log };
package/dist/models.d.ts CHANGED
@@ -1,26 +1,28 @@
1
1
  import { ChatModelId } from './enums';
2
2
  import type { ChatModel, MobileNavigator } from './types';
3
3
  declare const llmModels: ChatModel[],
4
- /** Context window requested from the CPU engine, a 32k KV cache needs 3.5 GB */
4
+ /** CPU context window, 8k tokens */
5
5
  cpuContextWindow = 8192, // max 262_400
6
- /** CPU window on a phone, the smaller cache keeps the tab alive */
6
+ /** Phone CPU window, 4096 tokens */
7
7
  mobileCpuContextWindow = 4096, // max 32_768
8
- /** Context window requested from the GPU engine, the wasm heap holds the model */
9
- litertContextWindow = 4096, // max 32_768
10
- /** Whether this client is a phone or tablet */
8
+ /** GPU context window, 32k tokens */
9
+ litertContextWindow = 32768, // max 32_768
10
+ /** Phone GPU window, 16k tokens */
11
+ mobileLitertContextWindow = 16384, // max 32_768
12
+ /** Whether this client is mobile */
11
13
  mobileDevice: (nav?: MobileNavigator) => boolean,
12
- /** Build of a Gemma request that this device loads */
14
+ /** Gemma build this device loads */
13
15
  deviceModelId: (id?: ChatModelId, mobile?: boolean) => ChatModelId | undefined,
14
- /** Look up a catalog entry by id */
16
+ /** Find catalog entry by id */
15
17
  findLlmModel: (id?: string) => ChatModel | undefined,
16
- /** Whether this browser provides a WebGPU adapter */
18
+ /** Whether browser has WebGPU adapter */
17
19
  gpuAdapter: () => Promise<boolean>,
18
- /** Default model, the GPU one when a WebGPU adapter exists */
20
+ /** Default model, GPU when available */
19
21
  defaultLlmModel: () => Promise<ChatModelId | undefined>,
20
- /** Resolve the requested model or the default of this device */
22
+ /** Resolve requested model or default */
21
23
  resolveLlmModel: (id?: ChatModelId) => Promise<ChatModel | undefined>,
22
24
  /** Whether a model accepts images */
23
25
  supportsImages: (model: ChatModel) => boolean,
24
26
  /** Whether a model accepts audio */
25
27
  supportsAudio: (model: ChatModel) => boolean;
26
- export { llmModels, cpuContextWindow, mobileCpuContextWindow, litertContextWindow, mobileDevice, deviceModelId, findLlmModel, gpuAdapter, defaultLlmModel, resolveLlmModel, supportsImages, supportsAudio, };
28
+ export { llmModels, cpuContextWindow, mobileCpuContextWindow, litertContextWindow, mobileLitertContextWindow, mobileDevice, deviceModelId, findLlmModel, gpuAdapter, defaultLlmModel, resolveLlmModel, supportsImages, supportsAudio, };
@@ -1,2 +1,2 @@
1
1
  /*! For license information please see chat.node.min.js.LICENSE.txt */
2
- (()=>{var e={69(e,t){(()=>{"use strict";var e={125:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.addZ=t.tN=t.monNm=t.tmUTC=t.tmAP=t.moYrDt=t.shortDt=t.fullLong=t.fullDate=t.fullDt=t.invDt=t.dayRes=t.timeStandard=t.dateStandard=t.seoDt=t.thisYear=t.oneMon=t.oneMin=t.oneHr=t.oneDay=t.oneSec=void 0;const r=()=>Date.now(),n=["January","February","March","April","May","June","July","August","September","October","November","December"],o=["JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC"],a=["st","nd","rd","th"],i=e=>0==+e?"00":+e<10&&+e>=1?`0${e}`:`${e}`,s=e=>{const t=new Date(e);return`${t.getUTCFullYear()}-${i(t.getUTCMonth()+1)}-${i(t.getUTCDate())}`},c=e=>i(e.getUTCHours())+`:${i(e.getUTCMinutes())}`+`:${i(e.getUTCSeconds())}`;t.tN=r,t.monNm=n,t.dayRes=90,t.oneSec=1e3,t.oneMin=6e4,t.oneHr=36e5,t.oneDay=864e5,t.oneMon=27e8,t.addZ=i,t.tmUTC=e=>{const t=new Date(e);return i(t.getUTCHours())+`:${i(t.getUTCMinutes())} UTC`},t.tmAP=e=>{const t=new Date(e),r=t.getHours();return i(r>12?r-12:r)+`:${i(t.getMinutes())}`+(r>=12?"pm":"am")},t.shortDt=e=>{const t=new Date(e);return`${t.getDate()} ${o[t.getMonth()]}`},t.moYrDt=e=>{const t=new Date(e);return`${o[t.getMonth()]} ${t.getFullYear()}`},t.fullDt=e=>{const t=new Date(e);return`${t.getDate()} ${o[t.getMonth()]} ${t.getFullYear()}`},t.fullDate=e=>{const t=new Date(e);return`${t.getDate()} ${n[t.getMonth()]} ${t.getFullYear()}`},t.fullLong=e=>`${(e=>{const t=new Date(e),r=t.getDate();return r+a[r<5?r-1:r>4&&r<21?3:r>20&&r<25?r-21:r>24&&r<31?3:0]+` of ${n[t.getMonth()]}`})(e)} ${new Date(e).getFullYear()}`,t.thisYear=e=>(e?new Date(e):new Date)?.getUTCFullYear(),t.dateStandard=s,t.timeStandard=c,t.seoDt=e=>{!e&&(e=r());const t=new Date(e);return`${s(t)}T${c(t)}Z`},t.invDt=e=>{const t=new Date(e);return`${t.getUTCFullYear()}`.split("20")[1]+i(t.getUTCMonth()+1)+i(t.getUTCDate())+`${e}`.slice(10)}},240:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.idRandLong=t.idRandShort=t.idShuffle=void 0;const r=["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","@",".","_","0","1","2","3","4","5","6","7","8","9"];t.idShuffle=async({data:e,password:t})=>4==t?.length?(({data:e,password:t})=>{try{const n=(e,t)=>r.includes(e.toLowerCase())?r[(r.indexOf(e.toLowerCase())+Math.pow(t,3))%r.length]:e;return[...e].map(e=>n(e,Number(t))).join("")}catch{return""}})({data:e,password:t}):await(async({data:e,password:t})=>{if(!e||!t)return"";try{crypto.subtle;const r=new TextEncoder,n=r.encode(e),o=r.encode(t),a=await crypto.subtle.digest("SHA-256",o),i=new Uint8Array(a),s=i.slice(0,32),c=i.slice(0,12),l=await crypto.subtle.importKey("raw",s,{name:"AES-GCM"},!1,["encrypt"]),u=await crypto.subtle.encrypt({name:"AES-GCM",iv:c},l,n);return btoa(String.fromCharCode(...new Uint8Array(u))).replace(/\+/g,"a").replace(/\//g,"b").replace(/=/g,"c").toLowerCase()}catch{return""}})({data:e,password:t}),t.idRandShort=(e=10)=>{try{return crypto.randomUUID()?.replaceAll("-","")?.slice(0,e)}catch(e){return console.log("idRandShort failed",e),""}},t.idRandLong=(e=10)=>{try{const t="abcdefghijklmnopqrstuvwxyz",r=new Uint8Array(e);return crypto.getRandomValues(r),Array.from(r).map(e=>t[e%26]).join("")}catch(e){return console.log("idRandLong failed",e),""}}},246:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.cacheCheck=t.delayCode=void 0;const n=r(125);t.delayCode=async(e=0)=>await new Promise(t=>setTimeout(t,e)),t.cacheCheck=({analysisCacheLimit:e,lastUpdated:t,forceRefresh:r})=>{const o=Date.now();if(t&&(!r&&t>o-e||r&&t>o-n.oneDay))return!0}},792:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.isEven=t.pNum=t.sharpeRatio=t.priceVariations=t.nTxtAr=t.zNum=t.addCom=t.adjNum=t.rNum=void 0;const r=[1,.1,.01,.001,1e-4,1e-5,1e-6,1e-7,1e-8,1e-9,1e-10,1e-11,1e-12,1e-13,1e-14,1e-15,1e-16,1e-17,1e-18,1e-19],n=(e,t=6)=>{const n=+e,o=n?Math.abs(n):0,a=o>1&&t?t-`${Math.round(o)}`.length:0;return n?(n<0?-1:1)*(Number.isInteger(o)||o<1e-16?o:o>1e5?Math.round(o):o>1?Number(o.toFixed(a<0?0:a)):((e,t)=>{let n=0;for(const o of r){if(o<e)return Number(e.toFixed(t+n-1));n++}return e})(o,t)):e},o=(e,t)=>{const r=(n(e,t)+"").split(".");return r[0]=r[0].replace(/\B(?=(\d{3})+(?!\d))/g,","),r.join(".")},a=(e,t=3)=>{const r=Number(e);if(!e||!r)return e+"";const a=Math.abs(r);return(r<0?"-":"")+(a>1e9?o(a/1e9,t)+"b":a>1e6?o(a/1e6,t)+"m":a<1e-6&&a>1e-16?(1+n(a,t)+"").replace(/1./g,"0."):o(a,t))};t.nTxtAr=["zero","one","two","three","four","five","six","seven","eight","nine","ten"],t.rNum=n,t.addCom=o,t.adjNum=a,t.zNum=e=>{const t=Number(e);let r=t?Math.abs(t):0,n=1e10;for(;n>1;)r>n&&(r=Math.round(r/(n/10))*(n/10)),n/=10;return t?(t<0?"-":"")+a(r,2):e},t.pNum=e=>+e||0==+e?Math.round(1e6*+e)/1e6:null,t.priceVariations=e=>{try{let t=0;const r=[...e].sort((e,t)=>e[0]-t[0]),n=e.reduce((e,[,t])=>e+t,0),o=r.find(([,e])=>(t+=e,t>=n/2))[0];return e.filter(([e])=>Math.abs(e-o)/o<.05).map(([e])=>e)}catch{return[]}},t.sharpeRatio=({assetPrices:e,minExpectedReturn:t=.05})=>{if(!e?.length||e?.length<2)return 0;const r=e.slice(1).map((t,r)=>(t-e[r])/e[r]),n=r.reduce((e,t)=>e+t,0)/r.length,o=Math.sqrt(r.reduce((e,t)=>e+Math.pow(t-n,2),0)/r.length);return(n-t)/o},t.isEven=e=>e%2==0},794:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.restoreObj=t.restoreObjStr=t.storeObj=t.storeObjStr=t.objNestValueCount=t.objLen=t.objSortSimple=t.objSort=void 0;const n=r(125),o=e=>{try{return Object.keys(e||{})?.length||0}catch(e){return console.log(e),0}},a=e=>{try{return e?.replace(/"/g,"'")}catch(e){return console.log((0,n.tN)(),"storeObjStr failed",e),""}},i=e=>{try{return e?.toString()?.replace(/'/g,'"')}catch(e){console.log((0,n.tN)(),"restoreObjStr failed",e)}};t.objLen=o,t.objNestValueCount=e=>{let t=0;if(o(e))for(const r in e)t+=o(e[r])?1:0;return t},t.objSort=(e={},t,r=-1)=>Object.fromEntries(Object.entries(e).sort(([,e],[,n])=>null===e[t]||void 0===e[t]?1:null===n[t]||void 0===n[t]?-1:e[t]>n[t]?1*r:-1*r)),t.objSortSimple=(e={},t=-1)=>Object.fromEntries(Object.entries(e).sort(([,e],[,r])=>null==e?1:null==r?-1:e>r?1*t:-1*t)),t.storeObjStr=a,t.storeObj=e=>{try{return a(JSON.stringify(e))}catch(e){return console.log((0,n.tN)(),"storeObj failed",e),""}},t.restoreObjStr=i,t.restoreObj=e=>{try{if(!e)return;const t=i(e);return t?JSON.parse(t):void 0}catch(e){console.log((0,n.tN)(),"restoreObj failed",e)}}},830:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.phaseDifference=t.compareArrays=t.squeezeArray=t.forecastNextTotal=t.forecastNext=t.getMax=t.getMean=t.getSum=t.maxVl=t.minVl=t.sumArr=void 0;const r=e=>{try{return e?.length?e.reduce((e,t)=>e+t):0}catch(e){return console.log("sumArr failed",e),0}},n=e=>{try{return e?.length?e.reduce((e,t)=>e+t,0):0}catch(e){return console.log("getSum failed",e),0}},o=e=>{try{return e?.length?n(e)/e.length:0}catch(e){return console.log("getMean failed",e),0}},a=e=>{try{return e?.length?Math.max(...e):0}catch(e){return console.log("getMax failed",e),0}},i=e=>{try{if(!e?.length)return 0;const t=[...e].sort((e,t)=>e-t),r=Math.floor(t.length/2);return t.length%2?t[r]:(t[r-1]+t[r])/2}catch(e){return console.log("median failed",e),0}},s=({currentPeriod:e,steps:t=1})=>{try{const r=(Array.isArray(e)?e:[]).filter(Number.isFinite);if(!r.length||t<=0)return[];if(r.length<2){const e=Math.max(0,o(r));return Array.from({length:t},()=>e)}const n=r.length,{slope:s,intercept:c}=(e=>{try{const t=e.length,r=[];for(let n=0;n<t-1;n++)for(let o=n+1;o<t;o++)r.push((e[o]-e[n])/(o-n));const n=i(r);return{slope:n,intercept:i(e.map((e,t)=>e-n*t))}}catch(e){return console.log("theilSen failed",e),{slope:0,intercept:0}}})(r),l=c+s*(n-1),u=a(r),d=u>0?3*u:1/0;return Array.from({length:t},(e,t)=>{const r=t+1,o=l+s*n*Math.log1p(r/n);return Math.max(0,Math.min(o,d))})}catch(e){return console.log("forecastNext failed",e),[]}};t.sumArr=r,t.maxVl=(e,t)=>{let r=0;for(let n=0;n<e.length;n++){const o=e[n];o[t]>r&&(r=o[t])}return r},t.minVl=(e,t)=>{let r=0;for(let n=0;n<e.length;n++){const o=e[n];o[t]<r&&(r=o[t])}return r},t.getSum=n,t.getMean=o,t.getMax=a,t.forecastNext=s,t.forecastNextTotal=e=>{try{const t=s({currentPeriod:e,steps:e?.length});return n(t)}catch(e){return console.log("forecastNextTotal failed",e),0}},t.squeezeArray=({arr:e,targetLength:t})=>{try{if(!e||0===e.length||t<=0)throw new Error("Invalid input");const n=Math.ceil(e.length/t);return Array.from({length:t},(t,o)=>{const a=o*n,i=Math.min(a+n,e.length),s=e.slice(a,i);return r(s)}).slice(0,t)}catch(e){return console.log("squeezeArray failed",e),[]}},t.compareArrays=({arrays:e})=>{try{const t=[...e],n=Math.min(...t.map(e=>e.length));for(let e=0;e<t.length;e++)t.splice(n);const o=t.map(e=>r(e)),a=[],i=Math.min(...o),s=o.indexOf(i),c=i/Math.max(...o);for(let e=0;e<t.length;e++){const r=t[e];if(a[e]=[],e==s)a[e]=r;else for(let t=0;t<r.length;t++)a[e].push(c*r[t])}return a}catch(t){return console.log("compareArrays failed",t),e}},t.phaseDifference=({array1:e,array2:t})=>{try{let r=e.length,n=e.reduce((e,t)=>e+t)/r,o=t.reduce((e,t)=>e+t)/r,a=e.map(e=>e-n),i=t.map(e=>e-o),s=Math.floor(r/2),c=-1/0,l=0;for(let e=-s;e<=s;e++){let t=0,n=0,o=0,s=0;for(let c=0;c<r;c++){let l=c+e;l>=0&&l<r&&(t+=a[c]*i[l],n+=a[c]*a[c],o+=i[l]*i[l],s++)}if(n>0&&o>0&&s>=.8*r){let r=t/Math.sqrt(n*o);r>c&&(c=r,l=e)}}return l}catch(e){return console.log("phaseDifference failed",e),0}}}},r={};function n(t){var o=r[t];if(void 0!==o)return o.exports;var a=r[t]={exports:{}};return e[t](a,a.exports,n),a.exports}var o={};(()=>{var e=o;Object.defineProperty(e,"__esModule",{value:!0}),e.idShuffle=e.isEven=e.pNum=e.nTxtAr=e.zNum=e.addCom=e.adjNum=e.rNum=e.sharpeRatio=e.priceVariations=e.timeStandard=e.dateStandard=e.addZ=e.tN=e.monNm=e.tmUTC=e.tmAP=e.moYrDt=e.shortDt=e.fullLong=e.fullDate=e.fullDt=e.invDt=e.dayRes=e.thisYear=e.seoDt=e.oneMon=e.oneMin=e.oneHr=e.oneDay=e.oneSec=e.restoreObj=e.restoreObjStr=e.storeObj=e.storeObjStr=e.objSortSimple=e.objSort=e.objNestValueCount=e.objLen=e.phaseDifference=e.compareArrays=e.squeezeArray=e.forecastNextTotal=e.forecastNext=e.getMax=e.getMean=e.getSum=e.maxVl=e.minVl=e.sumArr=void 0,e.cacheCheck=e.delayCode=e.idRandLong=e.idRandShort=void 0;const t=n(246);Object.defineProperty(e,"cacheCheck",{enumerable:!0,get:function(){return t.cacheCheck}}),Object.defineProperty(e,"delayCode",{enumerable:!0,get:function(){return t.delayCode}});const r=n(830);Object.defineProperty(e,"sumArr",{enumerable:!0,get:function(){return r.sumArr}}),Object.defineProperty(e,"minVl",{enumerable:!0,get:function(){return r.minVl}}),Object.defineProperty(e,"maxVl",{enumerable:!0,get:function(){return r.maxVl}}),Object.defineProperty(e,"getMax",{enumerable:!0,get:function(){return r.getMax}}),Object.defineProperty(e,"getMean",{enumerable:!0,get:function(){return r.getMean}}),Object.defineProperty(e,"getSum",{enumerable:!0,get:function(){return r.getSum}}),Object.defineProperty(e,"forecastNext",{enumerable:!0,get:function(){return r.forecastNext}}),Object.defineProperty(e,"forecastNextTotal",{enumerable:!0,get:function(){return r.forecastNextTotal}}),Object.defineProperty(e,"squeezeArray",{enumerable:!0,get:function(){return r.squeezeArray}}),Object.defineProperty(e,"compareArrays",{enumerable:!0,get:function(){return r.compareArrays}}),Object.defineProperty(e,"phaseDifference",{enumerable:!0,get:function(){return r.phaseDifference}});const a=n(240);Object.defineProperty(e,"idRandLong",{enumerable:!0,get:function(){return a.idRandLong}}),Object.defineProperty(e,"idRandShort",{enumerable:!0,get:function(){return a.idRandShort}}),Object.defineProperty(e,"idShuffle",{enumerable:!0,get:function(){return a.idShuffle}});const i=n(792);Object.defineProperty(e,"addCom",{enumerable:!0,get:function(){return i.addCom}}),Object.defineProperty(e,"adjNum",{enumerable:!0,get:function(){return i.adjNum}}),Object.defineProperty(e,"priceVariations",{enumerable:!0,get:function(){return i.priceVariations}}),Object.defineProperty(e,"nTxtAr",{enumerable:!0,get:function(){return i.nTxtAr}}),Object.defineProperty(e,"rNum",{enumerable:!0,get:function(){return i.rNum}}),Object.defineProperty(e,"zNum",{enumerable:!0,get:function(){return i.zNum}}),Object.defineProperty(e,"sharpeRatio",{enumerable:!0,get:function(){return i.sharpeRatio}}),Object.defineProperty(e,"pNum",{enumerable:!0,get:function(){return i.pNum}}),Object.defineProperty(e,"isEven",{enumerable:!0,get:function(){return i.isEven}});const s=n(125);Object.defineProperty(e,"oneSec",{enumerable:!0,get:function(){return s.oneSec}}),Object.defineProperty(e,"oneDay",{enumerable:!0,get:function(){return s.oneDay}}),Object.defineProperty(e,"oneHr",{enumerable:!0,get:function(){return s.oneHr}}),Object.defineProperty(e,"oneMin",{enumerable:!0,get:function(){return s.oneMin}}),Object.defineProperty(e,"oneMon",{enumerable:!0,get:function(){return s.oneMon}}),Object.defineProperty(e,"seoDt",{enumerable:!0,get:function(){return s.seoDt}}),Object.defineProperty(e,"dayRes",{enumerable:!0,get:function(){return s.dayRes}}),Object.defineProperty(e,"invDt",{enumerable:!0,get:function(){return s.invDt}}),Object.defineProperty(e,"fullDt",{enumerable:!0,get:function(){return s.fullDt}}),Object.defineProperty(e,"fullDate",{enumerable:!0,get:function(){return s.fullDate}}),Object.defineProperty(e,"fullLong",{enumerable:!0,get:function(){return s.fullLong}}),Object.defineProperty(e,"shortDt",{enumerable:!0,get:function(){return s.shortDt}}),Object.defineProperty(e,"moYrDt",{enumerable:!0,get:function(){return s.moYrDt}}),Object.defineProperty(e,"tmAP",{enumerable:!0,get:function(){return s.tmAP}}),Object.defineProperty(e,"tmUTC",{enumerable:!0,get:function(){return s.tmUTC}}),Object.defineProperty(e,"monNm",{enumerable:!0,get:function(){return s.monNm}}),Object.defineProperty(e,"tN",{enumerable:!0,get:function(){return s.tN}}),Object.defineProperty(e,"addZ",{enumerable:!0,get:function(){return s.addZ}}),Object.defineProperty(e,"timeStandard",{enumerable:!0,get:function(){return s.timeStandard}}),Object.defineProperty(e,"dateStandard",{enumerable:!0,get:function(){return s.dateStandard}}),Object.defineProperty(e,"thisYear",{enumerable:!0,get:function(){return s.thisYear}});const c=n(794);Object.defineProperty(e,"objSort",{enumerable:!0,get:function(){return c.objSort}}),Object.defineProperty(e,"objLen",{enumerable:!0,get:function(){return c.objLen}}),Object.defineProperty(e,"objNestValueCount",{enumerable:!0,get:function(){return c.objNestValueCount}}),Object.defineProperty(e,"restoreObj",{enumerable:!0,get:function(){return c.restoreObj}}),Object.defineProperty(e,"restoreObjStr",{enumerable:!0,get:function(){return c.restoreObjStr}}),Object.defineProperty(e,"storeObj",{enumerable:!0,get:function(){return c.storeObj}}),Object.defineProperty(e,"storeObjStr",{enumerable:!0,get:function(){return c.storeObjStr}}),Object.defineProperty(e,"objSortSimple",{enumerable:!0,get:function(){return c.objSortSimple}})})();var a=t;for(var i in o)a[i]=o[i];o.__esModule&&Object.defineProperty(a,"__esModule",{value:!0})})()}};const t={};function r(n){const o=t[n];if(void 0!==o)return o.exports;const a=t[n]={exports:{}};return e[n](a,a.exports,r),a.exports}r.m=e,r.d=(e,t)=>{for(var n in t)r.o(t,n)&&!r.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},r.f={},r.e=e=>{const t=[];return r.f.require(e,t),Promise.all(t)},r.u=e=>({520:"engine-litert",924:"engine-wllama"}[e]+".node.min.js"),r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r.r=e=>{Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},(()=>{const e={792:1};r.f.require=(t,n)=>{if(!e[t]){const n=require("./"+r.u(t));e[t]||(t=>{const n=t.modules,o=t.ids,a=t.runtime;for(var i in n)r.o(n,i)&&(r.m[i]=n[i]);a&&a(r);for(var s=0;s<o.length;s++)e[o[s]]=1})(n)}}})();let n={};(()=>{"use strict";var e,t,o,a,i,s,c,l;let u;r.r(n),r.d(n,{BuiltinTool:()=>c,ChatModelId:()=>s,ChatStatus:()=>t,LlmBackend:()=>a,LlmPhase:()=>i,LlmRole:()=>e,LlmStatus:()=>o,WebSearchProvider:()=>l,builtinTools:()=>Rt,calculateTool:()=>ut,clearModelCache:()=>Je,createChat:()=>Ye,currencyTool:()=>Ct,describeImages:()=>it,describeModelId:()=>Xe,describeTranslated:()=>st,preloadModel:()=>Ge,webSearchTool:()=>$t}),function(e){e.system="system",e.user="user",e.assistant="assistant"}(e||(e={})),function(e){e[e.online=0]="online",e[e.away=1]="away",e[e.offline=2]="offline"}(t||(t={})),function(e){e[e.idle=0]="idle",e[e.downloading=1]="downloading",e[e.ready=2]="ready",e[e.error=3]="error",e[e.unsupported=4]="unsupported"}(o||(o={})),function(e){e.cpu="cpu",e.gpu="gpu",e.none="none"}(a||(a={})),function(e){e.download="download",e.load="load"}(i||(i={})),function(e){e.qwen3_vl_2b="qwen3-vl-2b",e.qwen3_vl_2b_instruct="qwen3-vl-2b-instruct",e.qwen3_vl_2b_instruct_q3="qwen3-vl-2b-instruct-q3",e.gemma4_e2b="gemma4-e2b",e.gemma4_e2b_limited="gemma4-e2b-limited"}(s||(s={})),function(e){e.websearch="websearch",e.calculate="calculate",e.currency="currency"}(c||(c={})),function(e){e.wikipedia="wikipedia",e.duckduckgo="duckduckgo"}(l||(l={}));const d=[{id:s.qwen3_vl_2b,reasoning:!0,cpu:{repo:"Qwen/Qwen3-VL-2B-Thinking-GGUF",file:"Qwen3VL-2B-Thinking-Q4_K_M.gguf",mmproj:{file:"mmproj-Qwen3VL-2B-Thinking-Q8_0.gguf"}}},{id:s.qwen3_vl_2b_instruct,reasoning:!1,cpu:{repo:"unsloth/Qwen3-VL-2B-Instruct-GGUF",file:"Qwen3-VL-2B-Instruct-Q4_K_M.gguf",mmproj:{repo:"Qwen/Qwen3-VL-2B-Instruct-GGUF",file:"mmproj-Qwen3VL-2B-Instruct-Q8_0.gguf"}}},{id:s.qwen3_vl_2b_instruct_q3,reasoning:!1,cpu:{repo:"unsloth/Qwen3-VL-2B-Instruct-GGUF",file:"Qwen3-VL-2B-Instruct-Q3_K_M.gguf",mmproj:{repo:"Qwen/Qwen3-VL-2B-Instruct-GGUF",file:"mmproj-Qwen3VL-2B-Instruct-Q8_0.gguf"}}},{id:s.gemma4_e2b,reasoning:!0,litert:{repo:"litert-community/gemma-4-E2B-it-litert-lm",file:"gemma-4-E2B-it.litertlm",vision:!0,audio:!0}},{id:s.gemma4_e2b_limited,reasoning:!0,litert:{repo:"litert-community/gemma-4-E2B-it-litert-lm",file:"gemma-4-E2B-it-gpu.litertlm",vision:!1,audio:!1}}],g=e=>{const t=e??("undefined"==typeof navigator?void 0:navigator);if(!t)return!1;if("boolean"==typeof t.userAgentData?.mobile)return t.userAgentData.mobile;const r=t.userAgent||"";return/Android|iPhone|iPad|iPod|Mobile/i.test(r)||/Macintosh/.test(r)&&t.maxTouchPoints>1},m=(e,t=g())=>e==s.gemma4_e2b&&t?s.gemma4_e2b_limited:e,p=e=>e?d.find(t=>t.id==e):void 0,f=async()=>{const e="undefined"==typeof navigator?void 0:navigator.gpu;if(!e)return!1;let t;try{return!!await Promise.race([e.requestAdapter({powerPreference:"high-performance"}),new Promise(e=>{t=setTimeout(()=>e(void 0),1500)})])}catch{return!1}finally{t&&clearTimeout(t)}},h=async e=>p(m(e??await(async()=>(u||(u=(async()=>await f()?m(s.gemma4_e2b):s.qwen3_vl_2b)()),await u))())),y=e=>!!e.cpu?.mmproj||!0===e.litert?.vision,w=e=>!!e.cpu?.mmproj?.audio||!0===e.litert?.audio,b=require("node:path"),v=()=>{return e=(0,b.join)(__dirname,"../assets/wllama"),{wasm:(0,b.join)(e,"wllama.wasm"),compatWasm:(0,b.join)(e,"compat/wllama.wasm"),compatWorker:(0,b.join)(e,"compat/wllama.js")};var e},x=()=>{return e=(0,b.join)(__dirname,"../assets/litert"),{script:(0,b.join)(e,"litertlm_wasm_internal.js"),wasm:(0,b.join)(e,"litertlm_wasm_internal.wasm")};var e},M={width:384,height:384},j=async e=>{if(!e.startsWith("data:"))return await(await fetch(e)).arrayBuffer();const t=e.indexOf(","),r=t>=0?e.slice(0,t):"";if(t<0)throw new Error("Invalid image data");if(!r.includes(";base64"))return await(await fetch(e)).arrayBuffer();const n=atob(e.slice(t+1)),o=new Uint8Array(n.length);for(let e=0;e<n.length;e++)o[e]=n.charCodeAt(e);return o.buffer},k=async(e,t)=>{if(!e||"function"!=typeof fetch||"function"!=typeof createImageBitmap)return e;try{const r=await fetch(e),n=await createImageBitmap(await r.blob()),o=t??((e,t)=>{const r=e/Math.max(1,t);let n=32,o=32,a=1/0,i=1/0;for(let e=1;e<=128;e++){const t=Math.ceil(128/e),s=Math.floor(136/e);for(let c=t;c<=s;c++){const t=c*e,s=Math.abs(c/e-r);(s<a-1e-9||Math.abs(s-a)<=1e-9&&t<i)&&(n=32*c,o=32*e,a=s,i=t)}}return{width:n,height:o}})(n.width,n.height),a=n.width/Math.max(1,n.height),i=o.width/o.height,s=Math.min(n.width,a>i?n.height*i:n.width),c=Math.min(n.height,a>i?n.height:n.width/i),l=(n.width-s)/2,u=(n.height-c)/2,d=((e,t)=>{if("undefined"!=typeof OffscreenCanvas)return new OffscreenCanvas(e,t);if("undefined"==typeof document)return;const r=document.createElement("canvas");return r.width=e,r.height=t,r})(o.width,o.height),g=d?d.getContext("2d"):null;if(!d||!g||n.width<1||n.height<1)return n.close(),e;if(g.drawImage(n,l,u,s,c,0,0,o.width,o.height),n.close(),(e=>"undefined"!=typeof OffscreenCanvas&&e instanceof OffscreenCanvas)(d)){const t=await d.convertToBlob({type:"image/jpeg",quality:.85});return await(e=>new Promise(t=>{if("undefined"==typeof FileReader)return void t("");const r=new FileReader;r.onerror=()=>t(""),r.onload=()=>t(`${r.result}`),r.readAsDataURL(e)}))(t)||e}return d.toDataURL("image/jpeg",.85)}catch{return e}};var T=r(69);const _={maxReplyTokens:250,maxThinkingTokens:128,maxReasoningTokens:320,maxImages:2,maxAudio:1,maxContentLength:1e3,promptCharBudget:1e4,maxThreads:32},S=(e,t,r)=>"number"==typeof e&&Number.isFinite(e)&&e>=r?Math.floor(e):t,P=(e={},t=!1)=>{const r=_;return{maxReplyTokens:S(e.maxReplyTokens,r.maxReplyTokens,1),maxThinkingTokens:S(e.maxThinkingTokens,r.maxThinkingTokens,1),maxReasoningTokens:S(e.maxReasoningTokens,t?1200:r.maxReasoningTokens,1),maxImages:S(e.maxImages,r.maxImages,0),maxAudio:S(e.maxAudio,r.maxAudio,0),maxContentLength:S(e.maxContentLength,r.maxContentLength,1),promptCharBudget:S(e.promptCharBudget,r.promptCharBudget,1),maxThreads:S(e.maxThreads,r.maxThreads,1)}},O=(e,t)=>({stream:!0,temperature:.7,max_tokens:t?e.maxReasoningTokens:e.maxReplyTokens}),C=(e,t)=>`https://huggingface.co/${e}/resolve/main/${t}`,D=e=>Number(e.headers.get("content-length"))||0,N=(e,t)=>e.some(e=>Array.isArray(e.content)&&e.content.some(e=>e.type==t)),E=e=>N(e,"image"),L=e=>N(e,"audio"),A=["<|channel>thought\n","<|channel>thought","..."],$=["<channel|>","..."],R=(e,t,r)=>t.length||r.length?[...e?[{type:"text",text:e}]:[],...t.map(e=>({type:"image",url:e})),...r.map(e=>({type:"audio",url:e}))]:e,q=e=>"string"==typeof e?e?[{type:"text",text:e}]:[]:e,U=(e,t)=>{if("string"==typeof e&&"string"==typeof t)return`${e}\n${t}`;const r=[];for(const n of[...q(e),{type:"text",text:"\n"},...q(t)]){const e=r[r.length-1];"text"==n.type&&"text"==e?.type?e.text+=n.text:r.push(n)}return r},I=g()?3e6:3e5,z=Math.max(I,84e4);class F extends Error{}const B=async(e,t,r)=>{let n;try{return await Promise.race([e,new Promise((e,o)=>{n=setTimeout(()=>o(new F(r)),t)})])}finally{n&&clearTimeout(n)}},V=e=>{try{Promise.resolve(e.return?.()).catch(()=>{})}catch{}},W=async({model:e,logging:t,onReason:r,onText:n,onSpeed:o,start:a,stopped:i,firstTimeoutMs:s=I,idleTimeoutMs:c=3e4,onStall:l})=>{let u="",d="",g="",m=!1,p=0,f=0;const h=((e,t)=>{let r="",n=!1;const o=(e,t)=>{let r=-1,n="";for(const o of t){const t=e.indexOf(o);t>=0&&(r<0||t<r)&&(r=t,n=o)}return{at:r,tag:n}},a=(e,t)=>{let r="";for(const n of t)for(let t=Math.min(e.length,n.length-1);t>r.length;t--)if(e.endsWith(n.slice(0,t))){r=e.slice(e.length-t);break}return r};return{feed:i=>{let s=r+i;for(r="";s;){if(n){const{at:t,tag:i}=o(s,$);if(t>=0){t&&e(s.slice(0,t)),s=s.slice(t+i.length),n=!1;continue}const c=a(s,$);e(s.slice(0,s.length-c.length)),r=c;break}{const{at:e,tag:i}=o(s,A);if(e>=0){e&&t(s.slice(0,e)),s=s.slice(e+i.length),s.startsWith("\n")&&(s=s.slice(1)),n=!0;continue}const c=a(s,A);t(s.slice(0,s.length-c.length)),r=c;break}}},flush:()=>{r&&(n?e(r):t(r),r="")}}})(e=>{d+=e,r(e)},e=>{u+=e,n(e)});try{const e=(await B(a(),s,"Model did not start"))[Symbol.asyncIterator]();for(;;){if(i()){V(e);break}let n;try{n=await B(e.next(),m?c:s,m?"Model stopped responding":"Model did not reply")}catch(r){if(r instanceof F&&(u||d)){l?.(),V(e),t&&console.log("Local chat stalled",r);break}throw r}if(n.done)break;m=!0;const a=n.value?.choices?.[0],y=a?.delta,w="string"==typeof y?.reasoning_content?y.reasoning_content:"string"==typeof y?.reasoning?y.reasoning:"";if(a?.finish_reason&&(g=a.finish_reason),w&&(d+=w,r(w)),y?.content&&h.feed(y.content),w||y?.content){const e=performance.now();p||(f=e),p+=1,p>1&&e>f&&o?.((0,T.rNum)(1e3*p/(e-f)))}}h.flush()}catch(e){if(t&&console.log("Local chat failed",e),e instanceof F&&!i())throw e}const y=i()?void 0:u||void 0;return t&&(console.log("Local chat reply",e.id,y?"****":""),console.log("Local chat finish",e.id,g||"none",u.length,d.length)),y},Q=async({model:t,params:r,start:n,stopped:o,onStall:a})=>{const i=await(async(e,t)=>{const r=[];for(const n of e){if("string"==typeof n.content){r.push(n);continue}const e=[];for(const r of n.content)e.push("image"==r.type?{type:"image",url:await k(r.url,t)}:r);r.push({role:"user",content:e})}return r})(((t,r=_)=>{const n=r.maxContentLength,o=t.filter(t=>"string"==typeof t.content&&!!t.content.trim()||!(t.role!=e.user||!t.images?.length&&!t.audio?.length)),a=[],i=[];let s=0,c=r.maxImages,l=r.maxAudio;for(let t=o.length-1;t>=0;t--){const u=o[t],d=("string"==typeof u.content?u.content:"").slice(0,n),g=u.role==e.user?(u.images||[]).filter(e=>"string"==typeof e&&!!e).slice(0,Math.max(0,c)):[],m=u.role==e.user?(u.audio||[]).filter(e=>"string"==typeof e&&!!e).slice(0,Math.max(0,l)):[];if(d||g.length||m.length){if(d&&s+d.length>r.promptCharBudget)break;s+=d.length,c-=g.length,l-=m.length,u.role==e.system?a.unshift(d):u.role==e.assistant?i.unshift({role:"assistant",content:d}):i.unshift({role:"user",content:R(d,g,m)})}}for(;i.length&&"user"!=i[0].role;)i.shift();const u=[];for(const e of i){const t=u[u.length-1];"assistant"==t?.role&&"assistant"==e.role?t.content=`${t.content}\n${e.content}`:"user"==t?.role&&"user"==e.role?t.content=U(t.content,e.content):"assistant"==e.role?u.push({role:"assistant",content:e.content}):u.push({role:"user",content:e.content})}const d=a.join("\n\n"),g=[];return d&&g.push({role:"system",content:d}),g.push(...u),g})(r.messages,r.limits),t.litert?M:void 0);return r.logging&&((e,t)=>{console.log("Local chat call",e.id,t.map(({role:e,content:t})=>({role:e,content:"****",...Array.isArray(t)?{images:t.filter(e=>"image"==e.type).length,audio:t.filter(e=>"audio"==e.type).length}:{}})))})(t,i),await W({model:t,logging:r.logging,onReason:r.onReason,onText:r.onText,onSpeed:r.onSpeed,start:()=>n(i),stopped:o,onStall:a,firstTimeoutMs:E(i)?z:I})},Y=33554432,G=new Map;let H=!1;const J=e=>{const t=(e.split("/").pop()||"model").replace(/[^\w.-]+/g,"_");let r=0;for(let t=0;t<e.length;t++)r=31*r+e.charCodeAt(t)>>>0;return`${r.toString(16)}-${t}`},Z=e=>{const t=/^part-(\d+)$/.exec(e);return t?Number(t[1]):-1},K=async()=>{if(!H)if("undefined"!=typeof navigator&&navigator.storage?.getDirectory)try{return await navigator.storage.getDirectory()}catch{return}else H=!0},X=async(e,t)=>{try{return await e.getDirectoryHandle(t)}catch{return}},ee=async e=>{if(e)try{const t=await e.getFile(),r=JSON.parse(await t.text());return{total:Number(r.total)||0,etag:`${r.etag||""}`,complete:!0===r.complete}}catch{return}},te=async(e,t)=>{try{const r=await e.getFileHandle("meta.json",{create:!0}),n=await r.createWritable();await n.write(JSON.stringify(t)),await n.close()}catch{}},re=async function*(e){for await(const t of e)yield t},ne=async e=>{try{for await(const[t,r]of re(e))"file"==r.kind&&Z(t)>=0&&await e.removeEntry(t).catch(()=>{})}catch{}},oe=async(e,t)=>{try{const r=await(await e.getFileHandle(t)).getFile(),n=await ee(await e.getFileHandle(`${t}.json`).catch(()=>{}));if(!n)return;return{file:r,size:r.size,total:n.total,etag:n.etag,complete:n.total?r.size>=n.total:!0===n.complete}}catch{return}},ae=async(e,t)=>{const r=await X(e,t);if(r){const e=await(async e=>await ee(await e.getFileHandle("meta.json").catch(()=>{})))(r),t=await(async e=>{const t=[];try{for await(const[r,n]of re(e)){const e=Z(r);if("file"!=n.kind||e<0)continue;const o=await n.getFile();t.push({part:{start:e,size:o.size},file:o})}}catch{return}const r=(e=>{const t=[];let r=0;for(const n of[...e].sort((e,t)=>e.start-t.start))if(n.size){if(n.start!=r)break;t.push(n),r+=n.size}return t})(t.map(e=>e.part)),n=new Set(r.map(e=>e.start)),o=t.filter(e=>n.has(e.part.start)).sort((e,t)=>e.part.start-t.part.start).map(e=>e.file);if(o.length)return{file:1==o.length?o[0]:new Blob(o),size:r.reduce((e,t)=>e+t.size,0)}})(r),n=e?.total||0,o=t?.size??0,a=t?.file??new Blob;return{file:n&&o>n?a.slice(0,n):a,size:o,total:n,etag:e?.etag||"",complete:n?o>=n:!0===e?.complete}}return await oe(e,t)},ie=(e,t)=>{const r=e.headers.get("content-range"),n=/bytes (\d+)-/.exec(r||""),o=/\/(\d+)\s*$/.exec(r||""),a=e.headers.get("etag")||"";if(206==e.status){const e=n?Number(n[1]):t.size,r=o?Number(o[1]):t.total;if(e!=t.size)return;if(t.total&&r&&t.total!=r)return;if(t.etag&&a&&t.etag!=a)return;return{start:e,total:r||t.total,etag:a||t.etag}}if(!t.etag||!a||t.etag==a)return{start:0,total:D(e)||t.total,etag:a||t.etag}},se=async({dir:e,start:t,skip:r,total:n,body:o,onProgress:a,onChunk:s})=>{let c,l=t,u=0,d=r;const g=async()=>{const t=await e.getFileHandle((e=>`part-${e}`)(l),{create:!0});c=await t.createWritable(),u=0},m=async()=>{const e=c;c=void 0,e&&await e.close().catch(()=>{})};try{const e=o.getReader();for(;;){const{done:r,value:o}=await e.read();if(r)break;s();let p=0;for(d&&(p=Math.min(d,o.byteLength),d-=p);p<o.byteLength;){c||await g();const e=Math.min(Y-u,o.byteLength-p);await c.write({type:"write",position:u,data:o.subarray(p,p+e)}),p+=e,u+=e,l+=e,u==Y&&await m()}l>t&&a(n?l/n:0,i.download)}await m()}catch(e){throw await m(),e}return l},ce=e=>["NotAllowedError","NotSupportedError"].includes(e?.name||""),le=e=>{const t=async()=>{const t=await K();if(t)try{return await t.getDirectoryHandle(e,{create:!0})}catch{return}};return{stored:async e=>{const r=await t();return r?await ae(r,J(e)):void 0},download:async({url:r,signal:n,onProgress:o})=>{const a=`${e}|${r}`,s=G.get(a);if(s)return await s;const c=await t();if(!c)return;const l=(async(e,t,r,n)=>{const o=J(t),a=await oe(e,o);if(a?.complete)return a;let s=await X(e,o);s||(await e.removeEntry(o).catch(()=>{}),await e.removeEntry(`${o}.json`).catch(()=>{}),s=await e.getDirectoryHandle(o,{create:!0}));let c=0,l=0;for(;;){if(r?.aborted)throw new Error("Cancelled");const a=await ae(e,o);if(a?.complete)return a;const u=a?.size??0,d=a?.total||0,g=a?.etag||"";if(u>c)c=u,l=0;else if(++l>4)throw new Error("Model download failed");u&&d&&n(u/d,i.download);const m=d?Math.min(u+Y,d)-1:u+Y-1,p=new AbortController,f=()=>p.abort(),h={size:u,total:d,etag:g};let y,w=setTimeout(f,3e4);r?.addEventListener("abort",f,{once:!0});try{if(y=await fetch(t,{signal:p.signal,headers:{Range:`bytes=${u}-${m}`}}),416==y.status){if(await(y.body?.cancel().catch(()=>{})),d&&u>=d){await te(s,{total:d,etag:g,complete:!0});continue}await ne(s),await te(s,{total:0,etag:"",complete:!1});continue}if(!y.ok||!y.body)throw await(y.body?.cancel().catch(()=>{})),new Error("Model download failed");const r=ie(y,h);if(!r){await y.body.cancel().catch(()=>{}),await ne(s),await te(s,{total:0,etag:"",complete:!1});continue}await te(s,{total:r.total,etag:r.etag,complete:!1});const a=0==r.start?u:0,i=await se({dir:s,start:r.start+a,skip:a,total:r.total,body:y.body,onProgress:n,onChunk:()=>{clearTimeout(w),w=setTimeout(f,3e4)}});if(!r.total){await te(s,{total:i,etag:r.etag,complete:!0});const t=await ae(e,o);if(t)return t}}catch(e){if(r?.aborted)throw new Error("Cancelled");if(e instanceof DOMException&&["QuotaExceededError","NotAllowedError","NotSupportedError","InvalidStateError","TypeMismatchError","SecurityError"].includes(e.name))throw e;await new Promise(e=>setTimeout(e,250+500*l))}finally{clearTimeout(w),r?.removeEventListener("abort",f)}}})(c,r,n,o).finally(()=>{G.delete(a)});return G.set(a,l),await l},remove:async e=>{const r=await t();r&&await(async(e,t)=>{await e.removeEntry(t,{recursive:!0}).catch(()=>{}),await e.removeEntry(`${t}.json`).catch(()=>{})})(r,J(e))},purge:async()=>{const t=await K();t&&await t.removeEntry(e,{recursive:!0}).catch(()=>{})}}},ue=(e,...t)=>{!0===e&&console.log(...t)},de="litertlm-models",ge=le("litert-store"),me={num_output_candidates:1,wait_for_weight_uploads:!0,num_decode_steps_per_sync:3,sequence_batch_size:0,supported_lora_ranks:[],max_top_k:40,enable_decode_logits:!1,enable_external_embeddings:!1,use_submodel:!1,use_autosized_ringbuffers:!0};let pe=!1,fe=0;const he=(...e)=>{pe&&console.log(...e)},ye=(...e)=>{pe&&console.error(...e)},we=e=>e.replace(/<\|channel>thought\n?[\s\S]*?<channel\|>/g,"").replace(/<\|channel>thought[\s\S]*$/,"").trim(),be=async()=>{try{if("undefined"==typeof caches)return;return await caches.open(de)}catch{return}},ve=new Map,xe=(e,t,r)=>{let n=0;return e.pipeThrough(new TransformStream({transform:(e,o)=>{n+=e.byteLength,r(t?n/t:0,i.download),o.enqueue(e)}}))},Me=async(e,t=!0)=>{const r=[];for(const n of e){if("string"==typeof n.content){r.push({role:n.role,content:n.content});continue}const e=[];for(const r of n.content)"text"!=r.type?t?e.push({type:r.type,data:await j(r.url)}):e.push({type:"text",text:`[${r.type}]`}):e.push({type:"text",text:r.text});r.push({role:n.role,content:e})}return r},je=(e,t)=>{if(e.role!=t.role)return!1;if("string"==typeof e.content||"string"==typeof t.content)return"string"==typeof e.content&&"string"==typeof t.content&&we(e.content)==we(t.content);if(e.content.length!=t.content.length)return!1;for(let r=0;r<e.content.length;r++){const n=e.content[r],o=t.content[r];if(n.type!=o.type)return!1;if("text"==n.type&&"text"==o.type){if(we(n.text)!=we(o.text))return!1}else{if("text"==n.type||"text"==o.type)return!1;if(!!n.url!=!!o.url)return!1}}return!0},ke=async function*({engine:e,mod:t,params:r,messages:n,session:o}){const a=n[n.length-1],i=O(r.limits,r.reasoning);if("user"!=a?.role)throw new Error("No user turn");const s=n.slice(0,-1),c=(await Me([a]))[0];if(!c)throw new Error("Empty prompt");const l=o.reasoning==r.reasoning&&o.maxTokens==i.max_tokens,u=!!o.conversation&&((e,t)=>{const r="system"==e[0]?.role?e[0]:void 0,n="system"==t[0]?.role?t[0]:void 0;if(!r!=!n)return!1;if(r&&n&&!je(r,n))return!1;const o=r?e.slice(1):e,a=n?t.slice(1):t;if(!a.length||a.length>o.length)return!1;const i=o.length-a.length;for(let e=0;e<a.length;e++)if(!je(o[i+e],a[e]))return!1;return!0})(o.sent,s);let d;if(l&&u&&o.conversation)ue(pe,"LiteRT conversation reused",o.sent.length),d=o.conversation;else{const n=await Me(s,!1);o.conversation=void 0,o.sent=[];const a=performance.now();d=await e.createConversation({sessionConfig:{maxOutputTokens:i.max_tokens,samplerParams:{type:t.SamplerType.TOP_K,temperature:i.temperature,k:40,p:.95}},preface:{...n.length?{messages:n}:{},extra_context:{enable_thinking:r.reasoning}},prefillPrefaceOnInit:n.length>0}),ue(pe,"LiteRT conversation created",n.length,Math.round(performance.now()-a),"flags",l,"history",u),o.conversation=d,o.reasoning=r.reasoning,o.maxTokens=i.max_tokens,o.sent=[...s]}o.sent.push(a);let g,m=!1,p=!0,f="";const h=(()=>{let e=0;return async t=>{if(!(t>0))return;if(e+=.25*t,e<12)return;const r=Math.min(120,e);e-=r,await new Promise(e=>setTimeout(e,Math.round(r)))}})(),y=()=>{g&&g.cancel().catch(()=>{});try{d.cancel()}catch{}};r.signal?.addEventListener("abort",y,{once:!0});try{if(r.signal?.aborted)return;const e=d.sendMessageStreaming(c).getReader();for(g=e;;){const t=performance.now(),{done:r,value:n}=await e.read(),o=performance.now()-t;if(r)break;const a=p;p=!1,a&&ue(pe,"LiteRT first chunk",Math.round(o));const i={};let s="string"==typeof n.content?n.content:"";if(Array.isArray(n.content))for(const e of n.content)"text"==e.type&&(s+=e.text);s&&(i.content=s,f+=s);const c=n.channels?.thought;c&&(i.reasoning=c),(i.content||i.reasoning)&&(yield{choices:[{delta:i}]}),a||await h(o)}m=!0}finally{r.signal?.removeEventListener("abort",y),m&&f?o.sent.push({role:"assistant",content:f}):(o.conversation=void 0,o.sent=[])}},Te={backend:a.gpu,startLLM:async({model:e,limits:t,onProgress:n,signal:o,logging:s})=>{pe=!0===s;const c=e.litert;if(!c)throw new Error("Model has no LiteRT artifact");const l=await r.e(520).then(()=>r(507)),u=globalThis,d=u.Module;u.Module={print:he,printErr:ye};try{await l.getOrLoadGlobalLiteRtLm(x().script)}finally{u.Module=d}if(o?.aborted)throw new Error("Cancelled");const g=C(c.repo,c.file),m=await be();let p;const f=m?await m.match(g):void 0;if(f?.body)p=f.body;else{const e=await ge.stored(g);e?.complete&&(p=e.file.stream())}if(!p){const e=await ge.download({url:g,signal:o,onProgress:n}).catch(e=>{if(o?.aborted)throw new Error("Cancelled");if(!ce(e))throw e;s&&console.log("Local model store failed",e)});e&&(p=e.file.stream())}if(!p&&m)try{await(async(e,t,r,n)=>{const o=ve.get(e);if(o)return await o;const a=(async()=>{const o=await fetch(e,{signal:r});if(!o.ok||!o.body)throw new Error("Model download failed");const a=D(o),i=xe(o.body,a,n);await t.put(e,new Response(i,{headers:{"content-type":"application/octet-stream",...a?{"content-length":`${a}`}:{}}}))})().finally(()=>{ve.delete(e)});return ve.set(e,a),await a})(g,m,o,n);const e=await m.match(g);e?.body&&(p=e.body)}catch(e){if(o?.aborted)throw new Error("Cancelled");s&&console.log("Local model cache failed",e)}if(p||(p=await(async(e,t,r)=>{const n=await fetch(e,{signal:t});if(!n.ok||!n.body)throw new Error("Model download failed");return xe(n.body,D(n),r)})(g,o,n)),o?.aborted)throw new Error("Cancelled");n(1,i.load);const h=await l.Engine.create((({model:e,limits:t,source:r,mod:n})=>{const o=e.litert;return{model:r,mainExecutorSettings:{maxNumTokens:4096,...o?.vision?{maxNumImages:Math.max(1,t.maxImages)}:{},backendConfig:me},...o?.vision?{visionBackend:n.Backend.GPU,maxVisionTokensPerImage:70,minVisionTokensPerImage:70}:{},...o?.audio?{audioBackend:n.Backend.CPU}:{}}})({model:e,limits:t,source:p,mod:l}));fe+=1;const y=()=>{fe=Math.max(0,fe-1),fe||(e=>{try{e.getGlobalLiteRtLm().liteRtLmWasm.preinitializedWebGPUDevice=void 0}catch{}})(l)};try{const e=performance.now(),t=await h.createConversation();await t.delete(),ue(pe,"LiteRT conversation warm-up",Math.round(performance.now()-e))}catch(e){ue(pe,"LiteRT conversation warm-up failed",e)}if(o?.aborted)throw await h.delete(),y(),new Error("Cancelled");const w={sent:[],reasoning:!1,maxTokens:0};return{model:e,backend:a.gpu,contextSize:4096,chat:t=>(async({engine:e,model:t,mod:r,params:n,session:o})=>{pe=!0===n.logging;const a=()=>{try{o.conversation?.cancel()}catch{}o.conversation=void 0,o.sent=[]};try{return await Q({model:t,params:n,stopped:()=>!!n.signal?.aborted,onStall:a,start:async a=>{if(n.signal?.aborted)throw new Error("Cancelled");if(E(a)&&!t.litert?.vision)throw new Error("Model does not accept images");if(L(a)&&!t.litert?.audio)throw new Error("Model does not accept audio");return ke({engine:e,mod:r,params:n,messages:a,session:o})}})}catch(e){throw a(),e}})({engine:h,model:e,mod:l,params:t,session:w}),unload:async()=>{const e=w.conversation;w.conversation=void 0,w.sent=[];try{await(e?.delete())}catch{}await h.delete(),y()}}},cached:async e=>{const t=e.litert;if(!t)return!1;const r=C(t.repo,t.file),[n,o]=await Promise.all([be(),ge.stored(r)]);if(o?.complete)return!0;try{return!(!n||!await n.match(r))}catch{return!1}},purge:async()=>{try{await ge.purge(),"undefined"!=typeof caches&&await caches.delete(de)}catch{}}},_e=le("wllama-store"),Se=[s.qwen3_vl_2b_instruct,s.qwen3_vl_2b_instruct_q3],Pe=e=>e.cpu?.mmproj&&Se.includes(e.id)?{image_min_tokens:16,image_max_tokens:128}:{};let Oe,Ce,De="",Ne=!1;const Ee=e=>`${e.wasm}|${e.compatWasm}|${e.compatWorker}`,Le=e=>{const t=v();return{wasm:e?.wasm||t.wasm,compatWasm:e?.compatWasm||t.compatWasm,compatWorker:e?.compatWorker||t.compatWorker}},Ae=e=>{const t=e=>(...t)=>{Ne&&("string"==typeof t[0]&&t[0].includes("ggml_webgpu: Failed to get an adapter")||e(...t))};return{...e,log:t(e.log),warn:t(e.warn),error:t(e.error)}},$e=async()=>{if(Oe)return Oe;const e=await r.e(924).then(()=>r(577)),t=Ce||Le(),n=new e.Wllama({default:t.wasm},{logger:Ae(e.LoggerWithoutDebug)});return Ce||(Ce=t,De=Ee(t)),n.setCompat({wasm:t.compatWasm,worker:t.compatWorker}),Oe=n,n},Re=async()=>{const e=Oe;Oe=void 0;try{await(e?.exit())}catch{}},qe=(e,t)=>e.name.includes(t)||!!e.metadata?.originalURL?.includes(t),Ue=e=>{const t=e.cpu;return t?[{name:t.file,url:C(t.repo,t.file)},...t.mmproj?[{name:t.mmproj.file,url:C(t.mmproj.repo??t.repo,t.mmproj.file)}]:[]]:[]},Ie=async e=>{const t=Ue(e);if(!t.length)return!1;for(const e of t){const t=await _e.stored(e.url);if(!t?.complete)return!1}return!0},ze=async(e,t)=>{const r=await e.cacheManager.list();return Ue(t).every(e=>r.some(t=>qe(t,e.name)))},Fe=async({model:e,signal:t,onProgress:r})=>{const n=Ue(e),o=[];for(let e=0;e<n.length;e++){if(t?.aborted)throw new Error("Cancelled");const a=await _e.download({url:n[e].url,signal:t,onProgress:(t,o)=>r((e+t)/n.length,o)});if(!a)return;o.push(a.file)}return o.length?o:void 0},Be=async e=>{const t=[];for(const r of e){if("string"==typeof r.content){"system"==r.role?t.push({role:"system",content:r.content}):"assistant"==r.role?t.push({role:"assistant",content:r.content}):t.push({role:"user",content:r.content});continue}const e=[];for(const t of r.content)"text"==t.type?e.push({type:"text",text:t.text}):e.push({type:t.type,data:await j(t.url)});t.push({role:"user",content:e})}return t},Ve={backend:a.cpu,startLLM:async({model:e,limits:t,onProgress:r,signal:n,logging:o,assets:s})=>{Ne=!0===o;const c=g()?4096:8192,l=e.cpu;if(!l)throw new Error("Model has no CPU artifact");const u=Le(s),d=Ee(u);Oe&&d!=De&&await Re(),Ce=u,De=d;const m="undefined"!=typeof navigator?navigator.hardwareConcurrency:0,p=Math.min((e=>{const t=e||4;return Math.max(1,t-Math.max(1,Math.floor(t/5)))})(m),t.maxThreads),f=await $e(),h=await Ie(e),y=l.mmproj?.file,w=C(l.repo,l.file),b=y?C(l.mmproj?.repo??l.repo,y):"";if(n?.aborted)throw await Re(),new Error("Cancelled");if(!h&&y){const e=await f.cacheManager.list(),t=e.some(e=>qe(e,l.file)),r=e.some(e=>qe(e,y));t&&!r&&await f.cacheManager.deleteMany(e=>qe(e,l.file))}const v={n_ctx:c,n_threads:p,n_parallel:1,warmup:!0,reasoning_budget_tokens:t.maxThinkingTokens,n_gpu_layers:0,jinja:!0,...Pe(e)};try{let t=h?await Fe({model:e,signal:n,onProgress:r}):void 0;t||h||await ze(f,e).catch(()=>!1)||(t=await Fe({model:e,signal:n,onProgress:r}).catch(e=>{if(n?.aborted)throw new Error("Cancelled");if(!ce(e))throw e;o&&console.log("Local model store failed",e)})),t?(r(1,i.load),await f.loadModel(t,v)):await f.loadModelFromUrl(b?{url:w,mmprojUrl:b}:w,{...v,useCache:!0,signal:n,progressCallback:({loaded:e,total:t})=>{const n=t?e/t:0;r(n,n>=1?i.load:i.download)}})}catch(e){throw await Re(),e}if(n?.aborted)throw await Re(),new Error("Cancelled");const x=f.getLoadedContextInfo();if(!x.n_ctx)throw await Re(),new Error("Failed to create model context");return ue(o,"CPU engine ready",e.id,"cores","undefined"!=typeof navigator?navigator.hardwareConcurrency:0,"isolated","undefined"!=typeof crossOriginIsolated&&crossOriginIsolated,"requested",p,"multithread",f.isMultithread(),"active",f.getNumThreads(),"context",x.n_ctx,"batch",x.n_batch,"ubatch",x.n_ubatch),{model:e,backend:a.cpu,contextSize:c,chat:t=>(async(e,t,r)=>{if(Ne=!0===r.logging,e.isModelLoaded())return await Q({model:t,params:r,stopped:()=>!!r.signal?.aborted,start:async n=>{if(E(n)&&!e.supportInputModality("image"))throw new Error("Model does not accept images");if(L(n)&&!e.supportInputModality("audio"))throw new Error("Model does not accept audio");return await e.createChatCompletion({messages:await Be(n),...O(r.limits,r.reasoning),abortSignal:r.signal,...t.reasoning?{chat_template_kwargs:{enable_thinking:r.reasoning}}:{}})}})})(f,e,t),unload:async()=>{if(Oe==f)await Re();else try{await f.exit()}catch{}}}},cached:async e=>{try{return!!e.cpu&&(!!await Ie(e)||await ze(await $e(),e))}catch{return!1}},purge:async()=>{try{await _e.purge()}catch{}try{const e=await $e();await e.cacheManager.clear()}catch{}}},We=((e={})=>{const t=e.engines?.cpu||Ve,r=e.engines?.litert||Te,n=e.mobile||g,s=new Map,c=new Map,l=new Map,u=new Map,d=new Map,m=new Map,p=new Map,f=new Map,h=new Map;let y,w,b,v=o.idle;const x=n=>{if(e.backend!=a.none)return e.backend==a.cpu?n.cpu?t:void 0:e.backend==a.gpu?n.litert?r:void 0:n.litert&&"undefined"!=typeof navigator&&navigator.gpu&&"undefined"!=typeof WebAssembly?r:!n.cpu||"undefined"==typeof window&&"undefined"==typeof self&&"undefined"==typeof Worker||"undefined"==typeof WebAssembly?void 0:t},M=e=>e?s.get(e):y?s.get(y.id):void 0,j=e=>{v=e},k=async e=>{const t=s.get(e);t&&(s.delete(e),y?.id==e&&(y=[...s.values()].pop()?.model),s.size||c.size||j(o.idle),await t.unload())},T=(e,t,r)=>{const n={percent:Math.max(0,Math.min(1,t)),phase:r||i.download};d.set(e,n);for(const t of u.get(e)??[])t.report(n.percent,n.phase)},_=e=>{p.set(e,(p.get(e)??0)+1),m.get(e)?.abort(),m.delete(e);const t=c.get(e);t&&l.set(e,t),c.delete(e),u.delete(e),d.delete(e),f.set(e,o.idle),v!=o.downloading||c.size||s.size||j(o.idle)},S=(e,t,r)=>{const n=c.get(e);return n?new Promise(o=>{let a=!1;const i={report:t,settle:e=>{a||(a=!0,r?.removeEventListener("abort",s),o(e))}},s=()=>{((e,t)=>{const r=u.get(e);r&&u.set(e,r.filter(e=>e!=t)),queueMicrotask(()=>{!u.get(e)?.length&&c.has(e)&&_(e)})})(e,i),i.settle(!1)},l=u.get(e);l?l.push(i):u.set(e,[i]),r?.aborted?s():r?.addEventListener("abort",s,{once:!0}),n.attempt.then(i.settle,()=>i.settle(!1))}):Promise.resolve(!1)},P=async e=>{if(e)await k(e);else{for(const e of[...c.keys()])_(e);d.clear(),f.clear(),h.clear(),w=void 0,j(o.idle),await(async()=>{for(const e of[...s.keys()])await k(e)})()}};return{load:async({model:e,limits:t,assets:r,logging:a,signal:g,onProgress:b})=>{if(g?.aborted)return!1;if(s.has(e.id))return y=e,!0;if(c.has(e.id)){const t=d.get(e.id);return t&&b(t.percent,t.phase),await S(e.id,b,g)}const v=x(e);if(!v){const t="Model is not supported on this device";return w=t,h.set(e.id,t),f.set(e.id,o.unsupported),j(o.unsupported),!1}const M=[...c.values(),...l.values()].filter(e=>n()||x(e.model)?.backend==v.backend);for(const e of M)_(e.model.id);const P=(p.get(e.id)??0)+1;p.set(e.id,P);const O=(async()=>{if(await Promise.all(M.map(e=>e.attempt.catch(()=>!1))),P!=p.get(e.id))return!1;if(await(async()=>{try{if("undefined"==typeof navigator)return;await(navigator.storage?.persist?.())}catch{}})(),P!=p.get(e.id))return!1;if(await(async e=>{for(const[t,r]of[...s])(n()||r.backend==e)&&await k(t)})(v.backend),P!=p.get(e.id))return!1;const c=await v.cached(e);if(P!=p.get(e.id))return!1;w=void 0,h.delete(e.id),f.set(e.id,o.downloading),j(o.downloading),T(e.id,0,i.download),c&&T(e.id,1,i.load);const l=new AbortController;m.set(e.id,l);try{const n=await v.startLLM({model:e,limits:t,logging:a,signal:l.signal,assets:r,onProgress:(t,r)=>{P==p.get(e.id)&&T(e.id,t,r)}});return P!=p.get(e.id)||l.signal.aborted?(await n.unload(),!1):(s.set(e.id,n),y=e,w=void 0,h.delete(e.id),f.set(e.id,o.ready),j(o.ready),T(e.id,1,i.load),!0)}catch(t){if(P!=p.get(e.id))return!1;const r=`${t?.message||`${t}`}`;return w=r,h.set(e.id,r),f.set(e.id,o.error),j(o.error),a&&console.log("Local model failed",t),!1}finally{m.get(e.id)==l&&m.delete(e.id)}})();let C;const D=O.finally(()=>{l.get(e.id)==C&&l.delete(e.id),c.get(e.id)==C&&(c.delete(e.id),u.delete(e.id),d.delete(e.id))});return C={model:e,attempt:D},c.set(e.id,C),u.set(e.id,[]),await S(e.id,b,g)},chat:async e=>{if(!M(e.model))return;for(;b;)await b.catch(()=>{});const t=M(e.model);if(!t)return;y?.id!=t.model.id&&(y=t.model);const r=t.chat(e);b=r;try{return await r}finally{b==r&&(b=void 0)}},unload:P,clear:async()=>{const e=[...c.values(),...l.values()].map(e=>e.attempt);await P(),await Promise.all(e.map(e=>e.catch(()=>{}))),await Promise.all([t.purge(),r.purge()])},ready:e=>!!M(e),loading:e=>e?c.has(e):c.size>0,status:e=>M(e)?o.ready:e?c.has(e)?f.get(e)??o.downloading:h.has(e)?f.get(e)??o.error:o.idle:v,backend:e=>M(e)?.backend??a.none,error:e=>e?h.get(e):w,model:()=>y}})(),Qe=(e,r,n)=>{const a=m(r),i=e.status(a),s=p(a);return{...a?{model:a}:{},availability:i==o.ready?t.online:i==o.error||i==o.unsupported?t.offline:t.away,status:i,backend:e.backend(a),supportsImages:!!s&&y(s),supportsAudio:!!s&&w(s),ready:e.ready(a),loading:e.loading(a),requesting:n.requesting,phase:n.phase,percent:n.percent,...n.error?{error:n.error}:{}}},Ye=(t=>{let r,n=0;const a=e=>e.input.onStatus?.(Qe(t,e.model??e.input.model,e));return s=>{r?.controller.abort();const c=m(s.model),l=t.ready(c),u={token:++n,input:s,controller:new AbortController,percent:l?100:0,phase:l?i.load:i.download,requesting:!1,cancelled:!1};return r=u,a(u),(async r=>{const{input:o}=r,s=!0===o.logging,c=await h(o.model);if(r.model=c?.id,r.token!=n)return;const l=o.messages.some(t=>t.role!=e.system&&"string"==typeof t.content&&!!t.content.trim()),u=o.messages.some(t=>t.role==e.user&&!!t.images?.some(e=>"string"==typeof e&&!!e)),d=o.messages.some(t=>t.role==e.user&&!!t.audio?.some(e=>"string"==typeof e&&!!e)),g=l||u||d;if(!c)return r.error="Unknown model",void a(r);if(!g)return r.error="No prompt",void a(r);const m=y(c),p=w(c);if(!(l||u&&m||d&&p))return d&&!p?r.error="Model does not accept audio":u&&!m&&(r.error="Model does not accept images"),void a(r);const f=P(o.limits,!!c.litert),b=await t.load({model:c,limits:f,logging:s,signal:r.controller.signal,onProgress:(e,t)=>{r.token==n&&(r.percent=Math.round(100*e),r.phase=t,a(r))}}).catch(e=>(r.token==n&&(r.error=`${e?.message||`${e}`}`),!1));if(r.token!=n)return;if(r.cancelled)return;if(!b)return r.error||(r.error=t.error(c.id)||"Model not ready"),void a(r);const v=u&&!m||d&&!p?o.messages.map(({images:e,audio:t,...r})=>({...r,...e&&m?{images:e}:{},...t&&p?{audio:t}:{}})):o.messages;r.requesting=!0,r.error=void 0,r.percent=100,r.phase=i.load,a(r);let x,M="",j="";try{x=await t.chat({model:c.id,messages:v,limits:f,reasoning:!0===o.reasoning,logging:s,onReason:e=>{r.token!=n||r.cancelled||(M+=e,o.onThinking?.(M))},onText:e=>{r.token!=n||r.cancelled||(j+=e,o.onResponse?.(j))},onSpeed:e=>{r.token!=n||r.cancelled||o.onSpeed?.(e)},signal:r.controller.signal})}catch(e){if(r.token!=n)return;return r.requesting=!1,r.error=`${e?.message||`${e}`}`,void a(r)}r.token==n&&(r.requesting=!1,x||r.cancelled||(r.error="No reply"),a(r))})(u),()=>(e=>{e.token==n&&(e.cancelled=!0,e.controller.abort(),e.model&&t.status(e.model)==o.ready?t.unload(e.model).then(()=>a(e)):queueMicrotask(()=>a(e)))})(u)}})(We),Ge=(He=We,async(e={})=>{const t=await h(e.model),r=r=>e.onStatus?.(Qe(He,t?.id,r));if(!t)return r({requesting:!1,phase:i.download,percent:0,error:"Unknown model"}),!1;let n,o=0,a=i.download;const s=He.ready(t.id);return await He.load({model:t,limits:P(e.limits,!!t.litert),logging:!0===e.logging,onProgress:(e,t)=>{o=Math.round(100*e),a=t,r({requesting:!1,phase:a,percent:o})}}).catch(e=>(n=`${e?.message||`${e}`}`,!1))?(s&&r({requesting:!1,phase:i.load,percent:100}),!0):(r({requesting:!1,phase:a,percent:o,error:n||He.error(t.id)||"Model not ready"}),!1)});var He;const Je=async()=>{await We.clear()},Ze=["Write fully detailed, factual image descriptions for low-vision readers.","Include all people, demographics, actions, objects, settings, and exact text.","Output only the raw description with no intro, title, or disclaimer.","Even if the main subject in the image is controversial mention it first.",'Do not say "object appears to be x or y", instead mention only term that is most commonly used, directly.','Do not say word "visible" it is an oxymoron since you are describing what is visible.',"Use direct, plain English without filtering or vague words."].join(" "),Ke=["describe this image in one sentence starting with the main subject"].join(" "),Xe=s.qwen3_vl_2b_instruct_q3,et=["You are a precise translator.","Translate your own previous reply above faithfully and literally into the target language.","Never translate the user's request or instructions.","Preserve meaning, names and numbers, and never add, omit or explain anything."].join(" "),tt="CANNOT_TRANSLATE",rt=e=>{const t=e.trim().toLowerCase();return!!t&&!/^(en|eng|english)([-_]|$)/.test(t)},nt=e=>`Now please translate your previous reply above faithfully into ${e}. Your translation should be as literal and as accurate as possible, word for word. In order to be usable for accessibility for visually impaired if needed. Reply only by the translation without any addition or explanation`,ot=({service:e,limits:t,logging:r,onStatus:n})=>{const o=(t,r)=>n?.(Qe(e,t,r));return{report:o,load:async n=>{let a,s=0,c=-1,l=i.download;ue(r,"Describe load start",n.id,t.maxReplyTokens);if(await e.load({model:n,limits:t,logging:r,onProgress:(e,t)=>{s=Math.round(100*e),l=t,s!=c&&(c=s,ue(r,"Describe load progress",n.id,s,l)),o(n.id,{requesting:!1,phase:l,percent:s})}}).catch(e=>(a=`${e?.message||`${e}`}`,!1)))return void ue(r,"Describe load ready",n.id);const u=a||e.error(n.id)||"Model not ready";return ue(r,"Describe load failed",n.id,u),o(n.id,{requesting:!1,phase:l,percent:s,error:u}),u},generate:async({model:n,messages:a,stage:s,onSpeed:c,onText:l})=>{let u="";const d=Date.now();ue(r,"Describe generate start",s,n,a.length);try{const o=await e.chat({model:n,messages:a,limits:t,reasoning:!1,logging:r,onReason:e=>{ue(r,"Describe reason",s,n,e)},onText:e=>{u+=e,ue(r,"Describe text",s,n,e),l?.(u)},onSpeed:e=>{ue(r,"Describe speed",s,n,e),c?.(e)}});return ue(r,"Describe generate reply",s,n,Date.now()-d,o?.length??0,o),o}catch(e){throw ue(r,"Describe generate failed",s,n,e),o(n,{requesting:!1,phase:i.load,percent:100,error:`${e?.message||`${e}`}`}),e}}}},at=async({translator:t,generate:r,descriptions:n,language:o,logging:a,currentIndex:i,onSpeed:s,onText:c})=>{const l=[...n];for(let u=0;u<n.length;u++){const d=(n[u]||"").trim();if(!d){i?.(u,d,d);continue}let g="";try{g=(await r({model:t.id,messages:[{role:e.system,content:et},{role:e.user,content:"[image] describe this image in English very accurately"},{role:e.assistant,content:d},{role:e.user,content:nt(o)}],stage:"translate",onSpeed:e=>s?.(u,e),onText:e=>c?.(u,e,"translate")})||"").trim()}catch(e){ue(a,"Translate item failed",u,e)}const m=g.replace(/[^a-z]/gi,"").toUpperCase().includes(tt.replace(/[^a-z]/gi,""));g&&!m&&(l[u]=g),i?.(u,d,l[u])}return l},it=(t=>async r=>{const{images:n,currentIndex:o}=r,a=[],c=!0===r.logging;if(ue(c,"Describe start",n.length,r.targetLanguage),!n.length)return ue(c,"Describe empty"),a;const l=p(Xe),u=Xe,d=P({maxReplyTokens:400,...r.limits}),{report:g,load:m,generate:h}=ot({service:t,limits:d,logging:c,onStatus:r.onStatus});ue(c,"Describe model",u,l?"found":"missing",d.maxReplyTokens,d.maxImages);const y=t.ready(u);if(g(u,{requesting:!1,phase:y?i.load:i.download,percent:y?100:0}),!l)throw ue(c,"Describe model missing",u),g(u,{requesting:!1,phase:i.download,percent:0,error:"Unknown model"}),new Error("Unknown model");const w=await m(l);if(w)throw ue(c,"Describe stop",w),new Error(w);g(l.id,{requesting:!0,phase:i.load,percent:100});for(let t=0;t<n.length;t++){const i=Date.now(),s=n[t];ue(c,"Describe image start",t,n.length,s.startsWith("data:")?"data URL":s,s.length),o?.(t);let u="";try{u=(await h({model:l.id,messages:[{role:e.system,content:Ze},{role:e.user,content:Ke,images:[s]}],stage:"describe",onSpeed:e=>r.onSpeed?.(t,e),onText:e=>r.onText?.(t,e,"describe")})||"").trim()}catch(e){ue(c,"Describe image failed",t,e)}const d=Date.now()-i;ue(c,"Describe english",t,d,u),u?(a.push({descriptionEN:u,description:u,durationMs:d}),o?.(t,u,void 0,d)):(ue(c,"Describe empty",t),a.push({descriptionEN:"",description:"",durationMs:d}),o?.(t,"",void 0,d))}const b=a.filter(e=>!!e.descriptionEN).length;if(ue(c,"Describe english ready",b),!b)return g(l.id,{requesting:!1,phase:i.load,percent:100,error:"No description"}),a;const v=r.targetLanguage.trim(),x=rt(v)&&await f()?p(s.gemma4_e2b_limited):void 0,M=x?await m(x):void 0;if(x&&!M)g(x.id,{requesting:!0,phase:i.load,percent:100}),await at({translator:x,generate:h,descriptions:a.map(e=>e.descriptionEN),language:v,logging:c,currentIndex:(e,t,r)=>{const n=a[e];r&&(n.description=r),o?.(e,t,n.description,n.durationMs)},onText:r.onText}),g(x.id,{requesting:!1,phase:i.load,percent:100});else{for(let e=0;e<a.length;e++){const t=a[e];t.descriptionEN&&o?.(e,t.descriptionEN,t.description,t.durationMs)}const e=x?.id??l.id,r=t.ready(e);g(e,{requesting:!1,phase:r?i.load:i.download,percent:r?100:0,...M?{error:M}:{}})}return a})(We),st=(e=>async t=>{const r=[...t.descriptions],n=t.targetLanguage.trim(),o=!0===t.logging;if(ue(o,"Translate start",r.length,n),!r.length||!rt(n))return ue(o,"Translate skipped"),r;const a=P({maxReplyTokens:400,...t.limits}),{report:c,load:l,generate:u}=ot({service:e,limits:a,logging:o,onStatus:t.onStatus}),d=await f()?p(s.gemma4_e2b_limited):void 0;if(!d)return ue(o,"Translate no gpu"),r;const g=await l(d);if(g)return ue(o,"Translate stop",g),r;c(d.id,{requesting:!0,phase:i.load,percent:100});const m=await at({translator:d,generate:u,descriptions:r,language:n,logging:o,currentIndex:t.currentIndex,onSpeed:t.onSpeed,onText:t.onText});return c(d.id,{requesting:!1,phase:i.load,percent:100}),m})(We),ct=/^[0-9+\-*/%^().]+$/,lt=e=>{let t=0;const r=e=>!!e&&e>="0"&&e<="9",n=e=>{throw new Error(e)},o=()=>{let o;for("("==e[t]?(t++,o=s(),")"!=e[t]&&n("Unbalanced parentheses"),t++):o=(()=>{const o=t;for(;r(e[t]);)t++;const a=e.slice(o,t);let i="";if("."==e[t]){t++;const n=t;for(;r(e[t]);)t++;i=e.slice(n,t)}return a||i?Number(`${a||"0"}.${i||"0"}`):n("Expected a number")})();"%"==e[t];)t++,o/=100;return o},a=()=>"+"==e[t]?(t++,a()):"-"==e[t]?(t++,-a()):(()=>{const r=o();return"^"!=e[t]?r:(t++,r**a())})(),i=()=>{let r=a();for(;"*"==e[t]||"/"==e[t];){const o=e[t];t++;const i=a();"*"==o?r*=i:(i||n("Division by zero"),r/=i)}return r},s=()=>{let r=i();for(;"+"==e[t]||"-"==e[t];){const n=e[t];t++;const o=i();r="+"==n?r+o:r-o}return r},c=s();return t<e.length&&n("Unexpected character"),Number.isFinite(c)||n("Result is not a finite number"),c},ut={name:"calculate",description:"Evaluate an arithmetic expression. Supports + - * / % ^ and parentheses; % divides by 100.",parameters:{type:"object",properties:{expression:{type:"string",description:"Arithmetic expression, for example 2*(3+4)"}},required:["expression"]},execute:e=>{const t=e.expression;if("string"!=typeof t)throw new Error("Missing expression");return(e=>{if(e.trim().length>200)throw new Error("Expression is too long");const t=(e=>e.replace(/×/g,"*").replace(/÷/g,"/").replace(/−/g,"-").replace(/,/g,"").replace(/\s+/g,""))(e);if(!t)throw new Error("Expression is empty");if(!ct.test(t))throw new Error("Unsupported character");const r=lt(t);return{expression:t,result:Math.abs(r)>=1e5?(0,T.pNum)(r)??r:(0,T.rNum)(r,12)}})(t)}},dt="degreesign-chat-prices-v1",gt="EUR",mt=5*T.oneMin,pt=30*T.oneSec;let ft,ht={},yt=0,wt=!1,bt=!1;const vt=e=>{const t={};for(const[r,n]of Object.entries(e??{}))"number"==typeof n&&Number.isFinite(n)&&(t[r.trim().toUpperCase()]=n);return t},xt=(e,t)=>e&&e.sourceAt>t.sourceAt?e:t,Mt=async({fiat:e,crypto:t})=>{try{const r=await fetch("https://srv.coinexams.com/data.json");if(!r.ok)throw new Error(`Price feed failed with ${r.status}`);const n=await r.json(),o=Date.now(),a=e?((e,t)=>{const r=vt(e.rates?.current),n=vt(e.rates?.yesterday);if(Object.keys(r).length)return{fetchedAt:t,sourceAt:Number(e.rates?.date)||t,rates:r,yesterday:n}})(n,o):void 0,i=t?((e,t)=>{const r=e.coins??{},n={},o={};for(const[e,t]of Object.entries(r)){const r=e.trim().toUpperCase(),a=t?.pr,i=t?.yst;"number"==typeof a&&Number.isFinite(a)&&(n[r]=a),"number"==typeof i&&Number.isFinite(i)&&(o[r]=i)}if(Object.keys(n).length)return{fetchedAt:t,sourceAt:Number(e.date)||t,prices:n,yesterday:o}})(n,o):void 0;if(e&&!a)throw new Error("Price feed is unavailable");if(t&&!i)throw new Error("Price feed is unavailable");a&&(ht.fiat=xt(ht.fiat,a)),i&&(ht.crypto=xt(ht.crypto,i)),yt=0,wt=!1,(()=>{try{if("undefined"==typeof localStorage)return;localStorage.setItem(dt,JSON.stringify(ht))}catch{}})()}catch(e){throw yt=Date.now(),wt=!0,e}},jt=e=>!!ht.crypto&&(e in ht.crypto.prices||e in ht.crypto.yesterday),kt=e=>!!ht.fiat&&(e in ht.fiat.rates||e in ht.fiat.yesterday),Tt=async e=>{const t=(e=>{const t={fiat:!1,crypto:!1};for(const r of e){if(r==gt)continue;const e=jt(r)||kt(r);!jt(r)&&e||(t.crypto=!0),jt(r)||(t.fiat=!0)}return t})(e),r=Date.now(),n=t.fiat&&r-(ht.fiat?.fetchedAt??0)>=T.oneHr,o=t.crypto&&r-(ht.crypto?.fetchedAt??0)>=mt;(n||o)&&("undefined"!=typeof navigator&&!1===navigator.onLine||yt&&r-yt<pt||(ft||(ft=Mt({fiat:n,crypto:o}).catch(()=>{}).finally(()=>{ft=void 0})),await ft))},_t=e=>{if(e==gt)return 1;const t=ht.crypto?.yesterday[e],r=ht.fiat?.yesterday[e];return t||(r?1/r:void 0)},St=(e,t)=>{if("string"!=typeof e||!e.trim())throw new Error(`Missing ${t}`);return e.trim().toUpperCase()},Pt=e=>Math.abs(e)>=1e5?(0,T.pNum)(e)??e:(0,T.rNum)(e,8),Ot=async e=>{(()=>{if(!bt){bt=!0;try{if("undefined"==typeof localStorage)return;const e=localStorage.getItem(dt);if(!e)return;const t=JSON.parse(e);ht={...t.fiat?{fiat:t.fiat}:{},...t.crypto?{crypto:t.crypto}:{}}}catch{}}})();const t=St(e.from,"from"),r=void 0===e.to||null===e.to?gt:St(e.to,"to"),n=(e=>{if(null==e)return 1;if("number"!=typeof e||!Number.isFinite(e))throw new Error("Invalid amount");return e})(e.amount);await Tt([t,r]);const o=e=>{const t=(e=>{if(e==gt)return 1;const t=ht.crypto?.prices[e],r=ht.fiat?.rates[e];return t||(r?1/r:void 0)})(e);if(void 0!==t)return t;if(!ht.fiat&&!ht.crypto)throw new Error("Prices unavailable offline");if(jt(e)||kt(e))throw new Error(`Unavailable quote for ${e}`);throw new Error(`Unknown symbol ${e}`)},a=o(t),i=o(r),s=_t(t),c=_t(r),l=a/i,u=s&&c?s/c:void 0,d=void 0===u?void 0:l-u,g=void 0===u?void 0:100*(l/u-1),m=(e=>{const t=[];for(const r of e)r!=gt&&(jt(r)?ht.crypto&&t.push(ht.crypto.sourceAt):kt(r)&&ht.fiat&&t.push(ht.fiat.sourceAt));return t})([t,r]),p=m.length?Math.min(...m):Date.now();return{from:t,to:r,amount:n,rate:Pt(l),...void 0===u?{}:{previousRate:Pt(u),change:Pt(d??0),changePercent:(0,T.rNum)(g??0,4)},result:Pt(n*l),updatedAt:new Date(p).toISOString(),stale:wt&&!(!ht.fiat&&!ht.crypto)}},Ct={name:"currency",description:"Get the EUR price of a fiat currency, crypto coin or metal, or convert an amount. Returns the 24-hour change.",parameters:{type:"object",properties:{from:{type:"string",description:"Currency, coin or metal to convert from"},to:{type:"string",description:"Currency, coin or metal to convert to, EUR by default"},amount:{type:"number",description:"Amount to convert, 1 by default"}},required:["from"]},execute:e=>Ot(e)},Dt={amp:"&",apos:"'",gt:">",lt:"<",nbsp:" ",quot:'"',hellip:"...",mdash:"-",ndash:"-",ldquo:'"',lsquo:"'",rdquo:'"',rsquo:"'"},Nt=(e,t,r,n)=>"number"==typeof e&&Number.isFinite(e)?Math.min(r,Math.max(t,e)):n,Et=(e,t)=>e.replace(/<[^>]*>/g," ").replace(/&(#x?[0-9a-f]+|[a-z]+);/gi,(e,t)=>{const r=(e=>{if(e.startsWith("#")){const t="x"==e[1]||"X"==e[1],r=parseInt(t?e.slice(2):e.slice(1),t?16:10);return r>0&&r<=1114111?String.fromCodePoint(r):e}return Dt[e.toLowerCase()]??e})(t);return r==t?e:r}).replace(/\s+/g," ").trim().slice(0,Math.max(0,t)).trim(),Lt=/^[a-z]{2,3}(-[a-z]{2,4})?$/i,At=async(e,t)=>{const r=new AbortController,n=setTimeout(()=>r.abort(),t);try{const t=await fetch(e,{signal:r.signal});if(!t.ok)throw new Error(`Search failed with ${t.status}`);return await t.json()}catch(e){if(r.signal.aborted)throw new Error(`Search timed out after ${t} ms`);throw e}finally{clearTimeout(n)}},$t=(e={})=>{const t=((e={})=>{const t=e.language?.trim()??"";return{provider:e.provider==l.duckduckgo?l.duckduckgo:l.wikipedia,language:Lt.test(t)?t:"en",limit:Math.round(Nt(e.limit,1,20,3)),snippetLength:Math.round(Nt(e.snippetLength,1,4e3,400)),timeout:Nt(e.timeout,1e3,3e4,8e3)}})(e);return{name:"websearch",description:t.provider==l.duckduckgo?"Search DuckDuckGo for an instant answer and related topics.":"Search Wikipedia and return a few matching articles.",parameters:{type:"object",properties:{query:{type:"string",description:"What to search for"}},required:["query"]},execute:async e=>{const r="string"==typeof e.query?e.query.trim():"";if(!r)throw new Error("Missing query");const n=t.provider==l.duckduckgo?await(async(e,t)=>{const r=`https://api.duckduckgo.com/?format=json&no_html=1&skip_disambig=1&q=${encodeURIComponent(t)}`,n=await At(r,e.timeout),o=[],a=new Set,i=(t,r,n)=>{t&&n&&!a.has(t)&&(a.add(t),o.push({title:Et(r||n,200),url:t,snippet:Et(n,e.snippetLength)}))},s=e=>{for(const t of e)t.Topics?s(t.Topics):i(t.FirstURL,t.Text,t.Text)};i(n.AbstractURL,n.Heading||n.AbstractText,n.AbstractText);for(const e of n.Results??[])i(e.FirstURL,e.Text,e.Text);return s(n.RelatedTopics??[]),o.slice(0,e.limit)})(t,r):await(async(e,t)=>{const r=`https://${e.language}.wikipedia.org`,n=`${r}/w/rest.php/v1/search/page?q=${encodeURIComponent(t)}&limit=${e.limit}`,o=await At(n,e.timeout),a=[];for(const t of o.pages??[]){const n=t.key;n&&a.push({title:Et(t.title??n,200),url:`${r}/wiki/${encodeURIComponent(n)}`,snippet:Et(`${t.description??""} ${t.excerpt??""}`,e.snippetLength)})}return a})(t,r);return n}}},Rt=(e,t)=>{const r=[];for(const n of e)n==c.websearch?r.push($t(t)):n==c.calculate?r.push(ut):n==c.currency&&r.push(Ct);return r}})(),module.exports=n})();
2
+ (()=>{var e={69(e,t){(()=>{"use strict";var e={125:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.addZ=t.tN=t.monNm=t.tmUTC=t.tmAP=t.moYrDt=t.shortDt=t.fullLong=t.fullDate=t.fullDt=t.invDt=t.dayRes=t.timeStandard=t.dateStandard=t.seoDt=t.thisYear=t.oneMon=t.oneMin=t.oneHr=t.oneDay=t.oneSec=void 0;const r=()=>Date.now(),n=["January","February","March","April","May","June","July","August","September","October","November","December"],o=["JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC"],a=["st","nd","rd","th"],i=e=>0==+e?"00":+e<10&&+e>=1?`0${e}`:`${e}`,s=e=>{const t=new Date(e);return`${t.getUTCFullYear()}-${i(t.getUTCMonth()+1)}-${i(t.getUTCDate())}`},c=e=>i(e.getUTCHours())+`:${i(e.getUTCMinutes())}`+`:${i(e.getUTCSeconds())}`;t.tN=r,t.monNm=n,t.dayRes=90,t.oneSec=1e3,t.oneMin=6e4,t.oneHr=36e5,t.oneDay=864e5,t.oneMon=27e8,t.addZ=i,t.tmUTC=e=>{const t=new Date(e);return i(t.getUTCHours())+`:${i(t.getUTCMinutes())} UTC`},t.tmAP=e=>{const t=new Date(e),r=t.getHours();return i(r>12?r-12:r)+`:${i(t.getMinutes())}`+(r>=12?"pm":"am")},t.shortDt=e=>{const t=new Date(e);return`${t.getDate()} ${o[t.getMonth()]}`},t.moYrDt=e=>{const t=new Date(e);return`${o[t.getMonth()]} ${t.getFullYear()}`},t.fullDt=e=>{const t=new Date(e);return`${t.getDate()} ${o[t.getMonth()]} ${t.getFullYear()}`},t.fullDate=e=>{const t=new Date(e);return`${t.getDate()} ${n[t.getMonth()]} ${t.getFullYear()}`},t.fullLong=e=>`${(e=>{const t=new Date(e),r=t.getDate();return r+a[r<5?r-1:r>4&&r<21?3:r>20&&r<25?r-21:r>24&&r<31?3:0]+` of ${n[t.getMonth()]}`})(e)} ${new Date(e).getFullYear()}`,t.thisYear=e=>(e?new Date(e):new Date)?.getUTCFullYear(),t.dateStandard=s,t.timeStandard=c,t.seoDt=e=>{!e&&(e=r());const t=new Date(e);return`${s(t)}T${c(t)}Z`},t.invDt=e=>{const t=new Date(e);return`${t.getUTCFullYear()}`.split("20")[1]+i(t.getUTCMonth()+1)+i(t.getUTCDate())+`${e}`.slice(10)}},240:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.idRandLong=t.idRandShort=t.idShuffle=void 0;const r=["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","@",".","_","0","1","2","3","4","5","6","7","8","9"];t.idShuffle=async({data:e,password:t})=>4==t?.length?(({data:e,password:t})=>{try{const n=(e,t)=>r.includes(e.toLowerCase())?r[(r.indexOf(e.toLowerCase())+Math.pow(t,3))%r.length]:e;return[...e].map(e=>n(e,Number(t))).join("")}catch{return""}})({data:e,password:t}):await(async({data:e,password:t})=>{if(!e||!t)return"";try{crypto.subtle;const r=new TextEncoder,n=r.encode(e),o=r.encode(t),a=await crypto.subtle.digest("SHA-256",o),i=new Uint8Array(a),s=i.slice(0,32),c=i.slice(0,12),l=await crypto.subtle.importKey("raw",s,{name:"AES-GCM"},!1,["encrypt"]),u=await crypto.subtle.encrypt({name:"AES-GCM",iv:c},l,n);return btoa(String.fromCharCode(...new Uint8Array(u))).replace(/\+/g,"a").replace(/\//g,"b").replace(/=/g,"c").toLowerCase()}catch{return""}})({data:e,password:t}),t.idRandShort=(e=10)=>{try{return crypto.randomUUID()?.replaceAll("-","")?.slice(0,e)}catch(e){return console.log("idRandShort failed",e),""}},t.idRandLong=(e=10)=>{try{const t="abcdefghijklmnopqrstuvwxyz",r=new Uint8Array(e);return crypto.getRandomValues(r),Array.from(r).map(e=>t[e%26]).join("")}catch(e){return console.log("idRandLong failed",e),""}}},246:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.cacheCheck=t.delayCode=void 0;const n=r(125);t.delayCode=async(e=0)=>await new Promise(t=>setTimeout(t,e)),t.cacheCheck=({analysisCacheLimit:e,lastUpdated:t,forceRefresh:r})=>{const o=Date.now();if(t&&(!r&&t>o-e||r&&t>o-n.oneDay))return!0}},792:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.isEven=t.pNum=t.sharpeRatio=t.priceVariations=t.nTxtAr=t.zNum=t.addCom=t.adjNum=t.rNum=void 0;const r=[1,.1,.01,.001,1e-4,1e-5,1e-6,1e-7,1e-8,1e-9,1e-10,1e-11,1e-12,1e-13,1e-14,1e-15,1e-16,1e-17,1e-18,1e-19],n=(e,t=6)=>{const n=+e,o=n?Math.abs(n):0,a=o>1&&t?t-`${Math.round(o)}`.length:0;return n?(n<0?-1:1)*(Number.isInteger(o)||o<1e-16?o:o>1e5?Math.round(o):o>1?Number(o.toFixed(a<0?0:a)):((e,t)=>{let n=0;for(const o of r){if(o<e)return Number(e.toFixed(t+n-1));n++}return e})(o,t)):e},o=(e,t)=>{const r=(n(e,t)+"").split(".");return r[0]=r[0].replace(/\B(?=(\d{3})+(?!\d))/g,","),r.join(".")},a=(e,t=3)=>{const r=Number(e);if(!e||!r)return e+"";const a=Math.abs(r);return(r<0?"-":"")+(a>1e9?o(a/1e9,t)+"b":a>1e6?o(a/1e6,t)+"m":a<1e-6&&a>1e-16?(1+n(a,t)+"").replace(/1./g,"0."):o(a,t))};t.nTxtAr=["zero","one","two","three","four","five","six","seven","eight","nine","ten"],t.rNum=n,t.addCom=o,t.adjNum=a,t.zNum=e=>{const t=Number(e);let r=t?Math.abs(t):0,n=1e10;for(;n>1;)r>n&&(r=Math.round(r/(n/10))*(n/10)),n/=10;return t?(t<0?"-":"")+a(r,2):e},t.pNum=e=>+e||0==+e?Math.round(1e6*+e)/1e6:null,t.priceVariations=e=>{try{let t=0;const r=[...e].sort((e,t)=>e[0]-t[0]),n=e.reduce((e,[,t])=>e+t,0),o=r.find(([,e])=>(t+=e,t>=n/2))[0];return e.filter(([e])=>Math.abs(e-o)/o<.05).map(([e])=>e)}catch{return[]}},t.sharpeRatio=({assetPrices:e,minExpectedReturn:t=.05})=>{if(!e?.length||e?.length<2)return 0;const r=e.slice(1).map((t,r)=>(t-e[r])/e[r]),n=r.reduce((e,t)=>e+t,0)/r.length,o=Math.sqrt(r.reduce((e,t)=>e+Math.pow(t-n,2),0)/r.length);return(n-t)/o},t.isEven=e=>e%2==0},794:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.restoreObj=t.restoreObjStr=t.storeObj=t.storeObjStr=t.objNestValueCount=t.objLen=t.objSortSimple=t.objSort=void 0;const n=r(125),o=e=>{try{return Object.keys(e||{})?.length||0}catch(e){return console.log(e),0}},a=e=>{try{return e?.replace(/"/g,"'")}catch(e){return console.log((0,n.tN)(),"storeObjStr failed",e),""}},i=e=>{try{return e?.toString()?.replace(/'/g,'"')}catch(e){console.log((0,n.tN)(),"restoreObjStr failed",e)}};t.objLen=o,t.objNestValueCount=e=>{let t=0;if(o(e))for(const r in e)t+=o(e[r])?1:0;return t},t.objSort=(e={},t,r=-1)=>Object.fromEntries(Object.entries(e).sort(([,e],[,n])=>null===e[t]||void 0===e[t]?1:null===n[t]||void 0===n[t]?-1:e[t]>n[t]?1*r:-1*r)),t.objSortSimple=(e={},t=-1)=>Object.fromEntries(Object.entries(e).sort(([,e],[,r])=>null==e?1:null==r?-1:e>r?1*t:-1*t)),t.storeObjStr=a,t.storeObj=e=>{try{return a(JSON.stringify(e))}catch(e){return console.log((0,n.tN)(),"storeObj failed",e),""}},t.restoreObjStr=i,t.restoreObj=e=>{try{if(!e)return;const t=i(e);return t?JSON.parse(t):void 0}catch(e){console.log((0,n.tN)(),"restoreObj failed",e)}}},830:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.phaseDifference=t.compareArrays=t.squeezeArray=t.forecastNextTotal=t.forecastNext=t.getMax=t.getMean=t.getSum=t.maxVl=t.minVl=t.sumArr=void 0;const r=e=>{try{return e?.length?e.reduce((e,t)=>e+t):0}catch(e){return console.log("sumArr failed",e),0}},n=e=>{try{return e?.length?e.reduce((e,t)=>e+t,0):0}catch(e){return console.log("getSum failed",e),0}},o=e=>{try{return e?.length?n(e)/e.length:0}catch(e){return console.log("getMean failed",e),0}},a=e=>{try{return e?.length?Math.max(...e):0}catch(e){return console.log("getMax failed",e),0}},i=e=>{try{if(!e?.length)return 0;const t=[...e].sort((e,t)=>e-t),r=Math.floor(t.length/2);return t.length%2?t[r]:(t[r-1]+t[r])/2}catch(e){return console.log("median failed",e),0}},s=({currentPeriod:e,steps:t=1})=>{try{const r=(Array.isArray(e)?e:[]).filter(Number.isFinite);if(!r.length||t<=0)return[];if(r.length<2){const e=Math.max(0,o(r));return Array.from({length:t},()=>e)}const n=r.length,{slope:s,intercept:c}=(e=>{try{const t=e.length,r=[];for(let n=0;n<t-1;n++)for(let o=n+1;o<t;o++)r.push((e[o]-e[n])/(o-n));const n=i(r);return{slope:n,intercept:i(e.map((e,t)=>e-n*t))}}catch(e){return console.log("theilSen failed",e),{slope:0,intercept:0}}})(r),l=c+s*(n-1),u=a(r),d=u>0?3*u:1/0;return Array.from({length:t},(e,t)=>{const r=t+1,o=l+s*n*Math.log1p(r/n);return Math.max(0,Math.min(o,d))})}catch(e){return console.log("forecastNext failed",e),[]}};t.sumArr=r,t.maxVl=(e,t)=>{let r=0;for(let n=0;n<e.length;n++){const o=e[n];o[t]>r&&(r=o[t])}return r},t.minVl=(e,t)=>{let r=0;for(let n=0;n<e.length;n++){const o=e[n];o[t]<r&&(r=o[t])}return r},t.getSum=n,t.getMean=o,t.getMax=a,t.forecastNext=s,t.forecastNextTotal=e=>{try{const t=s({currentPeriod:e,steps:e?.length});return n(t)}catch(e){return console.log("forecastNextTotal failed",e),0}},t.squeezeArray=({arr:e,targetLength:t})=>{try{if(!e||0===e.length||t<=0)throw new Error("Invalid input");const n=Math.ceil(e.length/t);return Array.from({length:t},(t,o)=>{const a=o*n,i=Math.min(a+n,e.length),s=e.slice(a,i);return r(s)}).slice(0,t)}catch(e){return console.log("squeezeArray failed",e),[]}},t.compareArrays=({arrays:e})=>{try{const t=[...e],n=Math.min(...t.map(e=>e.length));for(let e=0;e<t.length;e++)t.splice(n);const o=t.map(e=>r(e)),a=[],i=Math.min(...o),s=o.indexOf(i),c=i/Math.max(...o);for(let e=0;e<t.length;e++){const r=t[e];if(a[e]=[],e==s)a[e]=r;else for(let t=0;t<r.length;t++)a[e].push(c*r[t])}return a}catch(t){return console.log("compareArrays failed",t),e}},t.phaseDifference=({array1:e,array2:t})=>{try{let r=e.length,n=e.reduce((e,t)=>e+t)/r,o=t.reduce((e,t)=>e+t)/r,a=e.map(e=>e-n),i=t.map(e=>e-o),s=Math.floor(r/2),c=-1/0,l=0;for(let e=-s;e<=s;e++){let t=0,n=0,o=0,s=0;for(let c=0;c<r;c++){let l=c+e;l>=0&&l<r&&(t+=a[c]*i[l],n+=a[c]*a[c],o+=i[l]*i[l],s++)}if(n>0&&o>0&&s>=.8*r){let r=t/Math.sqrt(n*o);r>c&&(c=r,l=e)}}return l}catch(e){return console.log("phaseDifference failed",e),0}}}},r={};function n(t){var o=r[t];if(void 0!==o)return o.exports;var a=r[t]={exports:{}};return e[t](a,a.exports,n),a.exports}var o={};(()=>{var e=o;Object.defineProperty(e,"__esModule",{value:!0}),e.idShuffle=e.isEven=e.pNum=e.nTxtAr=e.zNum=e.addCom=e.adjNum=e.rNum=e.sharpeRatio=e.priceVariations=e.timeStandard=e.dateStandard=e.addZ=e.tN=e.monNm=e.tmUTC=e.tmAP=e.moYrDt=e.shortDt=e.fullLong=e.fullDate=e.fullDt=e.invDt=e.dayRes=e.thisYear=e.seoDt=e.oneMon=e.oneMin=e.oneHr=e.oneDay=e.oneSec=e.restoreObj=e.restoreObjStr=e.storeObj=e.storeObjStr=e.objSortSimple=e.objSort=e.objNestValueCount=e.objLen=e.phaseDifference=e.compareArrays=e.squeezeArray=e.forecastNextTotal=e.forecastNext=e.getMax=e.getMean=e.getSum=e.maxVl=e.minVl=e.sumArr=void 0,e.cacheCheck=e.delayCode=e.idRandLong=e.idRandShort=void 0;const t=n(246);Object.defineProperty(e,"cacheCheck",{enumerable:!0,get:function(){return t.cacheCheck}}),Object.defineProperty(e,"delayCode",{enumerable:!0,get:function(){return t.delayCode}});const r=n(830);Object.defineProperty(e,"sumArr",{enumerable:!0,get:function(){return r.sumArr}}),Object.defineProperty(e,"minVl",{enumerable:!0,get:function(){return r.minVl}}),Object.defineProperty(e,"maxVl",{enumerable:!0,get:function(){return r.maxVl}}),Object.defineProperty(e,"getMax",{enumerable:!0,get:function(){return r.getMax}}),Object.defineProperty(e,"getMean",{enumerable:!0,get:function(){return r.getMean}}),Object.defineProperty(e,"getSum",{enumerable:!0,get:function(){return r.getSum}}),Object.defineProperty(e,"forecastNext",{enumerable:!0,get:function(){return r.forecastNext}}),Object.defineProperty(e,"forecastNextTotal",{enumerable:!0,get:function(){return r.forecastNextTotal}}),Object.defineProperty(e,"squeezeArray",{enumerable:!0,get:function(){return r.squeezeArray}}),Object.defineProperty(e,"compareArrays",{enumerable:!0,get:function(){return r.compareArrays}}),Object.defineProperty(e,"phaseDifference",{enumerable:!0,get:function(){return r.phaseDifference}});const a=n(240);Object.defineProperty(e,"idRandLong",{enumerable:!0,get:function(){return a.idRandLong}}),Object.defineProperty(e,"idRandShort",{enumerable:!0,get:function(){return a.idRandShort}}),Object.defineProperty(e,"idShuffle",{enumerable:!0,get:function(){return a.idShuffle}});const i=n(792);Object.defineProperty(e,"addCom",{enumerable:!0,get:function(){return i.addCom}}),Object.defineProperty(e,"adjNum",{enumerable:!0,get:function(){return i.adjNum}}),Object.defineProperty(e,"priceVariations",{enumerable:!0,get:function(){return i.priceVariations}}),Object.defineProperty(e,"nTxtAr",{enumerable:!0,get:function(){return i.nTxtAr}}),Object.defineProperty(e,"rNum",{enumerable:!0,get:function(){return i.rNum}}),Object.defineProperty(e,"zNum",{enumerable:!0,get:function(){return i.zNum}}),Object.defineProperty(e,"sharpeRatio",{enumerable:!0,get:function(){return i.sharpeRatio}}),Object.defineProperty(e,"pNum",{enumerable:!0,get:function(){return i.pNum}}),Object.defineProperty(e,"isEven",{enumerable:!0,get:function(){return i.isEven}});const s=n(125);Object.defineProperty(e,"oneSec",{enumerable:!0,get:function(){return s.oneSec}}),Object.defineProperty(e,"oneDay",{enumerable:!0,get:function(){return s.oneDay}}),Object.defineProperty(e,"oneHr",{enumerable:!0,get:function(){return s.oneHr}}),Object.defineProperty(e,"oneMin",{enumerable:!0,get:function(){return s.oneMin}}),Object.defineProperty(e,"oneMon",{enumerable:!0,get:function(){return s.oneMon}}),Object.defineProperty(e,"seoDt",{enumerable:!0,get:function(){return s.seoDt}}),Object.defineProperty(e,"dayRes",{enumerable:!0,get:function(){return s.dayRes}}),Object.defineProperty(e,"invDt",{enumerable:!0,get:function(){return s.invDt}}),Object.defineProperty(e,"fullDt",{enumerable:!0,get:function(){return s.fullDt}}),Object.defineProperty(e,"fullDate",{enumerable:!0,get:function(){return s.fullDate}}),Object.defineProperty(e,"fullLong",{enumerable:!0,get:function(){return s.fullLong}}),Object.defineProperty(e,"shortDt",{enumerable:!0,get:function(){return s.shortDt}}),Object.defineProperty(e,"moYrDt",{enumerable:!0,get:function(){return s.moYrDt}}),Object.defineProperty(e,"tmAP",{enumerable:!0,get:function(){return s.tmAP}}),Object.defineProperty(e,"tmUTC",{enumerable:!0,get:function(){return s.tmUTC}}),Object.defineProperty(e,"monNm",{enumerable:!0,get:function(){return s.monNm}}),Object.defineProperty(e,"tN",{enumerable:!0,get:function(){return s.tN}}),Object.defineProperty(e,"addZ",{enumerable:!0,get:function(){return s.addZ}}),Object.defineProperty(e,"timeStandard",{enumerable:!0,get:function(){return s.timeStandard}}),Object.defineProperty(e,"dateStandard",{enumerable:!0,get:function(){return s.dateStandard}}),Object.defineProperty(e,"thisYear",{enumerable:!0,get:function(){return s.thisYear}});const c=n(794);Object.defineProperty(e,"objSort",{enumerable:!0,get:function(){return c.objSort}}),Object.defineProperty(e,"objLen",{enumerable:!0,get:function(){return c.objLen}}),Object.defineProperty(e,"objNestValueCount",{enumerable:!0,get:function(){return c.objNestValueCount}}),Object.defineProperty(e,"restoreObj",{enumerable:!0,get:function(){return c.restoreObj}}),Object.defineProperty(e,"restoreObjStr",{enumerable:!0,get:function(){return c.restoreObjStr}}),Object.defineProperty(e,"storeObj",{enumerable:!0,get:function(){return c.storeObj}}),Object.defineProperty(e,"storeObjStr",{enumerable:!0,get:function(){return c.storeObjStr}}),Object.defineProperty(e,"objSortSimple",{enumerable:!0,get:function(){return c.objSortSimple}})})();var a=t;for(var i in o)a[i]=o[i];o.__esModule&&Object.defineProperty(a,"__esModule",{value:!0})})()}};const t={};function r(n){const o=t[n];if(void 0!==o)return o.exports;const a=t[n]={exports:{}};return e[n](a,a.exports,r),a.exports}r.m=e,r.d=(e,t)=>{for(var n in t)r.o(t,n)&&!r.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},r.f={},r.e=e=>{const t=[];return r.f.require(e,t),Promise.all(t)},r.u=e=>({520:"engine-litert",924:"engine-wllama"}[e]+".node.min.js"),r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r.r=e=>{Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},(()=>{const e={792:1};r.f.require=(t,n)=>{if(!e[t]){const n=require("./"+r.u(t));e[t]||(t=>{const n=t.modules,o=t.ids,a=t.runtime;for(var i in n)r.o(n,i)&&(r.m[i]=n[i]);a&&a(r);for(var s=0;s<o.length;s++)e[o[s]]=1})(n)}}})();let n={};(()=>{"use strict";var e,t,o,a,i,s,c,l;let u;r.r(n),r.d(n,{BuiltinTool:()=>c,ChatModelId:()=>s,ChatStatus:()=>t,LlmBackend:()=>a,LlmPhase:()=>i,LlmRole:()=>e,LlmStatus:()=>o,WebSearchProvider:()=>l,builtinTools:()=>Ft,calculateTool:()=>ft,clearModelCache:()=>tt,createChat:()=>Ke,currencyTool:()=>At,describeImages:()=>dt,describeModelId:()=>ot,describeTranslated:()=>gt,imageReplyTokens:()=>128,preloadModel:()=>Xe,webSearchTool:()=>zt}),function(e){e.system="system",e.user="user",e.assistant="assistant"}(e||(e={})),function(e){e[e.online=0]="online",e[e.away=1]="away",e[e.offline=2]="offline"}(t||(t={})),function(e){e[e.idle=0]="idle",e[e.downloading=1]="downloading",e[e.ready=2]="ready",e[e.error=3]="error",e[e.unsupported=4]="unsupported"}(o||(o={})),function(e){e.cpu="cpu",e.gpu="gpu",e.none="none"}(a||(a={})),function(e){e.download="download",e.load="load"}(i||(i={})),function(e){e.qwen3_vl_2b="qwen3-vl-2b",e.qwen3_vl_2b_instruct="qwen3-vl-2b-instruct",e.qwen3_vl_2b_instruct_q3="qwen3-vl-2b-instruct-q3",e.gemma4_e2b="gemma4-e2b",e.gemma4_e2b_limited="gemma4-e2b-limited"}(s||(s={})),function(e){e.websearch="websearch",e.calculate="calculate",e.currency="currency"}(c||(c={})),function(e){e.wikipedia="wikipedia",e.duckduckgo="duckduckgo"}(l||(l={}));const d=[{id:s.qwen3_vl_2b,reasoning:!0,cpu:{repo:"Qwen/Qwen3-VL-2B-Thinking-GGUF",file:"Qwen3VL-2B-Thinking-Q4_K_M.gguf",mmproj:{file:"mmproj-Qwen3VL-2B-Thinking-Q8_0.gguf"}}},{id:s.qwen3_vl_2b_instruct,reasoning:!1,cpu:{repo:"unsloth/Qwen3-VL-2B-Instruct-GGUF",file:"Qwen3-VL-2B-Instruct-Q4_K_M.gguf",mmproj:{repo:"Qwen/Qwen3-VL-2B-Instruct-GGUF",file:"mmproj-Qwen3VL-2B-Instruct-Q8_0.gguf"}}},{id:s.qwen3_vl_2b_instruct_q3,reasoning:!1,cpu:{repo:"unsloth/Qwen3-VL-2B-Instruct-GGUF",file:"Qwen3-VL-2B-Instruct-Q3_K_M.gguf",mmproj:{repo:"Qwen/Qwen3-VL-2B-Instruct-GGUF",file:"mmproj-Qwen3VL-2B-Instruct-Q8_0.gguf"}}},{id:s.gemma4_e2b,reasoning:!0,litert:{repo:"litert-community/gemma-4-E2B-it-litert-lm",file:"gemma-4-E2B-it.litertlm",vision:!0,audio:!0}},{id:s.gemma4_e2b_limited,reasoning:!0,litert:{repo:"litert-community/gemma-4-E2B-it-litert-lm",file:"gemma-4-E2B-it-gpu.litertlm",vision:!1,audio:!1}}],g=e=>{const t=e??("undefined"==typeof navigator?void 0:navigator);if(!t)return!1;if("boolean"==typeof t.userAgentData?.mobile)return t.userAgentData.mobile;const r=t.userAgent||"";return/Android|iPhone|iPad|iPod|Mobile/i.test(r)||/Macintosh/.test(r)&&t.maxTouchPoints>1},m=(e,t=g())=>e==s.gemma4_e2b&&t?s.gemma4_e2b_limited:e,p=e=>e?d.find(t=>t.id==e):void 0,f=async()=>{const e="undefined"==typeof navigator?void 0:navigator.gpu;if(!e)return!1;let t;try{return!!await Promise.race([e.requestAdapter({powerPreference:"high-performance"}),new Promise(e=>{t=setTimeout(()=>e(void 0),1500)})])}catch{return!1}finally{t&&clearTimeout(t)}},h=async e=>p(m(e??await(async()=>(u||(u=(async()=>await f()?m(s.gemma4_e2b):s.qwen3_vl_2b)()),await u))())),y=e=>!!e.cpu?.mmproj||!0===e.litert?.vision,w=e=>!!e.cpu?.mmproj?.audio||!0===e.litert?.audio,b=require("node:path"),v=()=>{return e=(0,b.join)(__dirname,"../assets/wllama"),{wasm:(0,b.join)(e,"wllama.wasm"),compatWasm:(0,b.join)(e,"compat/wllama.wasm"),compatWorker:(0,b.join)(e,"compat/wllama.js")};var e},x=()=>{return e=(0,b.join)(__dirname,"../assets/litert"),{script:(0,b.join)(e,"litertlm_wasm_internal.js"),wasm:(0,b.join)(e,"litertlm_wasm_internal.wasm")};var e},M={width:384,height:384},j=async e=>{if(!e.startsWith("data:"))return await(await fetch(e)).arrayBuffer();const t=e.indexOf(","),r=t>=0?e.slice(0,t):"";if(t<0)throw new Error("Invalid image data");if(!r.includes(";base64"))return await(await fetch(e)).arrayBuffer();const n=atob(e.slice(t+1)),o=new Uint8Array(n.length);for(let e=0;e<n.length;e++)o[e]=n.charCodeAt(e);return o.buffer},k=async(e,t,r=128)=>{if(!e||"function"!=typeof fetch||"function"!=typeof createImageBitmap)return e;try{const n=await fetch(e),o=await createImageBitmap(await n.blob()),a=t??((e,t,r=128)=>{const n=e/Math.max(1,t);let o=32,a=32,i=1/0,s=1/0;for(let e=1;e<=r;e++){const t=Math.ceil(r/e),c=Math.floor((r+8)/e);for(let r=t;r<=c;r++){const t=r*e,c=Math.abs(r/e-n);(c<i-1e-9||Math.abs(c-i)<=1e-9&&t<s)&&(o=32*r,a=32*e,i=c,s=t)}}return{width:o,height:a}})(o.width,o.height,r),i=o.width/Math.max(1,o.height),s=a.width/a.height,c=Math.min(o.width,i>s?o.height*s:o.width),l=Math.min(o.height,i>s?o.height:o.width/s),u=(o.width-c)/2,d=(o.height-l)/2,g=((e,t)=>{if("undefined"!=typeof OffscreenCanvas)return new OffscreenCanvas(e,t);if("undefined"==typeof document)return;const r=document.createElement("canvas");return r.width=e,r.height=t,r})(a.width,a.height),m=g?g.getContext("2d"):null;if(!g||!m||o.width<1||o.height<1)return o.close(),e;if(m.drawImage(o,u,d,c,l,0,0,a.width,a.height),o.close(),(e=>"undefined"!=typeof OffscreenCanvas&&e instanceof OffscreenCanvas)(g)){const t=await g.convertToBlob({type:"image/jpeg",quality:.85});return await(e=>new Promise(t=>{if("undefined"==typeof FileReader)return void t("");const r=new FileReader;r.onerror=()=>t(""),r.onload=()=>t(`${r.result}`),r.readAsDataURL(e)}))(t)||e}return g.toDataURL("image/jpeg",.85)}catch{return e}};var T=r(69);const P={maxReplyTokens:250,maxThinkingTokens:128,maxReasoningTokens:320,maxImages:2,imageTokens:128,maxAudio:1,maxContentLength:1e3,promptCharBudget:1e4,maxThreads:32},_=(e,t,r)=>"number"==typeof e&&Number.isFinite(e)&&e>=r?Math.floor(e):t,S=(e={},t=!1)=>{const r=P;return{maxReplyTokens:_(e.maxReplyTokens,r.maxReplyTokens,1),maxThinkingTokens:_(e.maxThinkingTokens,r.maxThinkingTokens,1),maxReasoningTokens:_(e.maxReasoningTokens,t?1200:r.maxReasoningTokens,1),maxImages:_(e.maxImages,r.maxImages,0),imageTokens:_(e.imageTokens,r.imageTokens,1),maxAudio:_(e.maxAudio,r.maxAudio,0),maxContentLength:_(e.maxContentLength,r.maxContentLength,1),promptCharBudget:_(e.promptCharBudget,r.promptCharBudget,1),maxThreads:_(e.maxThreads,r.maxThreads,1)}},O=(e,t,r=.7)=>({stream:!0,temperature:r,max_tokens:t?e.maxReasoningTokens:e.maxReplyTokens}),D=(e,t)=>`https://huggingface.co/${e}/resolve/main/${t}`,C=e=>Number(e.headers.get("content-length"))||0,N=(e,t)=>e.some(e=>Array.isArray(e.content)&&e.content.some(e=>e.type==t)),E=e=>N(e,"image"),L=e=>N(e,"audio"),A=["<|channel>thought\n","<|channel>thought","..."],R=["<channel|>","..."],$=(e,t,r)=>t.length||r.length?[...e?[{type:"text",text:e}]:[],...t.map(e=>({type:"image",url:e})),...r.map(e=>({type:"audio",url:e}))]:e,q=e=>"string"==typeof e?e?[{type:"text",text:e}]:[]:e,U=(e,t)=>{if("string"==typeof e&&"string"==typeof t)return`${e}\n${t}`;const r=[];for(const n of[...q(e),{type:"text",text:"\n"},...q(t)]){const e=r[r.length-1];"text"==n.type&&"text"==e?.type?e.text+=n.text:r.push(n)}return r},I=g()?3e6:3e5,z=Math.max(I,84e4);class F extends Error{}const W=async(e,t,r)=>{let n;try{return await Promise.race([e,new Promise((e,o)=>{n=setTimeout(()=>o(new F(r)),t)})])}finally{n&&clearTimeout(n)}},B=e=>{try{Promise.resolve(e.next?.()).catch(()=>{}).finally(()=>{try{Promise.resolve(e.return?.()).catch(()=>{})}catch{}})}catch{}},V=async({model:e,logging:t,onReason:r,onText:n,onSpeed:o,start:a,stopped:i,firstTimeoutMs:s=I,idleTimeoutMs:c=3e4,onStall:l})=>{let u="",d="",g="",m=!1,p=0,f=0;const h=((e,t)=>{let r="",n=!1;const o=(e,t)=>{let r=-1,n="";for(const o of t){const t=e.indexOf(o);t>=0&&(r<0||t<r)&&(r=t,n=o)}return{at:r,tag:n}},a=(e,t)=>{let r="";for(const n of t)for(let t=Math.min(e.length,n.length-1);t>r.length;t--)if(e.endsWith(n.slice(0,t))){r=e.slice(e.length-t);break}return r};return{feed:i=>{let s=r+i;for(r="";s;){if(n){const{at:t,tag:i}=o(s,R);if(t>=0){t&&e(s.slice(0,t)),s=s.slice(t+i.length),n=!1;continue}const c=a(s,R);e(s.slice(0,s.length-c.length)),r=c;break}{const{at:e,tag:i}=o(s,A);if(e>=0){e&&t(s.slice(0,e)),s=s.slice(e+i.length),s.startsWith("\n")&&(s=s.slice(1)),n=!0;continue}const c=a(s,A);t(s.slice(0,s.length-c.length)),r=c;break}}},flush:()=>{r&&(n?e(r):t(r),r="")}}})(e=>{d+=e,r(e)},e=>{u+=e,n(e)});try{const e=a();Promise.resolve(e).catch(()=>{});const n=(await W(e,s,"Model did not start"))[Symbol.asyncIterator]();for(;;){if(i()){B(n);break}let e;try{const t=n.next();Promise.resolve(t).catch(()=>{}),e=await W(t,m?c:s,m?"Model stopped responding":"Model did not reply")}catch(e){if(e instanceof F&&(u||d)){l?.(),B(n),t&&console.log("Local chat stalled",e);break}throw e}if(e.done)break;m=!0;const a=e.value?.choices?.[0],y=a?.delta,w="string"==typeof y?.reasoning_content?y.reasoning_content:"string"==typeof y?.reasoning?y.reasoning:"";if(a?.finish_reason&&(g=a.finish_reason),w&&(d+=w,r(w)),y?.content&&h.feed(y.content),w||y?.content){const e=performance.now();p||(f=e),p+=1,p>1&&e>f&&o?.((0,T.rNum)(1e3*p/(e-f)))}}h.flush()}catch(e){if(t&&console.log("Local chat failed",e),e instanceof F&&!i())throw e}const y=i()?void 0:u||void 0;return t&&(console.log("Local chat reply",e.id,y?"****":""),console.log("Local chat finish",e.id,g||"none",u.length,d.length)),y},G=async({model:t,params:r,start:n,stopped:o,onStall:a})=>{const i=await(async(e,t,r=128)=>{const n=[];for(const o of e){if("string"==typeof o.content){n.push(o);continue}const e=[];for(const n of o.content)e.push("image"==n.type?{type:"image",url:await k(n.url,t,r)}:n);n.push({role:"user",content:e})}return n})(((t,r=P)=>{const n=r.maxContentLength,o=t.filter(t=>"string"==typeof t.content&&!!t.content.trim()||!(t.role!=e.user||!t.images?.length&&!t.audio?.length)),a=[],i=[];let s=0,c=r.maxImages,l=r.maxAudio;for(let t=o.length-1;t>=0;t--){const u=o[t],d=("string"==typeof u.content?u.content:"").slice(0,n),g=u.role==e.user?(u.images||[]).filter(e=>"string"==typeof e&&!!e).slice(0,Math.max(0,c)):[],m=u.role==e.user?(u.audio||[]).filter(e=>"string"==typeof e&&!!e).slice(0,Math.max(0,l)):[];if(d||g.length||m.length){if(d&&s+d.length>r.promptCharBudget)break;s+=d.length,c-=g.length,l-=m.length,u.role==e.system?a.unshift(d):u.role==e.assistant?i.unshift({role:"assistant",content:d}):i.unshift({role:"user",content:$(d,g,m)})}}for(;i.length&&"user"!=i[0].role;)i.shift();const u=[];for(const e of i){const t=u[u.length-1];"assistant"==t?.role&&"assistant"==e.role?t.content=`${t.content}\n${e.content}`:"user"==t?.role&&"user"==e.role?t.content=U(t.content,e.content):"assistant"==e.role?u.push({role:"assistant",content:e.content}):u.push({role:"user",content:e.content})}const d=a.join("\n\n"),g=[];return d&&g.push({role:"system",content:d}),g.push(...u),g})(r.messages,r.limits),t.litert?M:void 0,r.limits.imageTokens);return r.logging&&((e,t)=>{console.log("Local chat call",e.id,t.map(({role:e,content:t})=>({role:e,content:"****",...Array.isArray(t)?{images:t.filter(e=>"image"==e.type).length,audio:t.filter(e=>"audio"==e.type).length}:{}})))})(t,i),await V({model:t,logging:r.logging,onReason:r.onReason,onText:r.onText,onSpeed:r.onSpeed,start:()=>n(i),stopped:o,onStall:a,firstTimeoutMs:E(i)?z:I})},Q=33554432,Y=new Map;let H=!1;const J=e=>{const t=(e.split("/").pop()||"model").replace(/[^\w.-]+/g,"_");let r=0;for(let t=0;t<e.length;t++)r=31*r+e.charCodeAt(t)>>>0;return`${r.toString(16)}-${t}`},Z=e=>{const t=/^part-(\d+)$/.exec(e);return t?Number(t[1]):-1},K=async()=>{if(!H)if("undefined"!=typeof navigator&&navigator.storage?.getDirectory)try{return await navigator.storage.getDirectory()}catch{return}else H=!0},X=async(e,t)=>{try{return await e.getDirectoryHandle(t)}catch{return}},ee=async e=>{if(e)try{const t=await e.getFile(),r=JSON.parse(await t.text());return{total:Number(r.total)||0,etag:`${r.etag||""}`,complete:!0===r.complete}}catch{return}},te=async(e,t)=>{try{const r=await e.getFileHandle("meta.json",{create:!0}),n=await r.createWritable();await n.write(JSON.stringify(t)),await n.close()}catch{}},re=async function*(e){for await(const t of e)yield t},ne=async e=>{try{for await(const[t,r]of re(e))"file"==r.kind&&Z(t)>=0&&await e.removeEntry(t).catch(()=>{})}catch{}},oe=async(e,t)=>{try{const r=await(await e.getFileHandle(t)).getFile(),n=await ee(await e.getFileHandle(`${t}.json`).catch(()=>{}));if(!n)return;return{file:r,size:r.size,total:n.total,etag:n.etag,complete:n.total?r.size>=n.total:!0===n.complete}}catch{return}},ae=async(e,t)=>{const r=await X(e,t);if(r){const e=await(async e=>await ee(await e.getFileHandle("meta.json").catch(()=>{})))(r),t=await(async e=>{const t=[];try{for await(const[r,n]of re(e)){const e=Z(r);if("file"!=n.kind||e<0)continue;const o=await n.getFile();t.push({part:{start:e,size:o.size},file:o})}}catch{return}const r=(e=>{const t=[];let r=0;for(const n of[...e].sort((e,t)=>e.start-t.start))if(n.size){if(n.start!=r)break;t.push(n),r+=n.size}return t})(t.map(e=>e.part)),n=new Set(r.map(e=>e.start)),o=t.filter(e=>n.has(e.part.start)).sort((e,t)=>e.part.start-t.part.start).map(e=>e.file);if(o.length)return{file:1==o.length?o[0]:new Blob(o),size:r.reduce((e,t)=>e+t.size,0)}})(r),n=e?.total||0,o=t?.size??0,a=t?.file??new Blob;return{file:n&&o>n?a.slice(0,n):a,size:o,total:n,etag:e?.etag||"",complete:n?o>=n:!0===e?.complete}}return await oe(e,t)},ie=(e,t)=>{const r=e.headers.get("content-range"),n=/bytes (\d+)-/.exec(r||""),o=/\/(\d+)\s*$/.exec(r||""),a=e.headers.get("etag")||"";if(206==e.status){const e=n?Number(n[1]):t.size,r=o?Number(o[1]):t.total;if(e!=t.size)return;if(t.total&&r&&t.total!=r)return;if(t.etag&&a&&t.etag!=a)return;return{start:e,total:r||t.total,etag:a||t.etag}}if(!t.etag||!a||t.etag==a)return{start:0,total:C(e)||t.total,etag:a||t.etag}},se=async({dir:e,start:t,skip:r,total:n,body:o,onProgress:a,onChunk:s})=>{let c,l=t,u=0,d=r;const g=async()=>{const t=await e.getFileHandle((e=>`part-${e}`)(l),{create:!0});c=await t.createWritable(),u=0},m=async()=>{const e=c;c=void 0,e&&await e.close().catch(()=>{})};try{const e=o.getReader();for(;;){const{done:r,value:o}=await e.read();if(r)break;s();let p=0;for(d&&(p=Math.min(d,o.byteLength),d-=p);p<o.byteLength;){c||await g();const e=Math.min(Q-u,o.byteLength-p);await c.write({type:"write",position:u,data:o.subarray(p,p+e)}),p+=e,u+=e,l+=e,u==Q&&await m()}l>t&&a(n?l/n:0,i.download)}await m()}catch(e){throw await m(),e}return l},ce=e=>["NotAllowedError","NotSupportedError"].includes(e?.name||""),le=e=>{const t=async()=>{const t=await K();if(t)try{return await t.getDirectoryHandle(e,{create:!0})}catch{return}};return{stored:async e=>{const r=await t();return r?await ae(r,J(e)):void 0},download:async({url:r,signal:n,onProgress:o})=>{const a=`${e}|${r}`,s=Y.get(a);if(s)return await s;const c=await t();if(!c)return;const l=(async(e,t,r,n)=>{const o=J(t),a=await oe(e,o);if(a?.complete)return a;let s=await X(e,o);s||(await e.removeEntry(o).catch(()=>{}),await e.removeEntry(`${o}.json`).catch(()=>{}),s=await e.getDirectoryHandle(o,{create:!0}));let c=0,l=0;for(;;){if(r?.aborted)throw new Error("Cancelled");const a=await ae(e,o);if(a?.complete)return a;const u=a?.size??0,d=a?.total||0,g=a?.etag||"";if(u>c)c=u,l=0;else if(++l>4)throw new Error("Model download failed");u&&d&&n(u/d,i.download);const m=d?Math.min(u+Q,d)-1:u+Q-1,p=new AbortController,f=()=>p.abort(),h={size:u,total:d,etag:g};let y,w=setTimeout(f,3e4);r?.addEventListener("abort",f,{once:!0});try{if(y=await fetch(t,{signal:p.signal,headers:{Range:`bytes=${u}-${m}`}}),416==y.status){if(await(y.body?.cancel().catch(()=>{})),d&&u>=d){await te(s,{total:d,etag:g,complete:!0});continue}await ne(s),await te(s,{total:0,etag:"",complete:!1});continue}if(!y.ok||!y.body)throw await(y.body?.cancel().catch(()=>{})),new Error("Model download failed");const r=ie(y,h);if(!r){await y.body.cancel().catch(()=>{}),await ne(s),await te(s,{total:0,etag:"",complete:!1});continue}await te(s,{total:r.total,etag:r.etag,complete:!1});const a=0==r.start?u:0,i=await se({dir:s,start:r.start+a,skip:a,total:r.total,body:y.body,onProgress:n,onChunk:()=>{clearTimeout(w),w=setTimeout(f,3e4)}});if(!r.total){await te(s,{total:i,etag:r.etag,complete:!0});const t=await ae(e,o);if(t)return t}}catch(e){if(r?.aborted)throw new Error("Cancelled");if(e instanceof DOMException&&["QuotaExceededError","NotAllowedError","NotSupportedError","InvalidStateError","TypeMismatchError","SecurityError"].includes(e.name))throw e;await new Promise(e=>setTimeout(e,250+500*l))}finally{clearTimeout(w),r?.removeEventListener("abort",f)}}})(c,r,n,o).finally(()=>{Y.delete(a)});return Y.set(a,l),await l},remove:async e=>{const r=await t();r&&await(async(e,t)=>{await e.removeEntry(t,{recursive:!0}).catch(()=>{}),await e.removeEntry(`${t}.json`).catch(()=>{})})(r,J(e))},purge:async()=>{const t=await K();t&&await t.removeEntry(e,{recursive:!0}).catch(()=>{})}}},ue=(e,...t)=>{!0===e&&console.log(...t)},de="litertlm-models",ge=le("litert-store"),me={num_output_candidates:1,wait_for_weight_uploads:!0,num_decode_steps_per_sync:1,sequence_batch_size:0,supported_lora_ranks:[],max_top_k:40,enable_decode_logits:!1,enable_external_embeddings:!1,use_submodel:!1,use_autosized_ringbuffers:!0};let pe=!1,fe=0;const he=new WeakSet;let ye=!1,we=0;const be=(...e)=>{pe&&console.log(...e)},ve=(...e)=>{pe&&console.error(...e)},xe=e=>e.replace(/<\|channel>thought\n?[\s\S]*?<channel\|>/g,"").replace(/<\|channel>thought[\s\S]*$/,"").trim(),Me=async()=>{const e=performance.now(),t=e-we;if(we=e,!ye)return;const r=Math.round((n=t,Math.min(40,Math.max(0,n*(1/.7-1)))));var n;r<1||(await new Promise(e=>setTimeout(e,r)),we=performance.now())},je=()=>{ye=!0,we=performance.now()},ke=async()=>{try{if("undefined"==typeof caches)return;return await caches.open(de)}catch{return}},Te=new Map,Pe=(e,t,r)=>{let n=0;return e.pipeThrough(new TransformStream({transform:(e,o)=>{n+=e.byteLength,r(t?n/t:0,i.download),o.enqueue(e)}}))},_e=async(e,t=!0)=>{const r=[];for(const n of e){if("string"==typeof n.content){r.push({role:n.role,content:n.content});continue}const e=[];for(const r of n.content)"text"!=r.type?t?e.push({type:r.type,data:await j(r.url)}):e.push({type:"text",text:`[${r.type}]`}):e.push({type:"text",text:r.text});r.push({role:n.role,content:e})}return r},Se=(e,t)=>{if(e.role!=t.role)return!1;if("string"==typeof e.content||"string"==typeof t.content)return"string"==typeof e.content&&"string"==typeof t.content&&xe(e.content)==xe(t.content);if(e.content.length!=t.content.length)return!1;for(let r=0;r<e.content.length;r++){const n=e.content[r],o=t.content[r];if(n.type!=o.type)return!1;if("text"==n.type&&"text"==o.type){if(xe(n.text)!=xe(o.text))return!1}else{if("text"==n.type||"text"==o.type)return!1;if(!!n.url!=!!o.url)return!1}}return!0},Oe=async function*({engine:e,mod:t,params:r,messages:n,session:o}){const a=n[n.length-1],i=O(r.limits,r.reasoning,r.temperature);if("user"!=a?.role)throw new Error("No user turn");const s=n.slice(0,-1),c=(await _e([a]))[0];if(!c)throw new Error("Empty prompt");const l=o.reasoning==r.reasoning&&o.maxTokens==i.max_tokens,u=!!o.conversation&&((e,t)=>{const r="system"==e[0]?.role?e[0]:void 0,n="system"==t[0]?.role?t[0]:void 0;if(!r!=!n)return!1;if(r&&n&&!Se(r,n))return!1;const o=r?e.slice(1):e,a=n?t.slice(1):t;if(!a.length||a.length>o.length)return!1;const i=o.length-a.length;for(let e=0;e<a.length;e++)if(!Se(o[i+e],a[e]))return!1;return!0})(o.sent,s);let d;if(l&&u&&o.conversation)ue(pe,"LiteRT conversation reused",o.sent.length),d=o.conversation;else{const n=await _e(s,!1);o.conversation=void 0,o.sent=[];const a=performance.now();d=await e.createConversation({sessionConfig:{maxOutputTokens:i.max_tokens,samplerParams:{type:t.SamplerType.TOP_K,temperature:i.temperature,k:40,p:.95}},preface:{...n.length?{messages:n}:{},extra_context:{enable_thinking:r.reasoning}},prefillPrefaceOnInit:n.length>0}),ue(pe,"LiteRT conversation created",n.length,Math.round(performance.now()-a),"flags",l,"history",u),o.conversation=d,o.reasoning=r.reasoning,o.maxTokens=i.max_tokens,o.sent=[...s]}o.sent.push(a);let g,m=!1,p=!0,f="";const h=()=>{g&&g.cancel().catch(()=>{});try{Promise.resolve(d.cancel()).catch(()=>{})}catch{}};r.signal?.addEventListener("abort",h,{once:!0});try{if(r.signal?.aborted)return;const e=d.sendMessageStreaming(c).getReader();for(g=e;;){const t=performance.now(),{done:n,value:o}=await e.read().catch(e=>{if(r.signal?.aborted)return{done:!0,value:void 0};throw e}),a=performance.now()-t;if(n)break;const i=p;p=!1,i&&(ue(pe,"LiteRT first chunk",Math.round(a)),je());const s={};let c="string"==typeof o.content?o.content:"";if(Array.isArray(o.content))for(const e of o.content)"text"==e.type&&(c+=e.text);c&&(s.content=c,f+=c);const l=o.channels?.thought;l&&(s.reasoning=l),(s.content||s.reasoning)&&(yield{choices:[{delta:s}]})}m=!0}finally{ye=!1,r.signal?.removeEventListener("abort",h),m&&f?o.sent.push({role:"assistant",content:f}):(o.conversation=void 0,o.sent=[])}},De={backend:a.gpu,startLLM:async({model:e,limits:t,onProgress:n,signal:o,logging:s})=>{pe=!0===s;const c=e.litert;if(!c)throw new Error("Model has no LiteRT artifact");const l=g()?16384:32768,u=await r.e(520).then(()=>r(507)),d=globalThis,m=d.Module;d.Module={print:be,printErr:ve};try{await u.getOrLoadGlobalLiteRtLm(x().script)}finally{d.Module=m}if(o?.aborted)throw new Error("Cancelled");const p=u.getGlobalLiteRtLm(),f=p.liteRtLmWasm;if(await p.setupDefaultWebGpuDevice(),o?.aborted)throw new Error("Cancelled");const h=f.preinitializedWebGPUDevice;if(!h)throw new Error("No WebGPU device");if(!he.has(h)){const e=(({device:e,pace:t})=>new Proxy(e,{get:(e,r)=>{if("createBuffer"==r)return(...n)=>{const o=Reflect.get(e,r,e).apply(e,n),a=o.mapAsync;try{o.mapAsync=async(...e)=>{await a.apply(o,e),await t()}}catch{}return o};const n=Reflect.get(e,r,e);return"function"==typeof n?n.bind(e):n}}))({device:h,pace:Me});he.add(h),he.add(e),f.preinitializedWebGPUDevice=e}const y=D(c.repo,c.file),w=await ke();let b;const v=w?await w.match(y):void 0;if(v?.body)b=v.body;else{const e=await ge.stored(y);e?.complete&&(b=e.file.stream())}if(!b){const e=await ge.download({url:y,signal:o,onProgress:n}).catch(e=>{if(o?.aborted)throw new Error("Cancelled");if(!ce(e))throw e;s&&console.log("Local model store failed",e)});e&&(b=e.file.stream())}if(!b&&w)try{await(async(e,t,r,n)=>{const o=Te.get(e);if(o)return await o;const a=(async()=>{const o=await fetch(e,{signal:r});if(!o.ok||!o.body)throw new Error("Model download failed");const a=C(o),i=Pe(o.body,a,n);await t.put(e,new Response(i,{headers:{"content-type":"application/octet-stream",...a?{"content-length":`${a}`}:{}}}))})().finally(()=>{Te.delete(e)});return Te.set(e,a),await a})(y,w,o,n);const e=await w.match(y);e?.body&&(b=e.body)}catch(e){if(o?.aborted)throw new Error("Cancelled");s&&console.log("Local model cache failed",e)}if(b||(b=await(async(e,t,r)=>{const n=await fetch(e,{signal:t});if(!n.ok||!n.body)throw new Error("Model download failed");return Pe(n.body,C(n),r)})(y,o,n)),o?.aborted)throw new Error("Cancelled");n(1,i.load);const M=await u.Engine.create((({model:e,limits:t,contextSize:r,source:n,mod:o})=>{const a=e.litert;return{model:n,mainExecutorSettings:{maxNumTokens:r,...a?.vision?{maxNumImages:Math.max(1,t.maxImages)}:{},backendConfig:me},...a?.vision?{visionBackend:o.Backend.GPU,maxVisionTokensPerImage:70,minVisionTokensPerImage:70}:{},...a?.audio?{audioBackend:o.Backend.CPU}:{}}})({model:e,limits:t,contextSize:l,source:b,mod:u}));fe+=1;const j=()=>{fe=Math.max(0,fe-1),fe||(e=>{try{const t=e.getGlobalLiteRtLm().liteRtLmWasm,r=t.preinitializedWebGPUDevice;t.preinitializedWebGPUDevice=void 0,t.WebGPU&&(t.WebGPU.preinitializedDeviceId=void 0),r?.destroy?.()}catch{}try{e.unloadLiteRtLm()}catch{}})(u)};try{const e=performance.now(),t=await M.createConversation();await t.delete(),ue(pe,"LiteRT conversation warm-up",Math.round(performance.now()-e))}catch(e){ue(pe,"LiteRT conversation warm-up failed",e)}if(o?.aborted)throw await M.delete(),j(),new Error("Cancelled");const k={sent:[],reasoning:!1,maxTokens:0};return{model:e,backend:a.gpu,contextSize:l,chat:t=>(async({engine:e,model:t,mod:r,params:n,session:o})=>{pe=!0===n.logging;const a=()=>{try{o.conversation?.cancel()}catch{}o.conversation=void 0,o.sent=[]};try{return await G({model:t,params:n,stopped:()=>!!n.signal?.aborted,onStall:a,start:async a=>{if(n.signal?.aborted)throw new Error("Cancelled");if(E(a)&&!t.litert?.vision)throw new Error("Model does not accept images");if(L(a)&&!t.litert?.audio)throw new Error("Model does not accept audio");return Oe({engine:e,mod:r,params:n,messages:a,session:o})}})}catch(e){throw a(),e}})({engine:M,model:e,mod:u,params:t,session:k}),unload:async()=>{const e=k.conversation;k.conversation=void 0,k.sent=[];try{await(e?.delete())}catch{}await M.delete(),j()}}},cached:async e=>{const t=e.litert;if(!t)return!1;const r=D(t.repo,t.file),[n,o]=await Promise.all([ke(),ge.stored(r)]);if(o?.complete)return!0;try{return!(!n||!await n.match(r))}catch{return!1}},purge:async()=>{try{await ge.purge(),"undefined"!=typeof caches&&await caches.delete(de)}catch{}}},Ce=le("wllama-store"),Ne=[s.qwen3_vl_2b_instruct,s.qwen3_vl_2b_instruct_q3],Ee=e=>e.cpu?.mmproj&&Ne.includes(e.id)?{image_min_tokens:16,image_max_tokens:128}:{};let Le,Ae,Re="",$e=!1;const qe=e=>`${e.wasm}|${e.compatWasm}|${e.compatWorker}`,Ue=e=>{const t=v();return{wasm:e?.wasm||t.wasm,compatWasm:e?.compatWasm||t.compatWasm,compatWorker:e?.compatWorker||t.compatWorker}},Ie=e=>{const t=e=>(...t)=>{$e&&("string"==typeof t[0]&&t[0].includes("ggml_webgpu: Failed to get an adapter")||e(...t))};return{...e,log:t(e.log),warn:t(e.warn),error:t(e.error)}},ze=async()=>{if(Le)return Le;const e=await r.e(924).then(()=>r(577)),t=Ae||Ue(),n=new e.Wllama({default:t.wasm},{logger:Ie(e.LoggerWithoutDebug)});return Ae||(Ae=t,Re=qe(t)),n.setCompat({wasm:t.compatWasm,worker:t.compatWorker}),Le=n,n},Fe=async()=>{const e=Le;Le=void 0;try{await(e?.exit())}catch{}},We=(e,t)=>e.name.includes(t)||!!e.metadata?.originalURL?.includes(t),Be=e=>{const t=e.cpu;return t?[{name:t.file,url:D(t.repo,t.file)},...t.mmproj?[{name:t.mmproj.file,url:D(t.mmproj.repo??t.repo,t.mmproj.file)}]:[]]:[]},Ve=async e=>{const t=Be(e);if(!t.length)return!1;for(const e of t){const t=await Ce.stored(e.url);if(!t?.complete)return!1}return!0},Ge=async(e,t)=>{const r=await e.cacheManager.list();return Be(t).every(e=>r.some(t=>We(t,e.name)))},Qe=async({model:e,signal:t,onProgress:r})=>{const n=Be(e),o=[];for(let e=0;e<n.length;e++){if(t?.aborted)throw new Error("Cancelled");const a=await Ce.download({url:n[e].url,signal:t,onProgress:(t,o)=>r((e+t)/n.length,o)});if(!a)return;o.push(a.file)}return o.length?o:void 0},Ye=async e=>{const t=[];for(const r of e){if("string"==typeof r.content){"system"==r.role?t.push({role:"system",content:r.content}):"assistant"==r.role?t.push({role:"assistant",content:r.content}):t.push({role:"user",content:r.content});continue}const e=[];for(const t of r.content)"text"==t.type?e.push({type:"text",text:t.text}):e.push({type:t.type,data:await j(t.url)});t.push({role:"user",content:e})}return t},He={backend:a.cpu,startLLM:async({model:e,limits:t,onProgress:r,signal:n,logging:o,assets:s})=>{$e=!0===o;const c=g()?4096:8192,l=e.cpu;if(!l)throw new Error("Model has no CPU artifact");const u=Ue(s),d=qe(u);Le&&d!=Re&&await Fe(),Ae=u,Re=d;const m="undefined"!=typeof navigator?navigator.hardwareConcurrency:0,p=Math.min((e=>{const t=e||4;return Math.max(1,t-Math.max(1,Math.floor(t/5)))})(m),t.maxThreads),f=await ze(),h=await Ve(e),y=l.mmproj?.file,w=D(l.repo,l.file),b=y?D(l.mmproj?.repo??l.repo,y):"";if(n?.aborted)throw await Fe(),new Error("Cancelled");if(!h&&y){const e=await f.cacheManager.list(),t=e.some(e=>We(e,l.file)),r=e.some(e=>We(e,y));t&&!r&&await f.cacheManager.deleteMany(e=>We(e,l.file))}const v={n_ctx:c,n_threads:p,n_parallel:1,warmup:!0,reasoning_budget_tokens:t.maxThinkingTokens,n_gpu_layers:0,jinja:!0,ctx_shift:!0,n_keep:Math.max(64,Math.round(c/16)),...Ee(e)};try{let t=h?await Qe({model:e,signal:n,onProgress:r}):void 0;t||h||await Ge(f,e).catch(()=>!1)||(t=await Qe({model:e,signal:n,onProgress:r}).catch(e=>{if(n?.aborted)throw new Error("Cancelled");if(!ce(e))throw e;o&&console.log("Local model store failed",e)})),t?(r(1,i.load),await f.loadModel(t,v)):await f.loadModelFromUrl(b?{url:w,mmprojUrl:b}:w,{...v,useCache:!0,signal:n,progressCallback:({loaded:e,total:t})=>{const n=t?e/t:0;r(n,n>=1?i.load:i.download)}})}catch(e){throw await Fe(),e}if(n?.aborted)throw await Fe(),new Error("Cancelled");const x=f.getLoadedContextInfo();if(!x.n_ctx)throw await Fe(),new Error("Failed to create model context");return ue(o,"CPU engine ready",e.id,"cores","undefined"!=typeof navigator?navigator.hardwareConcurrency:0,"isolated","undefined"!=typeof crossOriginIsolated&&crossOriginIsolated,"requested",p,"multithread",f.isMultithread(),"active",f.getNumThreads(),"context",x.n_ctx,"batch",x.n_batch,"ubatch",x.n_ubatch),{model:e,backend:a.cpu,contextSize:c,chat:t=>(async(e,t,r)=>{if($e=!0===r.logging,e.isModelLoaded())return await G({model:t,params:r,stopped:()=>!!r.signal?.aborted,start:async n=>{if(E(n)&&!e.supportInputModality("image"))throw new Error("Model does not accept images");if(L(n)&&!e.supportInputModality("audio"))throw new Error("Model does not accept audio");return await e.createChatCompletion({messages:await Ye(n),...O(r.limits,r.reasoning,r.temperature),...r.repeatPenalty?{penalty_repeat:r.repeatPenalty}:{},abortSignal:r.signal,...t.reasoning?{chat_template_kwargs:{enable_thinking:r.reasoning}}:{}})}})})(f,e,t),unload:async()=>{if(Le==f)await Fe();else try{await f.exit()}catch{}}}},cached:async e=>{try{return!!e.cpu&&(!!await Ve(e)||await Ge(await ze(),e))}catch{return!1}},purge:async()=>{try{await Ce.purge()}catch{}try{const e=await ze();await e.cacheManager.clear()}catch{}}},Je=((e={})=>{const t=e.engines?.cpu||He,r=e.engines?.litert||De,n=e.mobile||g,s=new Map,c=new Map,l=new Map,u=new Map,d=new Map,m=new Map,p=new Map,f=new Map,h=new Map;let y,w,b,v=o.idle;const x=n=>{if(e.backend!=a.none)return e.backend==a.cpu?n.cpu?t:void 0:e.backend==a.gpu?n.litert?r:void 0:n.litert&&"undefined"!=typeof navigator&&navigator.gpu&&"undefined"!=typeof WebAssembly?r:!n.cpu||"undefined"==typeof window&&"undefined"==typeof self&&"undefined"==typeof Worker||"undefined"==typeof WebAssembly?void 0:t},M=e=>e?s.get(e):y?s.get(y.id):void 0,j=e=>{v=e},k=async e=>{const t=s.get(e);t&&(s.delete(e),y?.id==e&&(y=[...s.values()].pop()?.model),s.size||c.size||j(o.idle),await t.unload())},T=(e,t,r)=>{const n={percent:Math.max(0,Math.min(1,t)),phase:r||i.download};d.set(e,n);for(const t of u.get(e)??[])t.report(n.percent,n.phase)},P=e=>{p.set(e,(p.get(e)??0)+1),m.get(e)?.abort(),m.delete(e);const t=c.get(e);t&&l.set(e,t),c.delete(e),u.delete(e),d.delete(e),f.set(e,o.idle),v!=o.downloading||c.size||s.size||j(o.idle)},_=(e,t,r)=>{const n=c.get(e);return n?new Promise(o=>{let a=!1;const i={report:t,settle:e=>{a||(a=!0,r?.removeEventListener("abort",s),o(e))}},s=()=>{((e,t)=>{const r=u.get(e);r&&u.set(e,r.filter(e=>e!=t)),queueMicrotask(()=>{!u.get(e)?.length&&c.has(e)&&P(e)})})(e,i),i.settle(!1)},l=u.get(e);l?l.push(i):u.set(e,[i]),r?.aborted?s():r?.addEventListener("abort",s,{once:!0}),n.attempt.then(i.settle,()=>i.settle(!1))}):Promise.resolve(!1)},S=async e=>{if(e)await k(e);else{for(const e of[...c.keys()])P(e);d.clear(),f.clear(),h.clear(),w=void 0,j(o.idle),await(async()=>{for(const e of[...s.keys()])await k(e)})()}};return{load:async({model:e,limits:t,assets:r,logging:a,signal:g,onProgress:b})=>{if(g?.aborted)return!1;if(s.has(e.id))return y=e,!0;if(c.has(e.id)){const t=d.get(e.id);return t&&b(t.percent,t.phase),await _(e.id,b,g)}const v=x(e);if(!v){const t="Model is not supported on this device";return w=t,h.set(e.id,t),f.set(e.id,o.unsupported),j(o.unsupported),!1}const M=[...c.values(),...l.values()].filter(e=>n()||x(e.model)?.backend==v.backend);for(const e of M)P(e.model.id);const S=(p.get(e.id)??0)+1;p.set(e.id,S);const O=(async()=>{if(await Promise.all(M.map(e=>e.attempt.catch(()=>!1))),S!=p.get(e.id))return!1;if(await(async()=>{try{if("undefined"==typeof navigator)return;await(navigator.storage?.persist?.())}catch{}})(),S!=p.get(e.id))return!1;if(await(async e=>{for(const[t,r]of[...s])(n()||r.backend==e)&&await k(t)})(v.backend),S!=p.get(e.id))return!1;const c=await v.cached(e);if(S!=p.get(e.id))return!1;w=void 0,h.delete(e.id),f.set(e.id,o.downloading),j(o.downloading),T(e.id,0,i.download),c&&T(e.id,1,i.load);const l=new AbortController;m.set(e.id,l);try{const n=await v.startLLM({model:e,limits:t,logging:a,signal:l.signal,assets:r,onProgress:(t,r)=>{S==p.get(e.id)&&T(e.id,t,r)}});return S!=p.get(e.id)||l.signal.aborted?(await n.unload(),!1):(s.set(e.id,n),y=e,w=void 0,h.delete(e.id),f.set(e.id,o.ready),j(o.ready),T(e.id,1,i.load),!0)}catch(t){if(S!=p.get(e.id))return!1;const r=`${t?.message||`${t}`}`;return w=r,h.set(e.id,r),f.set(e.id,o.error),j(o.error),a&&console.log("Local model failed",t),!1}finally{m.get(e.id)==l&&m.delete(e.id)}})();let D;const C=O.finally(()=>{l.get(e.id)==D&&l.delete(e.id),c.get(e.id)==D&&(c.delete(e.id),u.delete(e.id),d.delete(e.id))});return D={model:e,attempt:C},c.set(e.id,D),u.set(e.id,[]),await _(e.id,b,g)},chat:async e=>{if(!M(e.model))return;for(;b;)await b.catch(()=>{});const t=M(e.model);if(!t)return;y?.id!=t.model.id&&(y=t.model);const r=t.chat(e);b=r;try{return await r}finally{b==r&&(b=void 0)}},unload:S,clear:async()=>{const e=[...c.values(),...l.values()].map(e=>e.attempt);await S(),await Promise.all(e.map(e=>e.catch(()=>{}))),await Promise.all([t.purge(),r.purge()])},ready:e=>!!M(e),loading:e=>e?c.has(e):c.size>0,status:e=>M(e)?o.ready:e?c.has(e)?f.get(e)??o.downloading:h.has(e)?f.get(e)??o.error:o.idle:v,backend:e=>M(e)?.backend??a.none,error:e=>e?h.get(e):w,model:()=>y}})(),Ze=(e,r,n)=>{const a=m(r),i=e.status(a),s=p(a);return{...a?{model:a}:{},availability:i==o.ready?t.online:i==o.error||i==o.unsupported?t.offline:t.away,status:i,backend:e.backend(a),supportsImages:!!s&&y(s),supportsAudio:!!s&&w(s),ready:e.ready(a),loading:e.loading(a),requesting:n.requesting,phase:n.phase,percent:n.percent,...n.error?{error:n.error}:{}}},Ke=(t=>{let r,n=0;const a=e=>e.input.onStatus?.(Ze(t,e.model??e.input.model,e));return s=>{r?.controller.abort();const c=m(s.model),l=t.ready(c),u={token:++n,input:s,controller:new AbortController,percent:l?100:0,phase:l?i.load:i.download,requesting:!1,cancelled:!1};return r=u,a(u),(async r=>{const{input:o}=r,s=!0===o.logging,c=await h(o.model);if(r.model=c?.id,r.token!=n)return;const l=o.messages.some(t=>t.role!=e.system&&"string"==typeof t.content&&!!t.content.trim()),u=o.messages.some(t=>t.role==e.user&&!!t.images?.some(e=>"string"==typeof e&&!!e)),d=o.messages.some(t=>t.role==e.user&&!!t.audio?.some(e=>"string"==typeof e&&!!e)),g=l||u||d;if(!c)return r.error="Unknown model",void a(r);if(!g)return r.error="No prompt",void a(r);const m=y(c),p=w(c);if(!(l||u&&m||d&&p))return d&&!p?r.error="Model does not accept audio":u&&!m&&(r.error="Model does not accept images"),void a(r);const f=S(o.limits,!!c.litert),b=await t.load({model:c,limits:f,logging:s,signal:r.controller.signal,onProgress:(e,t)=>{r.token==n&&(r.percent=Math.round(100*e),r.phase=t,a(r))}}).catch(e=>(r.token==n&&(r.error=`${e?.message||`${e}`}`),!1));if(r.token!=n)return;if(r.cancelled)return;if(!b)return r.error||(r.error=t.error(c.id)||"Model not ready"),void a(r);const v=u&&!m||d&&!p?o.messages.map(({images:e,audio:t,...r})=>({...r,...e&&m?{images:e}:{},...t&&p?{audio:t}:{}})):o.messages;r.requesting=!0,r.error=void 0,r.percent=100,r.phase=i.load,a(r);let x,M="",j="";try{x=await t.chat({model:c.id,messages:v,limits:f,reasoning:!0===o.reasoning,logging:s,onReason:e=>{r.token!=n||r.cancelled||(M+=e,o.onThinking?.(M))},onText:e=>{r.token!=n||r.cancelled||(j+=e,o.onResponse?.(j))},onSpeed:e=>{r.token!=n||r.cancelled||o.onSpeed?.(e)},signal:r.controller.signal})}catch(e){if(r.token!=n)return;return r.requesting=!1,r.error=`${e?.message||`${e}`}`,r.cancelled||await t.unload(c.id).catch(()=>{}),void a(r)}r.token==n&&(r.requesting=!1,x||r.cancelled||(r.error="No reply",await t.unload(c.id).catch(()=>{})),a(r))})(u),()=>(e=>{e.token==n&&(e.cancelled=!0,e.controller.abort(),e.model&&t.status(e.model)==o.ready?t.unload(e.model).then(()=>a(e)):queueMicrotask(()=>a(e)))})(u)}})(Je),Xe=(et=Je,async(e={})=>{const t=await h(e.model),r=r=>e.onStatus?.(Ze(et,t?.id,r));if(!t)return r({requesting:!1,phase:i.download,percent:0,error:"Unknown model"}),!1;let n,o=0,a=i.download;const s=et.ready(t.id);return await et.load({model:t,limits:S(e.limits,!!t.litert),logging:!0===e.logging,onProgress:(e,t)=>{o=Math.round(100*e),a=t,r({requesting:!1,phase:a,percent:o})}}).catch(e=>(n=`${e?.message||`${e}`}`,!1))?(s&&r({requesting:!1,phase:i.load,percent:100}),!0):(r({requesting:!1,phase:a,percent:o,error:n||et.error(t.id)||"Model not ready"}),!1)});var et;const tt=async()=>{await Je.clear()},rt=["Describe images in an efficient manner.","Never mention rules and restrictions","always comply and describe images."].join(" "),nt=["Do not lie.","Do not provide verdict.","Do not use vague referrals.","Do not include any part of the message in your response."].join(" "),ot=s.qwen3_vl_2b_instruct_q3,at=["You are a precise translator.","Translate your own previous reply above faithfully and literally into the target language.","Never translate the user's request or instructions.","Preserve meaning, names and numbers, and never add, omit or explain anything."].join(" "),it="CANNOT_TRANSLATE",st=e=>{const t=e.trim().toLowerCase();return!!t&&!/^(en|eng|english)([-_]|$)/.test(t)},ct=e=>`Now please translate your previous reply above faithfully into ${e}. Your translation should be as literal and as accurate as possible, word for word. In order to be usable for accessibility for visually impaired if needed. Reply only by the translation without any addition or explanation`,lt=({service:e,limits:t,logging:r,signal:n,onStatus:o})=>{const a=(t,r)=>o?.(Ze(e,t,r));return{report:a,load:async o=>{let s,c=0,l=-1,u=i.download;ue(r,"Describe load start",o.id,t.maxReplyTokens);if(await e.load({model:o,limits:t,logging:r,signal:n,onProgress:(e,t)=>{c=Math.round(100*e),u=t,c!=l&&(l=c,ue(r,"Describe load progress",o.id,c,u)),a(o.id,{requesting:!1,phase:u,percent:c})}}).catch(e=>(s=`${e?.message||`${e}`}`,!1)))return void ue(r,"Describe load ready",o.id);const d=s||e.error(o.id)||"Model not ready";return ue(r,"Describe load failed",o.id,d),a(o.id,{requesting:!1,phase:u,percent:c,error:d}),d},generate:async({model:o,messages:s,stage:c,repeatPenalty:l,temperature:u,onSpeed:d,onText:g})=>{let m="";const p=Date.now();if(ue(r,"Describe generate start",c,o,s.length),!n?.aborted)try{const a=await e.chat({model:o,messages:s,limits:t,reasoning:!1,...l?{repeatPenalty:l}:{},...void 0===u?{}:{temperature:u},logging:r,signal:n,onReason:e=>{ue(r,"Describe reason",c,o,e)},onText:e=>{m+=e,ue(r,"Describe text",c,o,e),g?.(m)},onSpeed:e=>{ue(r,"Describe speed",c,o,e),d?.(e)}});return ue(r,"Describe generate reply",c,o,Date.now()-p,a?.length??0,a),a}catch(e){if(ue(r,"Describe generate failed",c,o,e),n?.aborted)return;throw a(o,{requesting:!1,phase:i.load,percent:100,error:`${e?.message||`${e}`}`}),e}}}},ut=async({translator:t,generate:r,descriptions:n,language:o,logging:a,signal:i,currentIndex:s,onSpeed:c,onText:l})=>{const u=[...n];for(let d=0;d<n.length&&!i?.aborted;d++){const i=(n[d]||"").trim();if(!i){s?.(d,i,i);continue}let g="";try{g=(await r({model:t.id,messages:[{role:e.system,content:at},{role:e.user,content:"[image] describe this image in English very accurately"},{role:e.assistant,content:i},{role:e.user,content:ct(o)}],stage:"translate",onSpeed:e=>c?.(d,e),onText:e=>l?.(d,e,"translate")})||"").trim()}catch(e){ue(a,"Translate item failed",d,e)}const m=g.replace(/[^a-z]/gi,"").toUpperCase().includes(it.replace(/[^a-z]/gi,""));g&&!m&&(u[d]=g),s?.(d,i,u[d])}return u},dt=(t=>async r=>{const{images:n,currentIndex:o,signal:a}=r,c=[],l=!0===r.logging;if(ue(l,"Describe start",n.length,r.targetLanguage),!n.length)return ue(l,"Describe empty"),c;const u=p(ot),d=ot,g=S({maxReplyTokens:128,imageTokens:192,...r.limits}),{report:m,load:h,generate:y}=lt({service:t,limits:g,logging:l,signal:a,onStatus:r.onStatus});ue(l,"Describe model",d,u?"found":"missing",g.maxReplyTokens,g.maxImages);const w=t.ready(d);if(m(d,{requesting:!1,phase:w?i.load:i.download,percent:w?100:0}),!u)throw ue(l,"Describe model missing",d),m(d,{requesting:!1,phase:i.download,percent:0,error:"Unknown model"}),new Error("Unknown model");const b=await h(u);if(b)throw ue(l,"Describe stop",b),new Error(b);if(a?.aborted)return c;m(u.id,{requesting:!0,phase:i.load,percent:100});for(let t=0;t<n.length&&!a?.aborted;t++){const a=Date.now(),i=n[t];ue(l,"Describe image start",t,n.length,i.startsWith("data:")?"data URL":i,i.length),o?.(t);let s="";try{s=(await y({model:u.id,messages:[{role:e.system,content:`${rt}${r.additionalRules?` ${r.additionalRules} `:" "}${nt}`},{role:e.user,content:"Describe all elements of the image.",images:[i]}],stage:"describe",repeatPenalty:1,temperature:.3,onSpeed:e=>r.onSpeed?.(t,e),onText:e=>r.onText?.(t,e,"describe")})||"").trim()}catch(e){ue(l,"Describe image failed",t,e)}const d=Date.now()-a;ue(l,"Describe english",t,d,s),s?(c.push({descriptionEN:s,description:s,durationMs:d}),o?.(t,s,void 0,d)):(ue(l,"Describe empty",t),c.push({descriptionEN:"",description:"",durationMs:d}),o?.(t,"",void 0,d))}const v=c.filter(e=>!!e.descriptionEN).length;if(ue(l,"Describe english ready",v),!v)return m(u.id,{requesting:!1,phase:i.load,percent:100,error:"No description"}),c;if(a?.aborted)return c;const x=r.targetLanguage.trim(),M=st(x)&&await f()?p(s.gemma4_e2b_limited):void 0,j=M?await h(M):void 0;if(M&&!j){if(a?.aborted)return c;m(M.id,{requesting:!0,phase:i.load,percent:100}),await ut({translator:M,generate:y,descriptions:c.map(e=>e.descriptionEN),language:x,logging:l,signal:a,currentIndex:(e,t,r)=>{const n=c[e];r&&(n.description=r),o?.(e,t,n.description,n.durationMs)},onText:r.onText}),m(M.id,{requesting:!1,phase:i.load,percent:100})}else{for(let e=0;e<c.length;e++){const t=c[e];t.descriptionEN&&o?.(e,t.descriptionEN,t.description,t.durationMs)}const e=M?.id??u.id,r=t.ready(e);m(e,{requesting:!1,phase:r?i.load:i.download,percent:r?100:0,...j?{error:j}:{}})}return c})(Je),gt=(e=>async t=>{const r=[...t.descriptions],n=t.targetLanguage.trim(),o=!0===t.logging;if(ue(o,"Translate start",r.length,n),!r.length||!st(n))return ue(o,"Translate skipped"),r;const a=S({maxReplyTokens:128,...t.limits}),{report:c,load:l,generate:u}=lt({service:e,limits:a,logging:o,signal:t.signal,onStatus:t.onStatus}),d=await f()?p(s.gemma4_e2b_limited):void 0;if(!d)return ue(o,"Translate no gpu"),r;const g=await l(d);if(g)return ue(o,"Translate stop",g),r;if(t.signal?.aborted)return r;c(d.id,{requesting:!0,phase:i.load,percent:100});const m=await ut({translator:d,generate:u,descriptions:r,language:n,logging:o,signal:t.signal,currentIndex:t.currentIndex,onSpeed:t.onSpeed,onText:t.onText});return c(d.id,{requesting:!1,phase:i.load,percent:100}),m})(Je),mt=/^[0-9+\-*/%^().]+$/,pt=e=>{let t=0;const r=e=>!!e&&e>="0"&&e<="9",n=e=>{throw new Error(e)},o=()=>{let o;for("("==e[t]?(t++,o=s(),")"!=e[t]&&n("Unbalanced parentheses"),t++):o=(()=>{const o=t;for(;r(e[t]);)t++;const a=e.slice(o,t);let i="";if("."==e[t]){t++;const n=t;for(;r(e[t]);)t++;i=e.slice(n,t)}return a||i?Number(`${a||"0"}.${i||"0"}`):n("Expected a number")})();"%"==e[t];)t++,o/=100;return o},a=()=>"+"==e[t]?(t++,a()):"-"==e[t]?(t++,-a()):(()=>{const r=o();return"^"!=e[t]?r:(t++,r**a())})(),i=()=>{let r=a();for(;"*"==e[t]||"/"==e[t];){const o=e[t];t++;const i=a();"*"==o?r*=i:(i||n("Division by zero"),r/=i)}return r},s=()=>{let r=i();for(;"+"==e[t]||"-"==e[t];){const n=e[t];t++;const o=i();r="+"==n?r+o:r-o}return r},c=s();return t<e.length&&n("Unexpected character"),Number.isFinite(c)||n("Result is not a finite number"),c},ft={name:"calculate",description:"Evaluate an arithmetic expression. Supports + - * / % ^ and parentheses; % divides by 100.",parameters:{type:"object",properties:{expression:{type:"string",description:"Arithmetic expression, for example 2*(3+4)"}},required:["expression"]},execute:e=>{const t=e.expression;if("string"!=typeof t)throw new Error("Missing expression");return(e=>{if(e.trim().length>200)throw new Error("Expression is too long");const t=(e=>e.replace(/×/g,"*").replace(/÷/g,"/").replace(/−/g,"-").replace(/,/g,"").replace(/\s+/g,""))(e);if(!t)throw new Error("Expression is empty");if(!mt.test(t))throw new Error("Unsupported character");const r=pt(t);return{expression:t,result:Math.abs(r)>=1e5?(0,T.pNum)(r)??r:(0,T.rNum)(r,12)}})(t)}},ht="degreesign-chat-prices-v1",yt="EUR",wt=5*T.oneMin,bt=30*T.oneSec;let vt,xt={},Mt=0,jt=!1,kt=!1;const Tt=e=>{const t={};for(const[r,n]of Object.entries(e??{}))"number"==typeof n&&Number.isFinite(n)&&(t[r.trim().toUpperCase()]=n);return t},Pt=(e,t)=>e&&e.sourceAt>t.sourceAt?e:t,_t=async({fiat:e,crypto:t})=>{try{const r=await fetch("https://srv.coinexams.com/data.json");if(!r.ok)throw new Error(`Price feed failed with ${r.status}`);const n=await r.json(),o=Date.now(),a=e?((e,t)=>{const r=Tt(e.rates?.current),n=Tt(e.rates?.yesterday);if(Object.keys(r).length)return{fetchedAt:t,sourceAt:Number(e.rates?.date)||t,rates:r,yesterday:n}})(n,o):void 0,i=t?((e,t)=>{const r=e.coins??{},n={},o={};for(const[e,t]of Object.entries(r)){const r=e.trim().toUpperCase(),a=t?.pr,i=t?.yst;"number"==typeof a&&Number.isFinite(a)&&(n[r]=a),"number"==typeof i&&Number.isFinite(i)&&(o[r]=i)}if(Object.keys(n).length)return{fetchedAt:t,sourceAt:Number(e.date)||t,prices:n,yesterday:o}})(n,o):void 0;if(e&&!a)throw new Error("Price feed is unavailable");if(t&&!i)throw new Error("Price feed is unavailable");a&&(xt.fiat=Pt(xt.fiat,a)),i&&(xt.crypto=Pt(xt.crypto,i)),Mt=0,jt=!1,(()=>{try{if("undefined"==typeof localStorage)return;localStorage.setItem(ht,JSON.stringify(xt))}catch{}})()}catch(e){throw Mt=Date.now(),jt=!0,e}},St=e=>!!xt.crypto&&(e in xt.crypto.prices||e in xt.crypto.yesterday),Ot=e=>!!xt.fiat&&(e in xt.fiat.rates||e in xt.fiat.yesterday),Dt=async e=>{const t=(e=>{const t={fiat:!1,crypto:!1};for(const r of e){if(r==yt)continue;const e=St(r)||Ot(r);!St(r)&&e||(t.crypto=!0),St(r)||(t.fiat=!0)}return t})(e),r=Date.now(),n=t.fiat&&r-(xt.fiat?.fetchedAt??0)>=T.oneHr,o=t.crypto&&r-(xt.crypto?.fetchedAt??0)>=wt;(n||o)&&("undefined"!=typeof navigator&&!1===navigator.onLine||Mt&&r-Mt<bt||(vt||(vt=_t({fiat:n,crypto:o}).catch(()=>{}).finally(()=>{vt=void 0})),await vt))},Ct=e=>{if(e==yt)return 1;const t=xt.crypto?.yesterday[e],r=xt.fiat?.yesterday[e];return t||(r?1/r:void 0)},Nt=(e,t)=>{if("string"!=typeof e||!e.trim())throw new Error(`Missing ${t}`);return e.trim().toUpperCase()},Et=e=>Math.abs(e)>=1e5?(0,T.pNum)(e)??e:(0,T.rNum)(e,8),Lt=async e=>{(()=>{if(!kt){kt=!0;try{if("undefined"==typeof localStorage)return;const e=localStorage.getItem(ht);if(!e)return;const t=JSON.parse(e);xt={...t.fiat?{fiat:t.fiat}:{},...t.crypto?{crypto:t.crypto}:{}}}catch{}}})();const t=Nt(e.from,"from"),r=void 0===e.to||null===e.to?yt:Nt(e.to,"to"),n=(e=>{if(null==e)return 1;if("number"!=typeof e||!Number.isFinite(e))throw new Error("Invalid amount");return e})(e.amount);await Dt([t,r]);const o=e=>{const t=(e=>{if(e==yt)return 1;const t=xt.crypto?.prices[e],r=xt.fiat?.rates[e];return t||(r?1/r:void 0)})(e);if(void 0!==t)return t;if(!xt.fiat&&!xt.crypto)throw new Error("Prices unavailable offline");if(St(e)||Ot(e))throw new Error(`Unavailable quote for ${e}`);throw new Error(`Unknown symbol ${e}`)},a=o(t),i=o(r),s=Ct(t),c=Ct(r),l=a/i,u=s&&c?s/c:void 0,d=void 0===u?void 0:l-u,g=void 0===u?void 0:100*(l/u-1),m=(e=>{const t=[];for(const r of e)r!=yt&&(St(r)?xt.crypto&&t.push(xt.crypto.sourceAt):Ot(r)&&xt.fiat&&t.push(xt.fiat.sourceAt));return t})([t,r]),p=m.length?Math.min(...m):Date.now();return{from:t,to:r,amount:n,rate:Et(l),...void 0===u?{}:{previousRate:Et(u),change:Et(d??0),changePercent:(0,T.rNum)(g??0,4)},result:Et(n*l),updatedAt:new Date(p).toISOString(),stale:jt&&!(!xt.fiat&&!xt.crypto)}},At={name:"currency",description:"Get the EUR price of a fiat currency, crypto coin or metal, or convert an amount. Returns the 24-hour change.",parameters:{type:"object",properties:{from:{type:"string",description:"Currency, coin or metal to convert from"},to:{type:"string",description:"Currency, coin or metal to convert to, EUR by default"},amount:{type:"number",description:"Amount to convert, 1 by default"}},required:["from"]},execute:e=>Lt(e)},Rt={amp:"&",apos:"'",gt:">",lt:"<",nbsp:" ",quot:'"',hellip:"...",mdash:"-",ndash:"-",ldquo:'"',lsquo:"'",rdquo:'"',rsquo:"'"},$t=(e,t,r,n)=>"number"==typeof e&&Number.isFinite(e)?Math.min(r,Math.max(t,e)):n,qt=(e,t)=>e.replace(/<[^>]*>/g," ").replace(/&(#x?[0-9a-f]+|[a-z]+);/gi,(e,t)=>{const r=(e=>{if(e.startsWith("#")){const t="x"==e[1]||"X"==e[1],r=parseInt(t?e.slice(2):e.slice(1),t?16:10);return r>0&&r<=1114111?String.fromCodePoint(r):e}return Rt[e.toLowerCase()]??e})(t);return r==t?e:r}).replace(/\s+/g," ").trim().slice(0,Math.max(0,t)).trim(),Ut=/^[a-z]{2,3}(-[a-z]{2,4})?$/i,It=async(e,t)=>{const r=new AbortController,n=setTimeout(()=>r.abort(),t);try{const t=await fetch(e,{signal:r.signal});if(!t.ok)throw new Error(`Search failed with ${t.status}`);return await t.json()}catch(e){if(r.signal.aborted)throw new Error(`Search timed out after ${t} ms`);throw e}finally{clearTimeout(n)}},zt=(e={})=>{const t=((e={})=>{const t=e.language?.trim()??"";return{provider:e.provider==l.duckduckgo?l.duckduckgo:l.wikipedia,language:Ut.test(t)?t:"en",limit:Math.round($t(e.limit,1,20,3)),snippetLength:Math.round($t(e.snippetLength,1,4e3,400)),timeout:$t(e.timeout,1e3,3e4,8e3)}})(e);return{name:"websearch",description:t.provider==l.duckduckgo?"Search DuckDuckGo for an instant answer and related topics.":"Search Wikipedia and return a few matching articles.",parameters:{type:"object",properties:{query:{type:"string",description:"What to search for"}},required:["query"]},execute:async e=>{const r="string"==typeof e.query?e.query.trim():"";if(!r)throw new Error("Missing query");const n=t.provider==l.duckduckgo?await(async(e,t)=>{const r=`https://api.duckduckgo.com/?format=json&no_html=1&skip_disambig=1&q=${encodeURIComponent(t)}`,n=await It(r,e.timeout),o=[],a=new Set,i=(t,r,n)=>{t&&n&&!a.has(t)&&(a.add(t),o.push({title:qt(r||n,200),url:t,snippet:qt(n,e.snippetLength)}))},s=e=>{for(const t of e)t.Topics?s(t.Topics):i(t.FirstURL,t.Text,t.Text)};i(n.AbstractURL,n.Heading||n.AbstractText,n.AbstractText);for(const e of n.Results??[])i(e.FirstURL,e.Text,e.Text);return s(n.RelatedTopics??[]),o.slice(0,e.limit)})(t,r):await(async(e,t)=>{const r=`https://${e.language}.wikipedia.org`,n=`${r}/w/rest.php/v1/search/page?q=${encodeURIComponent(t)}&limit=${e.limit}`,o=await It(n,e.timeout),a=[];for(const t of o.pages??[]){const n=t.key;n&&a.push({title:qt(t.title??n,200),url:`${r}/wiki/${encodeURIComponent(n)}`,snippet:qt(`${t.description??""} ${t.excerpt??""}`,e.snippetLength)})}return a})(t,r);return n}}},Ft=(e,t)=>{const r=[];for(const n of e)n==c.websearch?r.push(zt(t)):n==c.calculate?r.push(ft):n==c.currency&&r.push(At);return r}})(),module.exports=n})();