@degreesign/chat 0.9.3 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +58 -25
- package/dist/browser/chat.min.mjs +1 -1
- package/dist/describe.d.ts +6 -2
- package/dist/engines/images.d.ts +1 -1
- package/dist/engines/wllama.d.ts +2 -2
- package/dist/enums.d.ts +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/node/chat.node.min.js +1 -1
- package/dist/node/chat.node.min.mjs +1 -1
- package/dist/types.d.ts +26 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -124,7 +124,7 @@ second, measured from the first token so prompt processing is excluded.
|
|
|
124
124
|
`false` when it cannot load.
|
|
125
125
|
|
|
126
126
|
Attach images to a user turn with `images: [dataUrl]`. The package sends them
|
|
127
|
-
only to a model with vision support, fits each image to
|
|
127
|
+
only to a model with vision support, fits each image to 64 to 72 vision
|
|
128
128
|
tokens, snaps both sides to multiples of 32 px, crops the remainder, and caps
|
|
129
129
|
the number with `limits.maxImages`. The WebGPU engine asks LiteRT for the
|
|
130
130
|
smallest Gemma 4 vision budget (70 tokens, 630 patches), so it center-crops to a
|
|
@@ -230,6 +230,7 @@ starts the vision or audio encoder.
|
|
|
230
230
|
createChat(input: ChatInput): CancelChat
|
|
231
231
|
preloadModel(input?: ChatPreloadInput): Promise<boolean>
|
|
232
232
|
describeImages(input: DescribeImagesInput): Promise<ImageDescription[]>
|
|
233
|
+
describeTranslated(input: DescribeTranslatedInput): Promise<string[]>
|
|
233
234
|
clearModelCache(): Promise<void>
|
|
234
235
|
```
|
|
235
236
|
|
|
@@ -303,15 +304,15 @@ on failure. A preload owns no cancel function; a new load replaces it.
|
|
|
303
304
|
describeImages(input: DescribeImagesInput): Promise<ImageDescription[]>
|
|
304
305
|
```
|
|
305
306
|
|
|
306
|
-
Describe every image in English with `
|
|
307
|
-
Qwen3-VL 2B Instruct
|
|
308
|
-
and `targetLanguage` is not English, the English descriptions
|
|
309
|
-
translated one by one with `gemma4_e2b_limited`. Without a GPU, when
|
|
310
|
-
translation model cannot load, or when the translator replies
|
|
307
|
+
Describe every image in English with `qwen3_vl_2b_instruct_q3`, the Q3_K_M
|
|
308
|
+
build of Unsloth Qwen3-VL 2B Instruct, one image at a time. When a WebGPU
|
|
309
|
+
adapter exists and `targetLanguage` is not English, the English descriptions
|
|
310
|
+
are then translated one by one with `gemma4_e2b_limited`. Without a GPU, when
|
|
311
|
+
the translation model cannot load, or when the translator replies
|
|
311
312
|
`CANNOT_TRANSLATE`, `description` stays equal to `descriptionEN`. Both the
|
|
312
|
-
description and translation calls use a
|
|
313
|
-
`limits.maxReplyTokens` overrides it. The describer sets an explicit
|
|
314
|
-
|
|
313
|
+
description and translation calls use a 600-token reply budget unless
|
|
314
|
+
`limits.maxReplyTokens` overrides it. The describer sets an explicit 16 to
|
|
315
|
+
100 vision-token window; other models leave the engine image limits unset.
|
|
315
316
|
|
|
316
317
|
The describer and translator each receive a system message that puts accuracy
|
|
317
318
|
first: the describer reports only visible detail and the translator preserves
|
|
@@ -350,6 +351,30 @@ final snapshot has `requesting: false`; when the translator cannot load, it also
|
|
|
350
351
|
carries that error and the descriptions stay English. An empty `images` list
|
|
351
352
|
touches no model and reports nothing.
|
|
352
353
|
|
|
354
|
+
### Translate descriptions
|
|
355
|
+
|
|
356
|
+
```ts
|
|
357
|
+
describeTranslated(input: DescribeTranslatedInput): Promise<string[]>
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
Translate English image descriptions that the host already has, without another
|
|
361
|
+
vision pass. `describeImages` uses the same translation pass. When a WebGPU
|
|
362
|
+
adapter exists, each description is translated one by one with
|
|
363
|
+
`gemma4_e2b_limited`. Without a GPU, when the translator cannot load, or when it
|
|
364
|
+
replies `CANNOT_TRANSLATE`, the result keeps the English text. The promise
|
|
365
|
+
resolves one string per input description, in input order.
|
|
366
|
+
|
|
367
|
+
`DescribeTranslatedInput`:
|
|
368
|
+
|
|
369
|
+
| Field | Description |
|
|
370
|
+
| ----- | ----------- |
|
|
371
|
+
| `descriptions` | English descriptions, translated in this order. |
|
|
372
|
+
| `targetLanguage` | Language of each result; `en`, `English` or a tag such as `en-US` skips translation. |
|
|
373
|
+
| `currentIndex?` | Receives `index`, `descriptionEN` and `description` as each entry finishes. |
|
|
374
|
+
| `limits?` | Partial `LlmLimits` for the translation call. |
|
|
375
|
+
| `logging?` | Whether package and engine console logs are written. Defaults to `false`. |
|
|
376
|
+
| `onStatus?` | Receives a `ChatStatusSnapshot` while the translator loads and runs. |
|
|
377
|
+
|
|
353
378
|
## Tools
|
|
354
379
|
|
|
355
380
|
Three built-in tools ship as descriptors. They are not connected to the model:
|
|
@@ -401,13 +426,14 @@ search and currency tools fetch over the network; `calculate` does not.
|
|
|
401
426
|
|
|
402
427
|
The first snapshot fires synchronously inside `createChat`. A final snapshot
|
|
403
428
|
with `requesting: false` marks the end of the call. `describeImages` reports the
|
|
404
|
-
same snapshot for each model it loads: `
|
|
429
|
+
same snapshot for each model it loads: `qwen3_vl_2b_instruct_q3` while it
|
|
405
430
|
describes, then `gemma4_e2b_limited` while it translates.
|
|
406
431
|
|
|
407
|
-
A stream that never produces its first chunk ends with an error after
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
ends the stream and keeps the text already
|
|
432
|
+
A stream that never produces its first chunk ends with an error after 5
|
|
433
|
+
minutes on a desktop or 50 minutes on a phone or tablet, and an image turn
|
|
434
|
+
waits at least 14 minutes for a slow CPU vision prefill. Once a chunk has
|
|
435
|
+
arrived, 30 seconds of silence ends the stream and keeps the text already
|
|
436
|
+
delivered.
|
|
411
437
|
|
|
412
438
|
## Logging
|
|
413
439
|
|
|
@@ -424,6 +450,7 @@ without it goes quiet again.
|
|
|
424
450
|
| ------------- | ---- | --------- | ------ | ----- | --- | ------ |
|
|
425
451
|
| `qwen3_vl_2b` | Qwen3-VL 2B | Yes | Yes | No | Yes | No |
|
|
426
452
|
| `qwen3_vl_2b_instruct` | Qwen3-VL 2B Instruct | No | Yes | No | Yes | No |
|
|
453
|
+
| `qwen3_vl_2b_instruct_q3` | Qwen3-VL 2B Instruct Q3 | No | Yes | No | Yes | No |
|
|
427
454
|
| `gemma4_e2b` | Gemma 4 E2B | Yes | Yes | Yes | No | Yes |
|
|
428
455
|
| `gemma4_e2b_limited` | Gemma 4 E2B limited | Yes | No | No | No | Yes |
|
|
429
456
|
|
|
@@ -445,10 +472,13 @@ context on a phone and 8192 on a desktop. Its projector uses the same CPU thread
|
|
|
445
472
|
budget as the text pass, so image turns are slower than the Gemma 4 WebGPU path.
|
|
446
473
|
Use the GPU model when images need to be fast.
|
|
447
474
|
|
|
448
|
-
`
|
|
449
|
-
`describeImages` loads for the English pass
|
|
450
|
-
|
|
451
|
-
|
|
475
|
+
`qwen3_vl_2b_instruct_q3` is the Unsloth Qwen3-VL 2B Instruct build that
|
|
476
|
+
`describeImages` loads for the English pass, its Q3_K_M file. Both instruct
|
|
477
|
+
builds use Qwen's Q8_0 projector, about 445 MB, so the describer totals about
|
|
478
|
+
1.4 GB on the CPU engine. It has no reasoning pass, so it answers an image
|
|
479
|
+
prompt directly. `qwen3_vl_2b_instruct` is the same model in Q4_K_M, about
|
|
480
|
+
200 MB larger, for a host that prefers the higher precision describer and
|
|
481
|
+
names it explicitly.
|
|
452
482
|
|
|
453
483
|
Gemma 4 E2B downloads `gemma-4-E2B-it.litertlm`, about 2.6 GB, on a desktop. It
|
|
454
484
|
runs on the WebGPU engine with its vision and audio encoders in the same file,
|
|
@@ -486,8 +516,8 @@ user: {next turn}
|
|
|
486
516
|
vision or audio support.
|
|
487
517
|
- Images are collected from the newest turns first and capped by `maxImages`
|
|
488
518
|
(default 2). Older image parts are dropped and their text stays.
|
|
489
|
-
- Every image part keeps its full frame and targets
|
|
490
|
-
most
|
|
519
|
+
- Every image part keeps its full frame and targets 64 vision tokens, with at
|
|
520
|
+
most 72. Both sides are snapped to multiples of 32 px and the remainder is
|
|
491
521
|
cropped. The WebGPU engine instead center-crops to a 384 x 384 square, the
|
|
492
522
|
smallest Gemma 4 encoder signature.
|
|
493
523
|
- Audio is collected from the newest turns first and capped by `maxAudio`
|
|
@@ -513,9 +543,11 @@ onProgress })` contract and return the runtime object with `model`, `backend`,
|
|
|
513
543
|
matches the requested model.
|
|
514
544
|
|
|
515
545
|
The CPU engine derives a raw thread count from the device, then caps it at
|
|
516
|
-
`limits.maxThreads
|
|
517
|
-
|
|
518
|
-
|
|
546
|
+
`limits.maxThreads` and at 3 threads for a text model or 2 threads for a model
|
|
547
|
+
with a vision projector. The vision cap keeps the wasm image path alive: a
|
|
548
|
+
100-token image completes in about 89 seconds with 2 threads, while 3 threads
|
|
549
|
+
stalled past 10 minutes in the headless check. Every CPU model uses one count
|
|
550
|
+
for the whole load.
|
|
519
551
|
|
|
520
552
|
The CPU engine needs cross-origin isolation for its threads. Serve the page with
|
|
521
553
|
both headers:
|
|
@@ -639,6 +671,7 @@ const useReply = () => {
|
|
|
639
671
|
| `ChatInput` | One request: model, messages, budgets, reasoning and callbacks. |
|
|
640
672
|
| `ChatPreloadInput` | Model, limits, logging and status, the subset `preloadModel` needs. |
|
|
641
673
|
| `DescribeImagesInput` | Target language, images, progress callback, limits and logging. |
|
|
674
|
+
| `DescribeTranslatedInput` | English descriptions, target language, progress callback, limits and logging. |
|
|
642
675
|
| `ImageDescription` | `descriptionEN`, the translated `description` and `durationMs`. |
|
|
643
676
|
| `CancelChat` | The function returned by `createChat`. |
|
|
644
677
|
| `ChatMessage` | One prompt turn, `role`, `content` and optional `images` and `audio`. |
|
|
@@ -673,8 +706,8 @@ Yes, on models with vision support. Put image URLs in a user turn's `images`
|
|
|
673
706
|
array. Qwen3-VL 2B accepts images on the CPU engine and Gemma 4 E2B accepts
|
|
674
707
|
images on the desktop WebGPU engine. On a phone or tablet Gemma resolves to
|
|
675
708
|
`gemma4_e2b_limited`, the text-only browser build, so use `qwen3_vl_2b` for
|
|
676
|
-
mobile images. Each image keeps its full frame and targets
|
|
677
|
-
at most
|
|
709
|
+
mobile images. Each image keeps its full frame and targets 64 vision tokens,
|
|
710
|
+
at most 72, with both sides snapped to multiples of 32 px and the remainder
|
|
678
711
|
cropped. The WebGPU engine instead center-crops a 384 x 384 square with the
|
|
679
712
|
smallest Gemma 4 vision budget. A model without vision drops images
|
|
680
713
|
when the turn also has text; an image-only turn reports
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/*! For license information please see chat.min.mjs.LICENSE.txt */
|
|
2
|
-
var e={155(e){e.exports=(()=>{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"],n=({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""}},o=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""}};t.idShuffle=async({data:e,password:t})=>4==t?.length?n({data:e,password:t}):await o({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}}}},t={};function r(n){var o=t[n];if(void 0!==o)return o.exports;var a=t[n]={exports:{}};return e[n](a,a.exports,r),a.exports}var n={};return(()=>{var e=n;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=r(246);Object.defineProperty(e,"cacheCheck",{enumerable:!0,get:function(){return t.cacheCheck}}),Object.defineProperty(e,"delayCode",{enumerable:!0,get:function(){return t.delayCode}});const o=r(830);Object.defineProperty(e,"sumArr",{enumerable:!0,get:function(){return o.sumArr}}),Object.defineProperty(e,"minVl",{enumerable:!0,get:function(){return o.minVl}}),Object.defineProperty(e,"maxVl",{enumerable:!0,get:function(){return o.maxVl}}),Object.defineProperty(e,"getMax",{enumerable:!0,get:function(){return o.getMax}}),Object.defineProperty(e,"getMean",{enumerable:!0,get:function(){return o.getMean}}),Object.defineProperty(e,"getSum",{enumerable:!0,get:function(){return o.getSum}}),Object.defineProperty(e,"forecastNext",{enumerable:!0,get:function(){return o.forecastNext}}),Object.defineProperty(e,"forecastNextTotal",{enumerable:!0,get:function(){return o.forecastNextTotal}}),Object.defineProperty(e,"squeezeArray",{enumerable:!0,get:function(){return o.squeezeArray}}),Object.defineProperty(e,"compareArrays",{enumerable:!0,get:function(){return o.compareArrays}}),Object.defineProperty(e,"phaseDifference",{enumerable:!0,get:function(){return o.phaseDifference}});const a=r(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=r(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=r(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=r(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}})})(),n})()}};const t={};function r(n){const o=t[n];if(void 0!==o)return o.exports;const a=t[n]={exports:{}};return e[n].call(a.exports,a,a.exports,r),a.exports}var n,o,a,i,s,c,l,u;let d;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.j(e,t),Promise.all(t)},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={520:()=>import("./engine-litert.min.mjs"),924:()=>import("./engine-wllama.min.mjs")},t={792:0},n=e=>{let{__webpack_esm_ids__:n,__webpack_esm_modules__:o,__webpack_esm_runtime__:a}=e;var i,s,c=0;for(i in o)r.o(o,i)&&(r.m[i]=o[i]);for(a&&a(r);c<n.length;c++)s=n[c],r.o(t,s)&&t[s]&&t[s][0](),t[s]=0};r.f.j=(o,a)=>{let i=r.o(t,o)?t[o]:void 0;if(0!==i)if(i)a.push(i[1]);else{let r=e[o]().then(n,e=>{throw 0!==t[o]&&(t[o]=void 0),e});r=Promise.race([r,new Promise(e=>i=t[o]=[e])]),a.push(i[1]=r)}}})(),function(e){e.system="system",e.user="user",e.assistant="assistant"}(n||(n={})),function(e){e[e.online=0]="online",e[e.away=1]="away",e[e.offline=2]="offline"}(o||(o={})),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"}(a||(a={})),function(e){e.cpu="cpu",e.gpu="gpu",e.none="none"}(i||(i={})),function(e){e.download="download",e.load="load"}(s||(s={})),function(e){e.qwen3_vl_2b="qwen3-vl-2b",e.qwen3_vl_2b_instruct="qwen3-vl-2b-instruct",e.gemma4_e2b="gemma4-e2b",e.gemma4_e2b_limited="gemma4-e2b-limited"}(c||(c={})),function(e){e.websearch="websearch",e.calculate="calculate",e.currency="currency"}(l||(l={})),function(e){e.wikipedia="wikipedia",e.duckduckgo="duckduckgo"}(u||(u={}));const m=[{id:c.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:c.qwen3_vl_2b_instruct,reasoning:!1,cpu:{repo:"unsloth/Qwen3-VL-2B-Instruct-GGUF",file:"Qwen3-VL-2B-Instruct-Q4_K_M.gguf",mmproj:{file:"mmproj-F16.gguf"}}},{id:c.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:c.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},f=(e,t=g())=>e==c.gemma4_e2b&&t?c.gemma4_e2b_limited:e,p=e=>e?m.find(t=>t.id==e):void 0,h=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)}},y=async e=>p(f(e??await(async()=>(d||(d=(async()=>await h()?f(c.gemma4_e2b):c.qwen3_vl_2b)()),await d))())),w=e=>!!e.cpu?.mmproj||!0===e.litert?.vision,b=e=>!!e.cpu?.mmproj?.audio||!0===e.litert?.audio,v=new URL("./../assets/wllama/wllama.wasm",import.meta.url).href,x=new URL("./../assets/wllama/compat/wllama.wasm",import.meta.url).href,j=new URL("./../assets/wllama/compat/wllama.js",import.meta.url).href,M=new URL("./../assets/litert/litertlm_wasm_internal.js",import.meta.url).href,k=(new URL("./../assets/litert/litertlm_wasm_internal.wasm",import.meta.url).href,{width:384,height:384}),_=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},P=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),m=d?d.getContext("2d"):null;if(!d||!m||n.width<1||n.height<1)return n.close(),e;if(m.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 O=r(155);const S={maxReplyTokens:250,maxThinkingTokens:128,maxReasoningTokens:320,maxImages:2,maxAudio:1,maxContentLength:1e3,promptCharBudget:1e4,maxThreads:6},T=(e,t,r)=>"number"==typeof e&&Number.isFinite(e)&&e>=r?Math.floor(e):t,D=(e={},t=!1)=>{const r=S;return{maxReplyTokens:T(e.maxReplyTokens,r.maxReplyTokens,1),maxThinkingTokens:T(e.maxThinkingTokens,r.maxThinkingTokens,1),maxReasoningTokens:T(e.maxReasoningTokens,t?1200:r.maxReasoningTokens,1),maxImages:T(e.maxImages,r.maxImages,0),maxAudio:T(e.maxAudio,r.maxAudio,0),maxContentLength:T(e.maxContentLength,r.maxContentLength,1),promptCharBudget:T(e.promptCharBudget,r.promptCharBudget,1),maxThreads:T(e.maxThreads,r.maxThreads,1)}},C=(e,t)=>({stream:!0,temperature:.7,max_tokens:t?e.maxReasoningTokens:e.maxReplyTokens}),N=(e,t)=>`https://huggingface.co/${e}/resolve/main/${t}`,E=e=>Number(e.headers.get("content-length"))||0,A=(e,t)=>e.some(e=>Array.isArray(e.content)&&e.content.some(e=>e.type==t)),L=e=>A(e,"image"),$=e=>A(e,"audio"),R=["<|channel>thought\n","<|channel>thought","..."],U=["<channel|>","..."],q=(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,z=e=>"string"==typeof e?e?[{type:"text",text:e}]:[]:e,F=(e,t)=>{if("string"==typeof e&&"string"==typeof t)return`${e}\n${t}`;const r=[];for(const n of[...z(e),{type:"text",text:"\n"},...z(t)]){const e=r[r.length-1];"text"==n.type&&"text"==e?.type?e.text+=n.text:r.push(n)}return r},I=18e4;class V extends Error{}const W=async(e,t,r)=>{let n;try{return await Promise.race([e,new Promise((e,o)=>{n=setTimeout(()=>o(new V(r)),t)})])}finally{n&&clearTimeout(n)}},B=e=>{try{Promise.resolve(e.return?.()).catch(()=>{})}catch{}},Y=async({model:e,logging:t,onReason:r,onText:n,onSpeed:o,start:a,stopped:i,firstTimeoutMs:s=18e4,idleTimeoutMs:c=3e4,onStall:l})=>{let u="",d="",m="",g=!1,f=0,p=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,U);if(t>=0){t&&e(s.slice(0,t)),s=s.slice(t+i.length),n=!1;continue}const c=a(s,U);e(s.slice(0,s.length-c.length)),r=c;break}{const{at:e,tag:i}=o(s,R);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,R);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 W(a(),s,"Model did not start"))[Symbol.asyncIterator]();for(;;){if(i()){B(e);break}let n;try{n=await W(e.next(),g?c:s,g?"Model stopped responding":"Model did not reply")}catch(r){if(r instanceof V&&(u||d)){l?.(),B(e),t&&console.log("Local chat stalled",r);break}throw r}if(n.done)break;g=!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&&(m=a.finish_reason),w&&(d+=w,r(w)),y?.content&&h.feed(y.content),w||y?.content){const e=performance.now();f||(p=e),f+=1,f>1&&e>p&&o?.((0,O.rNum)(1e3*f/(e-p)))}}h.flush()}catch(e){if(t&&console.log("Local chat failed",e),e instanceof V&&!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,m||"none",u.length,d.length)),y},H=async({model:e,params:t,start:r,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 P(r.url,t)}:r);r.push({role:"user",content:e})}return r})(((e,t=S)=>{const r=t.maxContentLength,o=e.filter(e=>"string"==typeof e.content&&!!e.content.trim()||!(e.role!=n.user||!e.images?.length&&!e.audio?.length)),a=[],i=[];let s=0,c=t.maxImages,l=t.maxAudio;for(let e=o.length-1;e>=0;e--){const u=o[e],d=("string"==typeof u.content?u.content:"").slice(0,r),m=u.role==n.user?(u.images||[]).filter(e=>"string"==typeof e&&!!e).slice(0,Math.max(0,c)):[],g=u.role==n.user?(u.audio||[]).filter(e=>"string"==typeof e&&!!e).slice(0,Math.max(0,l)):[];if(d||m.length||g.length){if(d&&s+d.length>t.promptCharBudget)break;s+=d.length,c-=m.length,l-=g.length,u.role==n.system?a.unshift(d):u.role==n.assistant?i.unshift({role:"assistant",content:d}):i.unshift({role:"user",content:q(d,m,g)})}}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=F(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"),m=[];return d&&m.push({role:"system",content:d}),m.push(...u),m})(t.messages,t.limits),e.litert?k:void 0);return t.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}:{}})))})(e,i),await Y({model:e,logging:t.logging,onReason:t.onReason,onText:t.onText,onSpeed:t.onSpeed,start:()=>r(i),stopped:o,onStall:a,firstTimeoutMs:L(i)?42e4:I})},G=33554432,J=new Map;let Q=!1;const Z=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}`},K=e=>{const t=/^part-(\d+)$/.exec(e);return t?Number(t[1]):-1},X=async()=>{if(!Q)if("undefined"!=typeof navigator&&navigator.storage?.getDirectory)try{return await navigator.storage.getDirectory()}catch{return}else Q=!0},ee=async(e,t)=>{try{return await e.getDirectoryHandle(t)}catch{return}},te=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}},re=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{}},ne=async function*(e){for await(const t of e)yield t},oe=async e=>{try{for await(const[t,r]of ne(e))"file"==r.kind&&K(t)>=0&&await e.removeEntry(t).catch(()=>{})}catch{}},ae=async(e,t)=>{try{const r=await(await e.getFileHandle(t)).getFile(),n=await te(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}},ie=async(e,t)=>{const r=await ee(e,t);if(r){const e=await(async e=>await te(await e.getFileHandle("meta.json").catch(()=>{})))(r),t=await(async e=>{const t=[];try{for await(const[r,n]of ne(e)){const e=K(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 ae(e,t)},se=(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:E(e)||t.total,etag:a||t.etag}},ce=async({dir:e,start:t,skip:r,total:n,body:o,onProgress:a,onChunk:i})=>{let c,l=t,u=0,d=r;const m=async()=>{const t=await e.getFileHandle((e=>`part-${e}`)(l),{create:!0});c=await t.createWritable(),u=0},g=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;i();let f=0;for(d&&(f=Math.min(d,o.byteLength),d-=f);f<o.byteLength;){c||await m();const e=Math.min(G-u,o.byteLength-f);await c.write({type:"write",position:u,data:o.subarray(f,f+e)}),f+=e,u+=e,l+=e,u==G&&await g()}l>t&&a(n?l/n:0,s.download)}await g()}catch(e){throw await g(),e}return l},le=e=>["NotAllowedError","NotSupportedError"].includes(e?.name||""),ue=e=>{const t=async()=>{const t=await X();if(t)try{return await t.getDirectoryHandle(e,{create:!0})}catch{return}};return{stored:async e=>{const r=await t();return r?await ie(r,Z(e)):void 0},download:async({url:r,signal:n,onProgress:o})=>{const a=`${e}|${r}`,i=J.get(a);if(i)return await i;const c=await t();if(!c)return;const l=(async(e,t,r,n)=>{const o=Z(t),a=await ae(e,o);if(a?.complete)return a;let i=await ee(e,o);i||(await e.removeEntry(o).catch(()=>{}),await e.removeEntry(`${o}.json`).catch(()=>{}),i=await e.getDirectoryHandle(o,{create:!0}));let c=0,l=0;for(;;){if(r?.aborted)throw new Error("Cancelled");const a=await ie(e,o);if(a?.complete)return a;const u=a?.size??0,d=a?.total||0,m=a?.etag||"";if(u>c)c=u,l=0;else if(++l>4)throw new Error("Model download failed");u&&d&&n(u/d,s.download);const g=d?Math.min(u+G,d)-1:u+G-1,f=new AbortController,p=()=>f.abort(),h={size:u,total:d,etag:m};let y,w=setTimeout(p,3e4);r?.addEventListener("abort",p,{once:!0});try{if(y=await fetch(t,{signal:f.signal,headers:{Range:`bytes=${u}-${g}`}}),416==y.status){if(await(y.body?.cancel().catch(()=>{})),d&&u>=d){await re(i,{total:d,etag:m,complete:!0});continue}await oe(i),await re(i,{total:0,etag:"",complete:!1});continue}if(!y.ok||!y.body)throw await(y.body?.cancel().catch(()=>{})),new Error("Model download failed");const r=se(y,h);if(!r){await y.body.cancel().catch(()=>{}),await oe(i),await re(i,{total:0,etag:"",complete:!1});continue}await re(i,{total:r.total,etag:r.etag,complete:!1});const a=0==r.start?u:0,s=await ce({dir:i,start:r.start+a,skip:a,total:r.total,body:y.body,onProgress:n,onChunk:()=>{clearTimeout(w),w=setTimeout(p,3e4)}});if(!r.total){await re(i,{total:s,etag:r.etag,complete:!0});const t=await ie(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",p)}}})(c,r,n,o).finally(()=>{J.delete(a)});return J.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,Z(e))},purge:async()=>{const t=await X();t&&await t.removeEntry(e,{recursive:!0}).catch(()=>{})}}},de="litertlm-models",me=ue("litert-store"),ge={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 fe=!1;const pe=(...e)=>{fe&&console.log(...e)},he=(...e)=>{fe&&console.error(...e)},ye=e=>{try{e.getGlobalLiteRtLm().liteRtLmWasm.preinitializedWebGPUDevice=void 0}catch{}},we=async()=>{try{if("undefined"==typeof caches)return;return await caches.open(de)}catch{return}},be=new Map,ve=(e,t,r)=>{let n=0;return e.pipeThrough(new TransformStream({transform:(e,o)=>{n+=e.byteLength,r(t?n/t:0,s.download),o.enqueue(e)}}))},xe=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 _(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 e.content==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(n.text!=o.text)return!1}else if(("image"==n.type&&"image"==o.type||"audio"==n.type&&"audio"==o.type)&&n.url!=o.url)return!1}return!0},Me=async function*({engine:e,mod:t,params:r,messages:n,session:o}){const a=n[n.length-1],i=C(r.limits,r.reasoning);if("user"!=a?.role)throw new Error("No user turn");const s=n.slice(0,-1),c=(await xe([a]))[0];if(!c)throw new Error("Empty prompt");const l=!!o.conversation&&o.reasoning==r.reasoning&&o.maxTokens==i.max_tokens&&((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 u;if(l&&o.conversation)u=o.conversation;else{const n=await xe(s,!1);o.conversation=void 0,o.sent=[],u=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}),o.conversation=u,o.reasoning=r.reasoning,o.maxTokens=i.max_tokens,o.sent=[...s]}o.sent.push(a);let d,m=!1,g="";const f=()=>{d&&d.cancel().catch(()=>{});try{u.cancel()}catch{}};r.signal?.addEventListener("abort",f,{once:!0});try{if(r.signal?.aborted)return;const e=u.sendMessageStreaming(c).getReader();for(d=e;;){const{done:t,value:r}=await e.read();if(t)break;const n={};let o="string"==typeof r.content?r.content:"";if(Array.isArray(r.content))for(const e of r.content)"text"==e.type&&(o+=e.text);o&&(n.content=o,g+=o);const a=r.channels?.thought;a&&(n.reasoning=a),(n.content||n.reasoning)&&(yield{choices:[{delta:n}]})}m=!0}finally{r.signal?.removeEventListener("abort",f),m&&g?o.sent.push({role:"assistant",content:g}):(o.conversation=void 0,o.sent=[])}},ke={backend:i.gpu,startLLM:async({model:e,limits:t,onProgress:n,signal:o,logging:a})=>{fe=!0===a;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:pe,printErr:he};try{await l.getOrLoadGlobalLiteRtLm(M)}finally{u.Module=d}if(o?.aborted)throw new Error("Cancelled");const m=N(c.repo,c.file),g=await we();let f;const p=g?await g.match(m):void 0;if(p?.body)f=p.body;else{const e=await me.stored(m);e?.complete&&(f=e.file.stream())}if(!f){const e=await me.download({url:m,signal:o,onProgress:n}).catch(e=>{if(o?.aborted)throw new Error("Cancelled");if(!le(e))throw e;a&&console.log("Local model store failed",e)});e&&(f=e.file.stream())}if(!f&&g)try{await(async(e,t,r,n)=>{const o=be.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=E(o),i=ve(o.body,a,n);await t.put(e,new Response(i,{headers:{"content-type":"application/octet-stream",...a?{"content-length":`${a}`}:{}}}))})().finally(()=>{be.delete(e)});return be.set(e,a),await a})(m,g,o,n);const e=await g.match(m);e?.body&&(f=e.body)}catch(e){if(o?.aborted)throw new Error("Cancelled");a&&console.log("Local model cache failed",e)}if(f||(f=await(async(e,t,r)=>{const n=await fetch(e,{signal:t});if(!n.ok||!n.body)throw new Error("Model download failed");return ve(n.body,E(n),r)})(m,o,n)),o?.aborted)throw new Error("Cancelled");n(1,s.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:ge},...o?.vision?{visionBackend:n.Backend.GPU,maxVisionTokensPerImage:70,minVisionTokensPerImage:70}:{},...o?.audio?{audioBackend:n.Backend.CPU}:{}}})({model:e,limits:t,source:f,mod:l}));if(o?.aborted)throw await h.delete(),ye(l),new Error("Cancelled");const y={sent:[],reasoning:!1,maxTokens:0};return{model:e,backend:i.gpu,contextSize:4096,chat:t=>(async({engine:e,model:t,mod:r,params:n,session:o})=>{fe=!0===n.logging;const a=()=>{try{o.conversation?.cancel()}catch{}o.conversation=void 0,o.sent=[]};try{return await H({model:t,params:n,stopped:()=>!!n.signal?.aborted,onStall:a,start:async a=>{if(n.signal?.aborted)throw new Error("Cancelled");if(L(a)&&!t.litert?.vision)throw new Error("Model does not accept images");if($(a)&&!t.litert?.audio)throw new Error("Model does not accept audio");return Me({engine:e,mod:r,params:n,messages:a,session:o})}})}catch(e){throw a(),e}})({engine:h,model:e,mod:l,params:t,session:y}),unload:async()=>{const e=y.conversation;y.conversation=void 0,y.sent=[];try{await(e?.delete())}catch{}await h.delete(),ye(l)}}},cached:async e=>{const t=e.litert;if(!t)return!1;const r=N(t.repo,t.file),[n,o]=await Promise.all([we(),me.stored(r)]);if(o?.complete)return!0;try{return!(!n||!await n.match(r))}catch{return!1}},purge:async()=>{try{await me.purge(),"undefined"!=typeof caches&&await caches.delete(de)}catch{}}},_e=ue("wllama-store"),Pe=e=>e.cpu?.mmproj&&e.id==c.qwen3_vl_2b_instruct?{image_min_tokens:128,image_max_tokens:256}:{};let Oe,Se,Te="",De=!1;const Ce=e=>`${e.wasm}|${e.compatWasm}|${e.compatWorker}`,Ne=e=>{const t={wasm:v,compatWasm:x,compatWorker:j};return{wasm:e?.wasm||t.wasm,compatWasm:e?.compatWasm||t.compatWasm,compatWorker:e?.compatWorker||t.compatWorker}},Ee=e=>{const t=e=>(...t)=>{De&&("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)}},Ae=async()=>{if(Oe)return Oe;const e=await r.e(924).then(()=>r(577)),t=Se||Ne(),n=new e.Wllama({default:t.wasm},{logger:Ee(e.LoggerWithoutDebug)});return Se||(Se=t,Te=Ce(t)),n.setCompat({wasm:t.compatWasm,worker:t.compatWorker}),Oe=n,n},Le=async()=>{const e=Oe;Oe=void 0;try{await(e?.exit())}catch{}},$e=(e,t)=>e.name.includes(t)||!!e.metadata?.originalURL?.includes(t),Re=e=>{const t=e.cpu;return t?[{name:t.file,url:N(t.repo,t.file)},...t.mmproj?[{name:t.mmproj.file,url:N(t.repo,t.mmproj.file)}]:[]]:[]},Ue=async e=>{const t=Re(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},qe=async(e,t)=>{const r=await e.cacheManager.list();return Re(t).every(e=>r.some(t=>$e(t,e.name)))},ze=async({model:e,signal:t,onProgress:r})=>{const n=Re(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},Fe=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 _(t.url)});t.push({role:"user",content:e})}return t},Ie={backend:i.cpu,startLLM:async({model:e,limits:t,onProgress:r,signal:n,logging:o,assets:a})=>{De=!0===o;const c=g()?4096:8192,l=e.cpu;if(!l)throw new Error("Model has no CPU artifact");const u=Ne(a),d=Ce(u);Oe&&d!=Te&&await Le(),Se=u,Te=d;const m=(f="undefined"!=typeof navigator&&navigator.hardwareConcurrency||4,t.maxThreads,Math.max(1,Math.min(Math.max(2,Math.min(8,(f||4)-1)),2)));var f;const p=await Ae(),h=await Ue(e),y=l.mmproj?.file,w=N(l.repo,l.file),b=y?N(l.repo,y):"";if(n?.aborted)throw await Le(),new Error("Cancelled");if(!h&&y){const e=await p.cacheManager.list(),t=e.some(e=>$e(e,l.file)),r=e.some(e=>$e(e,y));t&&!r&&await p.cacheManager.deleteMany(e=>$e(e,l.file))}const v={n_ctx:c,n_threads:m,reasoning_budget_tokens:t.maxThinkingTokens,n_gpu_layers:0,jinja:!0,...Pe(e)};try{let t=h?await ze({model:e,signal:n,onProgress:r}):void 0;t||h||await qe(p,e).catch(()=>!1)||(t=await ze({model:e,signal:n,onProgress:r}).catch(e=>{if(n?.aborted)throw new Error("Cancelled");if(!le(e))throw e;o&&console.log("Local model store failed",e)})),t?(r(1,s.load),await p.loadModel(t,v)):await p.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?s.load:s.download)}})}catch(e){throw await Le(),e}if(n?.aborted)throw await Le(),new Error("Cancelled");if(!p.getLoadedContextInfo().n_ctx)throw await Le(),new Error("Failed to create model context");return{model:e,backend:i.cpu,contextSize:c,chat:t=>(async(e,t,r)=>{if(De=!0===r.logging,e.isModelLoaded())return await H({model:t,params:r,stopped:()=>!!r.signal?.aborted,start:async n=>{if(L(n)&&!e.supportInputModality("image"))throw new Error("Model does not accept images");if($(n)&&!e.supportInputModality("audio"))throw new Error("Model does not accept audio");return await e.createChatCompletion({messages:await Fe(n),...C(r.limits,r.reasoning),abortSignal:r.signal,...t.reasoning?{chat_template_kwargs:{enable_thinking:r.reasoning}}:{}})}})})(p,e,t),unload:async()=>{if(Oe==p)await Le();else try{await p.exit()}catch{}}}},cached:async e=>{try{return!!e.cpu&&(!!await Ue(e)||await qe(await Ae(),e))}catch{return!1}},purge:async()=>{try{await _e.purge()}catch{}try{const e=await Ae();await e.cacheManager.clear()}catch{}}},Ve=((e={})=>{const t=e.engines?.cpu||Ie,r=e.engines?.litert||ke;let n,o,c,l,u,d,m,g=i.none,f=a.idle,p=[],h=0,y={percent:0,phase:s.download};const w=n=>{if(e.backend!=i.none)return e.backend==i.cpu?n.cpu?t:void 0:e.backend==i.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},b=async()=>{const e=n;n=void 0,o=void 0,await(e?.unload())},v=(e,t)=>{y={percent:Math.max(0,Math.min(1,e)),phase:t||s.download};for(const e of[...p])e.report(y.percent,y.phase)},x=e=>{f=e},j=()=>{h++,u?.abort(),u=void 0,l=void 0,f==a.downloading&&x(a.idle)},M=(e,t)=>{const r=c;return r?new Promise(n=>{let o=!1;const a={report:e,settle:e=>{o||(o=!0,t?.removeEventListener("abort",i),n(e))}},i=()=>{(e=>{p=p.filter(t=>t!=e),queueMicrotask(()=>{!p.length&&c&&j()})})(a),a.settle(!1)};p.push(a),t?.aborted?i():t?.addEventListener("abort",i,{once:!0}),r.then(a.settle,()=>a.settle(!1))}):Promise.resolve(!1)},k=()=>f==a.ready&&!!n&&!!o,_=async()=>{j(),x(a.idle),await b()};return{load:async({model:e,limits:t,assets:r,logging:i,signal:m,onProgress:f})=>{if(m?.aborted)return!1;if(k()&&o?.id==e.id)return!0;if(c&&l==e.id)return f(y.percent,y.phase),await M(f,m);c&&(j(),p=[],await c.catch(()=>!1));const _=++h,P=(async()=>{await(async()=>{try{if("undefined"==typeof navigator)return;await(navigator.storage?.persist?.())}catch{}})();const c=w(e);if(_!=h)return!1;if(!c)return d="Model is not supported on this device",x(a.unsupported),!1;if(await b(),_!=h)return!1;const l=await c.cached(e);if(_!=h)return!1;d=void 0,x(a.downloading),v(0,s.download),l&&v(1,s.load);const m=new AbortController;u=m;try{const l=await c.startLLM({model:e,limits:t,logging:i,signal:m.signal,assets:r,onProgress:(e,t)=>{_==h&&v(e,t)}});return _!=h||m.signal.aborted?(await l.unload(),!1):(n=l,o=e,g=c.backend,d=void 0,x(a.ready),v(1,s.load),!0)}catch(e){return _!=h||(n=void 0,o=void 0,d=`${e?.message||`${e}`}`,i&&console.log("Local model failed",e),x(a.error)),!1}finally{u==m&&(u=void 0)}})().finally(()=>{c==P&&(c=void 0,l=void 0,p=[])});return c=P,l=e.id,await M(f,m)},chat:async e=>{if(!k()||!n)return;for(;m;)await m.catch(()=>{});if(!k()||!n)return;const t=n.chat(e);m=t;try{return await t}finally{m==t&&(m=void 0)}},unload:_,clear:async()=>{const e=c;await _(),await(e?.catch(()=>{})),await Promise.all([t.purge(),r.purge()])},ready:k,loading:()=>!k()&&f==a.downloading,status:()=>f,backend:()=>g,error:()=>d,model:()=>o}})(),We=(e,t,r)=>{const n=e.status(),i=f(t),s=p(i);return{...i?{model:i}:{},availability:n==a.ready?o.online:n==a.error||n==a.unsupported?o.offline:o.away,status:n,backend:e.backend(),supportsImages:!!s&&w(s),supportsAudio:!!s&&b(s),ready:e.ready(),loading:e.loading(),requesting:r.requesting,phase:r.phase,percent:r.percent,...r.error?{error:r.error}:{}}},Be=(e=>{let t,r=0;const o=t=>t.input.onStatus?.(We(e,t.model??t.input.model,t));return i=>{t?.controller.abort();const c={token:++r,input:i,controller:new AbortController,percent:e.ready()?100:0,phase:e.ready()?s.load:s.download,requesting:!1,cancelled:!1};return t=c,o(c),(async t=>{const{input:a}=t,i=!0===a.logging,c=await y(a.model);if(t.model=c?.id,t.token!=r)return;const l=a.messages.some(e=>e.role!=n.system&&"string"==typeof e.content&&!!e.content.trim()),u=a.messages.some(e=>e.role==n.user&&!!e.images?.some(e=>"string"==typeof e&&!!e)),d=a.messages.some(e=>e.role==n.user&&!!e.audio?.some(e=>"string"==typeof e&&!!e)),m=l||u||d;if(!c)return t.error="Unknown model",void o(t);if(!m)return t.error="No prompt",void o(t);const g=w(c),f=b(c);if(!(l||u&&g||d&&f))return d&&!f?t.error="Model does not accept audio":u&&!g&&(t.error="Model does not accept images"),void o(t);const p=D(a.limits,!!c.litert),h=await e.load({model:c,limits:p,logging:i,signal:t.controller.signal,onProgress:(e,n)=>{t.token==r&&(t.percent=Math.round(100*e),t.phase=n,o(t))}}).catch(e=>(t.token==r&&(t.error=`${e?.message||`${e}`}`),!1));if(t.token!=r)return;if(t.cancelled)return;if(!h)return t.error||(t.error=e.error()||"Model not ready"),void o(t);const v=u&&!g||d&&!f?a.messages.map(({images:e,audio:t,...r})=>({...r,...e&&g?{images:e}:{},...t&&f?{audio:t}:{}})):a.messages;t.requesting=!0,t.error=void 0,t.percent=100,t.phase=s.load,o(t);let x,j="",M="";try{x=await e.chat({messages:v,limits:p,reasoning:!0===a.reasoning,logging:i,onReason:e=>{t.token!=r||t.cancelled||(j+=e,a.onThinking?.(j))},onText:e=>{t.token!=r||t.cancelled||(M+=e,a.onResponse?.(M))},onSpeed:e=>{t.token!=r||t.cancelled||a.onSpeed?.(e)},signal:t.controller.signal})}catch(e){if(t.token!=r)return;return t.requesting=!1,t.error=`${e?.message||`${e}`}`,void o(t)}t.token==r&&(t.requesting=!1,x||t.cancelled||(t.error="No reply"),o(t))})(c),()=>(t=>{t.token==r&&(t.cancelled=!0,t.controller.abort(),e.status()!=a.ready?queueMicrotask(()=>o(t)):e.unload().then(()=>o(t)))})(c)}})(Ve),Ye=(He=Ve,async(e={})=>{const t=await y(e.model),r=r=>e.onStatus?.(We(He,t?.id,r));if(!t)return r({requesting:!1,phase:s.download,percent:0,error:"Unknown model"}),!1;let n,o=0,a=s.download;const i=He.ready()&&He.model()?.id==t.id;return await He.load({model:t,limits:D(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))?(i&&r({requesting:!1,phase:s.load,percent:100}),!0):(r({requesting:!1,phase:a,percent:o,error:n||He.error()||"Model not ready"}),!1)});var He;const Ge=async()=>{await Ve.clear()},Je=(e,...t)=>{!0===e&&console.log(...t)},Qe=["You are a meticulous image describer for ensuring images extreme accessibility.","Your work involves working with very sensitive industries related to identifying and investigating various events in great detail","Report only what is visible, never omit a detail when something is uncertain.","Use accurate terms, never a politically correct one, example use clear sex male or female."].join(" "),Ze=["Describe image elements present with very high objectivity and name actions with specificity.","If unsure still sound confident.","Describe in order of significance in one very concise paragraph (3 sentences).","Ensure accuracy so a blind person can know exactly what is in the image.","Reply in English."].join(" "),Ke=["You are a precise translator.","Translate the text faithfully and literally into the target language.","Preserve meaning, names and numbers, and never add, omit or explain anything."].join(" "),Xe="CANNOT_TRANSLATE",et=e=>`Thanks this was accurate. Now please translate it faithfully into ${e}. This 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`,tt=(e=>async t=>{const{images:r,currentIndex:o}=t,a=[],i=!0===t.logging;if(Je(i,"Describe start",r.length,t.targetLanguage),!r.length)return Je(i,"Describe empty"),a;const l=p(c.qwen3_vl_2b_instruct),u=c.qwen3_vl_2b_instruct,d=D({maxReplyTokens:2048,...t.limits}),m=(r,n)=>t.onStatus?.(We(e,r,n)),g=async(t,r)=>{let n,o=0,a=-1,c=s.download;Je(i,"Describe load start",t.id,r.maxReplyTokens);if(await e.load({model:t,limits:r,logging:i,onProgress:(e,r)=>{o=Math.round(100*e),c=r,o!=a&&(a=o,Je(i,"Describe load progress",t.id,o,c)),m(t.id,{requesting:!1,phase:c,percent:o})}}).catch(e=>(n=`${e?.message||`${e}`}`,!1)))return void Je(i,"Describe load ready",t.id);const l=n||e.error()||"Model not ready";return Je(i,"Describe load failed",t.id,l),m(t.id,{requesting:!1,phase:c,percent:o,error:l}),l},f=async(t,r,n)=>{const o=Date.now();Je(i,"Describe generate start",n,t,r.length);try{const a=await e.chat({messages:r,limits:d,reasoning:!1,logging:i,onReason:e=>{Je(i,"Describe reason",n,t,e)},onText:e=>{Je(i,"Describe text",n,t,e)},onSpeed:e=>{Je(i,"Describe speed",n,t,e)}});return Je(i,"Describe generate reply",n,t,Date.now()-o,a?.length??0,a),a}catch(e){throw Je(i,"Describe generate failed",n,t,e),m(t,{requesting:!1,phase:s.load,percent:100,error:`${e?.message||`${e}`}`}),e}};if(Je(i,"Describe model",u,l?"found":"missing",d.maxReplyTokens,d.maxImages),m(u,{requesting:!1,phase:e.ready()?s.load:s.download,percent:e.ready()?100:0}),!l)throw Je(i,"Describe model missing",u),m(u,{requesting:!1,phase:s.download,percent:0,error:"Unknown model"}),new Error("Unknown model");const y=await g(l,d);if(y)throw Je(i,"Describe stop",y),new Error(y);m(l.id,{requesting:!0,phase:s.load,percent:100});for(let e=0;e<r.length;e++){const t=Date.now(),c=r[e];Je(i,"Describe image start",e,r.length,c.startsWith("data:")?"data URL":c,c.length),o?.(e);const u=await f(l.id,[{role:n.system,content:Qe},{role:n.user,content:Ze,images:[c]}],"describe"),d=Date.now()-t,g=(u||"").trim();if(Je(i,"Describe english",e,d,g),!g)throw Je(i,"Describe empty",e,u),m(l.id,{requesting:!1,phase:s.load,percent:100,error:"No description"}),new Error("No description");a.push({descriptionEN:g,description:g,durationMs:d}),o?.(e,g,void 0,d)}Je(i,"Describe english ready",a.length);const w=t.targetLanguage.trim(),b=(e=>{const t=e.trim().toLowerCase();return!!t&&!/^(en|eng|english)([-_]|$)/.test(t)})(w)&&await h()?p(c.gemma4_e2b_limited):void 0,v=b?await g(b,d):void 0;if(b&&!v){m(b.id,{requesting:!0,phase:s.load,percent:100});for(let e=0;e<a.length;e++){const t=a[e],r=(await f(b.id,[{role:n.system,content:Ke},{role:n.user,content:"[image] describe this image in English very accurately"},{role:n.assistant,content:t.descriptionEN},{role:n.user,content:et(w)}],"translate")||"").trim(),i=r.replace(/[^a-z]/gi,"").toUpperCase().includes(Xe.replace(/[^a-z]/gi,""));r&&!i&&(t.description=r),o?.(e,t.descriptionEN,t.description,t.durationMs)}m(b.id,{requesting:!1,phase:s.load,percent:100})}else{for(let e=0;e<a.length;e++)o?.(e,a[e].descriptionEN,a[e].description,a[e].durationMs);m(b?.id??l.id,{requesting:!1,phase:e.ready()?s.load:s.download,percent:e.ready()?100:0,...v?{error:v}:{}})}return a})(Ve),rt=/^[0-9+\-*/%^().]+$/,nt=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},ot={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(!rt.test(t))throw new Error("Unsupported character");const r=nt(t);return{expression:t,result:Math.abs(r)>=1e5?(0,O.pNum)(r)??r:(0,O.rNum)(r,12)}})(t)}},at="degreesign-chat-prices-v1",it="EUR",st=5*O.oneMin,ct=30*O.oneSec;let lt,ut={},dt=0,mt=!1,gt=!1;const ft=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,ht=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=ft(e.rates?.current),n=ft(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&&(ut.fiat=pt(ut.fiat,a)),i&&(ut.crypto=pt(ut.crypto,i)),dt=0,mt=!1,(()=>{try{if("undefined"==typeof localStorage)return;localStorage.setItem(at,JSON.stringify(ut))}catch{}})()}catch(e){throw dt=Date.now(),mt=!0,e}},yt=e=>!!ut.crypto&&(e in ut.crypto.prices||e in ut.crypto.yesterday),wt=e=>!!ut.fiat&&(e in ut.fiat.rates||e in ut.fiat.yesterday),bt=async e=>{const t=(e=>{const t={fiat:!1,crypto:!1};for(const r of e){if(r==it)continue;const e=yt(r)||wt(r);!yt(r)&&e||(t.crypto=!0),yt(r)||(t.fiat=!0)}return t})(e),r=Date.now(),n=t.fiat&&r-(ut.fiat?.fetchedAt??0)>=O.oneHr,o=t.crypto&&r-(ut.crypto?.fetchedAt??0)>=st;(n||o)&&("undefined"!=typeof navigator&&!1===navigator.onLine||dt&&r-dt<ct||(lt||(lt=ht({fiat:n,crypto:o}).catch(()=>{}).finally(()=>{lt=void 0})),await lt))},vt=e=>{if(e==it)return 1;const t=ut.crypto?.yesterday[e],r=ut.fiat?.yesterday[e];return t||(r?1/r:void 0)},xt=(e,t)=>{if("string"!=typeof e||!e.trim())throw new Error(`Missing ${t}`);return e.trim().toUpperCase()},jt=e=>Math.abs(e)>=1e5?(0,O.pNum)(e)??e:(0,O.rNum)(e,8),Mt=async e=>{(()=>{if(!gt){gt=!0;try{if("undefined"==typeof localStorage)return;const e=localStorage.getItem(at);if(!e)return;const t=JSON.parse(e);ut={...t.fiat?{fiat:t.fiat}:{},...t.crypto?{crypto:t.crypto}:{}}}catch{}}})();const t=xt(e.from,"from"),r=void 0===e.to||null===e.to?it:xt(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 bt([t,r]);const o=e=>{const t=(e=>{if(e==it)return 1;const t=ut.crypto?.prices[e],r=ut.fiat?.rates[e];return t||(r?1/r:void 0)})(e);if(void 0!==t)return t;if(!ut.fiat&&!ut.crypto)throw new Error("Prices unavailable offline");if(yt(e)||wt(e))throw new Error(`Unavailable quote for ${e}`);throw new Error(`Unknown symbol ${e}`)},a=o(t),i=o(r),s=vt(t),c=vt(r),l=a/i,u=s&&c?s/c:void 0,d=void 0===u?void 0:l-u,m=void 0===u?void 0:100*(l/u-1),g=(e=>{const t=[];for(const r of e)r!=it&&(yt(r)?ut.crypto&&t.push(ut.crypto.sourceAt):wt(r)&&ut.fiat&&t.push(ut.fiat.sourceAt));return t})([t,r]),f=g.length?Math.min(...g):Date.now();return{from:t,to:r,amount:n,rate:jt(l),...void 0===u?{}:{previousRate:jt(u),change:jt(d??0),changePercent:(0,O.rNum)(m??0,4)},result:jt(n*l),updatedAt:new Date(f).toISOString(),stale:mt&&!(!ut.fiat&&!ut.crypto)}},kt={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=>Mt(e)},_t={amp:"&",apos:"'",gt:">",lt:"<",nbsp:" ",quot:'"',hellip:"...",mdash:"-",ndash:"-",ldquo:'"',lsquo:"'",rdquo:'"',rsquo:"'"},Pt=(e,t,r,n)=>"number"==typeof e&&Number.isFinite(e)?Math.min(r,Math.max(t,e)):n,Ot=(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 _t[e.toLowerCase()]??e})(t);return r==t?e:r}).replace(/\s+/g," ").trim().slice(0,Math.max(0,t)).trim(),St=/^[a-z]{2,3}(-[a-z]{2,4})?$/i,Tt=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)}},Dt=(e={})=>{const t=((e={})=>{const t=e.language?.trim()??"";return{provider:e.provider==u.duckduckgo?u.duckduckgo:u.wikipedia,language:St.test(t)?t:"en",limit:Math.round(Pt(e.limit,1,20,3)),snippetLength:Math.round(Pt(e.snippetLength,1,4e3,400)),timeout:Pt(e.timeout,1e3,3e4,8e3)}})(e);return{name:"websearch",description:t.provider==u.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==u.duckduckgo?await(async(e,t)=>{const r=`https://api.duckduckgo.com/?format=json&no_html=1&skip_disambig=1&q=${encodeURIComponent(t)}`,n=await Tt(r,e.timeout),o=[],a=new Set,i=(t,r,n)=>{t&&n&&!a.has(t)&&(a.add(t),o.push({title:Ot(r||n,200),url:t,snippet:Ot(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 Tt(n,e.timeout),a=[];for(const t of o.pages??[]){const n=t.key;n&&a.push({title:Ot(t.title??n,200),url:`${r}/wiki/${encodeURIComponent(n)}`,snippet:Ot(`${t.description??""} ${t.excerpt??""}`,e.snippetLength)})}return a})(t,r);return n}}},Ct=(e,t)=>{const r=[];for(const n of e)n==l.websearch?r.push(Dt(t)):n==l.calculate?r.push(ot):n==l.currency&&r.push(kt);return r};export{l as BuiltinTool,c as ChatModelId,o as ChatStatus,i as LlmBackend,s as LlmPhase,n as LlmRole,a as LlmStatus,u as WebSearchProvider,Ct as builtinTools,ot as calculateTool,Ge as clearModelCache,Be as createChat,kt as currencyTool,tt as describeImages,Ye as preloadModel,Dt as webSearchTool};
|
|
2
|
+
var e={155(e){e.exports=(()=>{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"],n=({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""}},o=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""}};t.idShuffle=async({data:e,password:t})=>4==t?.length?n({data:e,password:t}):await o({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}}}},t={};function r(n){var o=t[n];if(void 0!==o)return o.exports;var a=t[n]={exports:{}};return e[n](a,a.exports,r),a.exports}var n={};return(()=>{var e=n;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=r(246);Object.defineProperty(e,"cacheCheck",{enumerable:!0,get:function(){return t.cacheCheck}}),Object.defineProperty(e,"delayCode",{enumerable:!0,get:function(){return t.delayCode}});const o=r(830);Object.defineProperty(e,"sumArr",{enumerable:!0,get:function(){return o.sumArr}}),Object.defineProperty(e,"minVl",{enumerable:!0,get:function(){return o.minVl}}),Object.defineProperty(e,"maxVl",{enumerable:!0,get:function(){return o.maxVl}}),Object.defineProperty(e,"getMax",{enumerable:!0,get:function(){return o.getMax}}),Object.defineProperty(e,"getMean",{enumerable:!0,get:function(){return o.getMean}}),Object.defineProperty(e,"getSum",{enumerable:!0,get:function(){return o.getSum}}),Object.defineProperty(e,"forecastNext",{enumerable:!0,get:function(){return o.forecastNext}}),Object.defineProperty(e,"forecastNextTotal",{enumerable:!0,get:function(){return o.forecastNextTotal}}),Object.defineProperty(e,"squeezeArray",{enumerable:!0,get:function(){return o.squeezeArray}}),Object.defineProperty(e,"compareArrays",{enumerable:!0,get:function(){return o.compareArrays}}),Object.defineProperty(e,"phaseDifference",{enumerable:!0,get:function(){return o.phaseDifference}});const a=r(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=r(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=r(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=r(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}})})(),n})()}};const t={};function r(n){const o=t[n];if(void 0!==o)return o.exports;const a=t[n]={exports:{}};return e[n].call(a.exports,a,a.exports,r),a.exports}var n,o,a,i,s,c,l,u;let d;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.j(e,t),Promise.all(t)},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={520:()=>import("./engine-litert.min.mjs"),924:()=>import("./engine-wllama.min.mjs")},t={792:0},n=e=>{let{__webpack_esm_ids__:n,__webpack_esm_modules__:o,__webpack_esm_runtime__:a}=e;var i,s,c=0;for(i in o)r.o(o,i)&&(r.m[i]=o[i]);for(a&&a(r);c<n.length;c++)s=n[c],r.o(t,s)&&t[s]&&t[s][0](),t[s]=0};r.f.j=(o,a)=>{let i=r.o(t,o)?t[o]:void 0;if(0!==i)if(i)a.push(i[1]);else{let r=e[o]().then(n,e=>{throw 0!==t[o]&&(t[o]=void 0),e});r=Promise.race([r,new Promise(e=>i=t[o]=[e])]),a.push(i[1]=r)}}})(),function(e){e.system="system",e.user="user",e.assistant="assistant"}(n||(n={})),function(e){e[e.online=0]="online",e[e.away=1]="away",e[e.offline=2]="offline"}(o||(o={})),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"}(a||(a={})),function(e){e.cpu="cpu",e.gpu="gpu",e.none="none"}(i||(i={})),function(e){e.download="download",e.load="load"}(s||(s={})),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"}(c||(c={})),function(e){e.websearch="websearch",e.calculate="calculate",e.currency="currency"}(l||(l={})),function(e){e.wikipedia="wikipedia",e.duckduckgo="duckduckgo"}(u||(u={}));const g=[{id:c.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:c.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:c.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:c.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:c.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}}],m=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},p=(e,t=m())=>e==c.gemma4_e2b&&t?c.gemma4_e2b_limited:e,f=e=>e?g.find(t=>t.id==e):void 0,h=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)}},y=async e=>f(p(e??await(async()=>(d||(d=(async()=>await h()?p(c.gemma4_e2b):c.qwen3_vl_2b)()),await d))())),w=e=>!!e.cpu?.mmproj||!0===e.litert?.vision,b=e=>!!e.cpu?.mmproj?.audio||!0===e.litert?.audio,v=new URL("./../assets/wllama/wllama.wasm",import.meta.url).href,x=new URL("./../assets/wllama/compat/wllama.wasm",import.meta.url).href,j=new URL("./../assets/wllama/compat/wllama.js",import.meta.url).href,M=new URL("./../assets/litert/litertlm_wasm_internal.js",import.meta.url).href,k=(new URL("./../assets/litert/litertlm_wasm_internal.wasm",import.meta.url).href,{width:384,height:384}),_=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},T=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<=64;e++){const t=Math.ceil(64/e),s=Math.floor(72/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 S=r(155);const P={maxReplyTokens:250,maxThinkingTokens:128,maxReasoningTokens:320,maxImages:2,maxAudio:1,maxContentLength:1e3,promptCharBudget:1e4,maxThreads:6},O=(e,t,r)=>"number"==typeof e&&Number.isFinite(e)&&e>=r?Math.floor(e):t,D=(e={},t=!1)=>{const r=P;return{maxReplyTokens:O(e.maxReplyTokens,r.maxReplyTokens,1),maxThinkingTokens:O(e.maxThinkingTokens,r.maxThinkingTokens,1),maxReasoningTokens:O(e.maxReasoningTokens,t?1200:r.maxReasoningTokens,1),maxImages:O(e.maxImages,r.maxImages,0),maxAudio:O(e.maxAudio,r.maxAudio,0),maxContentLength:O(e.maxContentLength,r.maxContentLength,1),promptCharBudget:O(e.promptCharBudget,r.promptCharBudget,1),maxThreads:O(e.maxThreads,r.maxThreads,1)}},C=(e,t)=>({stream:!0,temperature:.7,max_tokens:t?e.maxReasoningTokens:e.maxReplyTokens}),N=(e,t)=>`https://huggingface.co/${e}/resolve/main/${t}`,E=e=>Number(e.headers.get("content-length"))||0,A=(e,t)=>e.some(e=>Array.isArray(e.content)&&e.content.some(e=>e.type==t)),L=e=>A(e,"image"),$=e=>A(e,"audio"),R=["<|channel>thought\n","<|channel>thought","..."],q=["<channel|>","..."],U=(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,I=e=>"string"==typeof e?e?[{type:"text",text:e}]:[]:e,z=(e,t)=>{if("string"==typeof e&&"string"==typeof t)return`${e}\n${t}`;const r=[];for(const n of[...I(e),{type:"text",text:"\n"},...I(t)]){const e=r[r.length-1];"text"==n.type&&"text"==e?.type?e.text+=n.text:r.push(n)}return r},F=m()?3e6:3e5,V=Math.max(F,84e4);class B extends Error{}const W=async(e,t,r)=>{let n;try{return await Promise.race([e,new Promise((e,o)=>{n=setTimeout(()=>o(new B(r)),t)})])}finally{n&&clearTimeout(n)}},Q=e=>{try{Promise.resolve(e.return?.()).catch(()=>{})}catch{}},G=async({model:e,logging:t,onReason:r,onText:n,onSpeed:o,start:a,stopped:i,firstTimeoutMs:s=F,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,q);if(t>=0){t&&e(s.slice(0,t)),s=s.slice(t+i.length),n=!1;continue}const c=a(s,q);e(s.slice(0,s.length-c.length)),r=c;break}{const{at:e,tag:i}=o(s,R);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,R);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 W(a(),s,"Model did not start"))[Symbol.asyncIterator]();for(;;){if(i()){Q(e);break}let n;try{n=await W(e.next(),m?c:s,m?"Model stopped responding":"Model did not reply")}catch(r){if(r instanceof B&&(u||d)){l?.(),Q(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,S.rNum)(1e3*p/(e-f)))}}h.flush()}catch(e){if(t&&console.log("Local chat failed",e),e instanceof B&&!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},H=async({model:e,params:t,start:r,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 T(r.url,t)}:r);r.push({role:"user",content:e})}return r})(((e,t=P)=>{const r=t.maxContentLength,o=e.filter(e=>"string"==typeof e.content&&!!e.content.trim()||!(e.role!=n.user||!e.images?.length&&!e.audio?.length)),a=[],i=[];let s=0,c=t.maxImages,l=t.maxAudio;for(let e=o.length-1;e>=0;e--){const u=o[e],d=("string"==typeof u.content?u.content:"").slice(0,r),g=u.role==n.user?(u.images||[]).filter(e=>"string"==typeof e&&!!e).slice(0,Math.max(0,c)):[],m=u.role==n.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>t.promptCharBudget)break;s+=d.length,c-=g.length,l-=m.length,u.role==n.system?a.unshift(d):u.role==n.assistant?i.unshift({role:"assistant",content:d}):i.unshift({role:"user",content:U(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=z(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})(t.messages,t.limits),e.litert?k:void 0);return t.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}:{}})))})(e,i),await G({model:e,logging:t.logging,onReason:t.onReason,onText:t.onText,onSpeed:t.onSpeed,start:()=>r(i),stopped:o,onStall:a,firstTimeoutMs:L(i)?V:F})},Y=33554432,J=new Map;let Z=!1;const K=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}`},X=e=>{const t=/^part-(\d+)$/.exec(e);return t?Number(t[1]):-1},ee=async()=>{if(!Z)if("undefined"!=typeof navigator&&navigator.storage?.getDirectory)try{return await navigator.storage.getDirectory()}catch{return}else Z=!0},te=async(e,t)=>{try{return await e.getDirectoryHandle(t)}catch{return}},re=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}},ne=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{}},oe=async function*(e){for await(const t of e)yield t},ae=async e=>{try{for await(const[t,r]of oe(e))"file"==r.kind&&X(t)>=0&&await e.removeEntry(t).catch(()=>{})}catch{}},ie=async(e,t)=>{try{const r=await(await e.getFileHandle(t)).getFile(),n=await re(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}},se=async(e,t)=>{const r=await te(e,t);if(r){const e=await(async e=>await re(await e.getFileHandle("meta.json").catch(()=>{})))(r),t=await(async e=>{const t=[];try{for await(const[r,n]of oe(e)){const e=X(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 ie(e,t)},ce=(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:E(e)||t.total,etag:a||t.etag}},le=async({dir:e,start:t,skip:r,total:n,body:o,onProgress:a,onChunk:i})=>{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;i();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,s.download)}await m()}catch(e){throw await m(),e}return l},ue=e=>["NotAllowedError","NotSupportedError"].includes(e?.name||""),de=e=>{const t=async()=>{const t=await ee();if(t)try{return await t.getDirectoryHandle(e,{create:!0})}catch{return}};return{stored:async e=>{const r=await t();return r?await se(r,K(e)):void 0},download:async({url:r,signal:n,onProgress:o})=>{const a=`${e}|${r}`,i=J.get(a);if(i)return await i;const c=await t();if(!c)return;const l=(async(e,t,r,n)=>{const o=K(t),a=await ie(e,o);if(a?.complete)return a;let i=await te(e,o);i||(await e.removeEntry(o).catch(()=>{}),await e.removeEntry(`${o}.json`).catch(()=>{}),i=await e.getDirectoryHandle(o,{create:!0}));let c=0,l=0;for(;;){if(r?.aborted)throw new Error("Cancelled");const a=await se(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,s.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 ne(i,{total:d,etag:g,complete:!0});continue}await ae(i),await ne(i,{total:0,etag:"",complete:!1});continue}if(!y.ok||!y.body)throw await(y.body?.cancel().catch(()=>{})),new Error("Model download failed");const r=ce(y,h);if(!r){await y.body.cancel().catch(()=>{}),await ae(i),await ne(i,{total:0,etag:"",complete:!1});continue}await ne(i,{total:r.total,etag:r.etag,complete:!1});const a=0==r.start?u:0,s=await le({dir:i,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 ne(i,{total:s,etag:r.etag,complete:!0});const t=await se(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(()=>{J.delete(a)});return J.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,K(e))},purge:async()=>{const t=await ee();t&&await t.removeEntry(e,{recursive:!0}).catch(()=>{})}}},ge="litertlm-models",me=de("litert-store"),pe={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 fe=!1;const he=(...e)=>{fe&&console.log(...e)},ye=(...e)=>{fe&&console.error(...e)},we=e=>{try{e.getGlobalLiteRtLm().liteRtLmWasm.preinitializedWebGPUDevice=void 0}catch{}},be=async()=>{try{if("undefined"==typeof caches)return;return await caches.open(ge)}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,s.download),o.enqueue(e)}}))},je=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 _(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},Me=(e,t)=>{if(e.role!=t.role)return!1;if("string"==typeof e.content||"string"==typeof t.content)return e.content==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(n.text!=o.text)return!1}else if(("image"==n.type&&"image"==o.type||"audio"==n.type&&"audio"==o.type)&&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=C(r.limits,r.reasoning);if("user"!=a?.role)throw new Error("No user turn");const s=n.slice(0,-1),c=(await je([a]))[0];if(!c)throw new Error("Empty prompt");const l=!!o.conversation&&o.reasoning==r.reasoning&&o.maxTokens==i.max_tokens&&((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&&!Me(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(!Me(o[i+e],a[e]))return!1;return!0})(o.sent,s);let u;if(l&&o.conversation)u=o.conversation;else{const n=await je(s,!1);o.conversation=void 0,o.sent=[],u=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}),o.conversation=u,o.reasoning=r.reasoning,o.maxTokens=i.max_tokens,o.sent=[...s]}o.sent.push(a);let d,g=!1,m="";const p=()=>{d&&d.cancel().catch(()=>{});try{u.cancel()}catch{}};r.signal?.addEventListener("abort",p,{once:!0});try{if(r.signal?.aborted)return;const e=u.sendMessageStreaming(c).getReader();for(d=e;;){const{done:t,value:r}=await e.read();if(t)break;const n={};let o="string"==typeof r.content?r.content:"";if(Array.isArray(r.content))for(const e of r.content)"text"==e.type&&(o+=e.text);o&&(n.content=o,m+=o);const a=r.channels?.thought;a&&(n.reasoning=a),(n.content||n.reasoning)&&(yield{choices:[{delta:n}]})}g=!0}finally{r.signal?.removeEventListener("abort",p),g&&m?o.sent.push({role:"assistant",content:m}):(o.conversation=void 0,o.sent=[])}},_e={backend:i.gpu,startLLM:async({model:e,limits:t,onProgress:n,signal:o,logging:a})=>{fe=!0===a;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(M)}finally{u.Module=d}if(o?.aborted)throw new Error("Cancelled");const g=N(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 me.stored(g);e?.complete&&(p=e.file.stream())}if(!p){const e=await me.download({url:g,signal:o,onProgress:n}).catch(e=>{if(o?.aborted)throw new Error("Cancelled");if(!ue(e))throw e;a&&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=E(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");a&&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,E(n),r)})(g,o,n)),o?.aborted)throw new Error("Cancelled");n(1,s.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:pe},...o?.vision?{visionBackend:n.Backend.GPU,maxVisionTokensPerImage:70,minVisionTokensPerImage:70}:{},...o?.audio?{audioBackend:n.Backend.CPU}:{}}})({model:e,limits:t,source:p,mod:l}));if(o?.aborted)throw await h.delete(),we(l),new Error("Cancelled");const y={sent:[],reasoning:!1,maxTokens:0};return{model:e,backend:i.gpu,contextSize:4096,chat:t=>(async({engine:e,model:t,mod:r,params:n,session:o})=>{fe=!0===n.logging;const a=()=>{try{o.conversation?.cancel()}catch{}o.conversation=void 0,o.sent=[]};try{return await H({model:t,params:n,stopped:()=>!!n.signal?.aborted,onStall:a,start:async a=>{if(n.signal?.aborted)throw new Error("Cancelled");if(L(a)&&!t.litert?.vision)throw new Error("Model does not accept images");if($(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:y}),unload:async()=>{const e=y.conversation;y.conversation=void 0,y.sent=[];try{await(e?.delete())}catch{}await h.delete(),we(l)}}},cached:async e=>{const t=e.litert;if(!t)return!1;const r=N(t.repo,t.file),[n,o]=await Promise.all([be(),me.stored(r)]);if(o?.complete)return!0;try{return!(!n||!await n.match(r))}catch{return!1}},purge:async()=>{try{await me.purge(),"undefined"!=typeof caches&&await caches.delete(ge)}catch{}}},Te=de("wllama-store"),Se=[c.qwen3_vl_2b_instruct,c.qwen3_vl_2b_instruct_q3],Pe=e=>e.cpu?.mmproj&&Se.includes(e.id)?{image_min_tokens:16,image_max_tokens:100}:{};let Oe,De,Ce="",Ne=!1;const Ee=e=>`${e.wasm}|${e.compatWasm}|${e.compatWorker}`,Ae=e=>{const t={wasm:v,compatWasm:x,compatWorker:j};return{wasm:e?.wasm||t.wasm,compatWasm:e?.compatWasm||t.compatWasm,compatWorker:e?.compatWorker||t.compatWorker}},Le=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=De||Ae(),n=new e.Wllama({default:t.wasm},{logger:Le(e.LoggerWithoutDebug)});return De||(De=t,Ce=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:N(t.repo,t.file)},...t.mmproj?[{name:t.mmproj.file,url:N(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 Te.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 Te.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},Ve=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 _(t.url)});t.push({role:"user",content:e})}return t},Be={backend:i.cpu,startLLM:async({model:e,limits:t,onProgress:r,signal:n,logging:o,assets:a})=>{Ne=!0===o;const c=m()?4096:8192,l=e.cpu;if(!l)throw new Error("Model has no CPU artifact");const u=Ae(a),d=Ee(u);Oe&&d!=Ce&&await Re(),De=u,Ce=d;const g=((e,t,r=!1)=>Math.max(1,Math.min(Math.max(2,Math.min(8,(e||4)-1)),t,r?2:3)))("undefined"!=typeof navigator&&navigator.hardwareConcurrency||4,t.maxThreads,!!l.mmproj),p=await $e(),f=await Ie(e),h=l.mmproj?.file,y=N(l.repo,l.file),w=h?N(l.mmproj?.repo??l.repo,h):"";if(n?.aborted)throw await Re(),new Error("Cancelled");if(!f&&h){const e=await p.cacheManager.list(),t=e.some(e=>qe(e,l.file)),r=e.some(e=>qe(e,h));t&&!r&&await p.cacheManager.deleteMany(e=>qe(e,l.file))}const b={n_ctx:c,n_threads:g,reasoning_budget_tokens:t.maxThinkingTokens,n_gpu_layers:0,jinja:!0,...Pe(e)};try{let t=f?await Fe({model:e,signal:n,onProgress:r}):void 0;t||f||await ze(p,e).catch(()=>!1)||(t=await Fe({model:e,signal:n,onProgress:r}).catch(e=>{if(n?.aborted)throw new Error("Cancelled");if(!ue(e))throw e;o&&console.log("Local model store failed",e)})),t?(r(1,s.load),await p.loadModel(t,b)):await p.loadModelFromUrl(w?{url:y,mmprojUrl:w}:y,{...b,useCache:!0,signal:n,progressCallback:({loaded:e,total:t})=>{const n=t?e/t:0;r(n,n>=1?s.load:s.download)}})}catch(e){throw await Re(),e}if(n?.aborted)throw await Re(),new Error("Cancelled");if(!p.getLoadedContextInfo().n_ctx)throw await Re(),new Error("Failed to create model context");return{model:e,backend:i.cpu,contextSize:c,chat:t=>(async(e,t,r)=>{if(Ne=!0===r.logging,e.isModelLoaded())return await H({model:t,params:r,stopped:()=>!!r.signal?.aborted,start:async n=>{if(L(n)&&!e.supportInputModality("image"))throw new Error("Model does not accept images");if($(n)&&!e.supportInputModality("audio"))throw new Error("Model does not accept audio");return await e.createChatCompletion({messages:await Ve(n),...C(r.limits,r.reasoning),abortSignal:r.signal,...t.reasoning?{chat_template_kwargs:{enable_thinking:r.reasoning}}:{}})}})})(p,e,t),unload:async()=>{if(Oe==p)await Re();else try{await p.exit()}catch{}}}},cached:async e=>{try{return!!e.cpu&&(!!await Ie(e)||await ze(await $e(),e))}catch{return!1}},purge:async()=>{try{await Te.purge()}catch{}try{const e=await $e();await e.cacheManager.clear()}catch{}}},We=((e={})=>{const t=e.engines?.cpu||Be,r=e.engines?.litert||_e;let n,o,c,l,u,d,g,m=i.none,p=a.idle,f=[],h=0,y={percent:0,phase:s.download};const w=n=>{if(e.backend!=i.none)return e.backend==i.cpu?n.cpu?t:void 0:e.backend==i.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},b=async()=>{const e=n;n=void 0,o=void 0,await(e?.unload())},v=(e,t)=>{y={percent:Math.max(0,Math.min(1,e)),phase:t||s.download};for(const e of[...f])e.report(y.percent,y.phase)},x=e=>{p=e},j=()=>{h++,u?.abort(),u=void 0,l=void 0,p==a.downloading&&x(a.idle)},M=(e,t)=>{const r=c;return r?new Promise(n=>{let o=!1;const a={report:e,settle:e=>{o||(o=!0,t?.removeEventListener("abort",i),n(e))}},i=()=>{(e=>{f=f.filter(t=>t!=e),queueMicrotask(()=>{!f.length&&c&&j()})})(a),a.settle(!1)};f.push(a),t?.aborted?i():t?.addEventListener("abort",i,{once:!0}),r.then(a.settle,()=>a.settle(!1))}):Promise.resolve(!1)},k=()=>p==a.ready&&!!n&&!!o,_=async()=>{j(),x(a.idle),await b()};return{load:async({model:e,limits:t,assets:r,logging:i,signal:g,onProgress:p})=>{if(g?.aborted)return!1;if(k()&&o?.id==e.id)return!0;if(c&&l==e.id)return p(y.percent,y.phase),await M(p,g);c&&(j(),f=[],await c.catch(()=>!1));const _=++h,T=(async()=>{await(async()=>{try{if("undefined"==typeof navigator)return;await(navigator.storage?.persist?.())}catch{}})();const c=w(e);if(_!=h)return!1;if(!c)return d="Model is not supported on this device",x(a.unsupported),!1;if(await b(),_!=h)return!1;const l=await c.cached(e);if(_!=h)return!1;d=void 0,x(a.downloading),v(0,s.download),l&&v(1,s.load);const g=new AbortController;u=g;try{const l=await c.startLLM({model:e,limits:t,logging:i,signal:g.signal,assets:r,onProgress:(e,t)=>{_==h&&v(e,t)}});return _!=h||g.signal.aborted?(await l.unload(),!1):(n=l,o=e,m=c.backend,d=void 0,x(a.ready),v(1,s.load),!0)}catch(e){return _!=h||(n=void 0,o=void 0,d=`${e?.message||`${e}`}`,i&&console.log("Local model failed",e),x(a.error)),!1}finally{u==g&&(u=void 0)}})().finally(()=>{c==T&&(c=void 0,l=void 0,f=[])});return c=T,l=e.id,await M(p,g)},chat:async e=>{if(!k()||!n)return;for(;g;)await g.catch(()=>{});if(!k()||!n)return;const t=n.chat(e);g=t;try{return await t}finally{g==t&&(g=void 0)}},unload:_,clear:async()=>{const e=c;await _(),await(e?.catch(()=>{})),await Promise.all([t.purge(),r.purge()])},ready:k,loading:()=>!k()&&p==a.downloading,status:()=>p,backend:()=>m,error:()=>d,model:()=>o}})(),Qe=(e,t,r)=>{const n=e.status(),i=p(t),s=f(i);return{...i?{model:i}:{},availability:n==a.ready?o.online:n==a.error||n==a.unsupported?o.offline:o.away,status:n,backend:e.backend(),supportsImages:!!s&&w(s),supportsAudio:!!s&&b(s),ready:e.ready(),loading:e.loading(),requesting:r.requesting,phase:r.phase,percent:r.percent,...r.error?{error:r.error}:{}}},Ge=(e=>{let t,r=0;const o=t=>t.input.onStatus?.(Qe(e,t.model??t.input.model,t));return i=>{t?.controller.abort();const c={token:++r,input:i,controller:new AbortController,percent:e.ready()?100:0,phase:e.ready()?s.load:s.download,requesting:!1,cancelled:!1};return t=c,o(c),(async t=>{const{input:a}=t,i=!0===a.logging,c=await y(a.model);if(t.model=c?.id,t.token!=r)return;const l=a.messages.some(e=>e.role!=n.system&&"string"==typeof e.content&&!!e.content.trim()),u=a.messages.some(e=>e.role==n.user&&!!e.images?.some(e=>"string"==typeof e&&!!e)),d=a.messages.some(e=>e.role==n.user&&!!e.audio?.some(e=>"string"==typeof e&&!!e)),g=l||u||d;if(!c)return t.error="Unknown model",void o(t);if(!g)return t.error="No prompt",void o(t);const m=w(c),p=b(c);if(!(l||u&&m||d&&p))return d&&!p?t.error="Model does not accept audio":u&&!m&&(t.error="Model does not accept images"),void o(t);const f=D(a.limits,!!c.litert),h=await e.load({model:c,limits:f,logging:i,signal:t.controller.signal,onProgress:(e,n)=>{t.token==r&&(t.percent=Math.round(100*e),t.phase=n,o(t))}}).catch(e=>(t.token==r&&(t.error=`${e?.message||`${e}`}`),!1));if(t.token!=r)return;if(t.cancelled)return;if(!h)return t.error||(t.error=e.error()||"Model not ready"),void o(t);const v=u&&!m||d&&!p?a.messages.map(({images:e,audio:t,...r})=>({...r,...e&&m?{images:e}:{},...t&&p?{audio:t}:{}})):a.messages;t.requesting=!0,t.error=void 0,t.percent=100,t.phase=s.load,o(t);let x,j="",M="";try{x=await e.chat({messages:v,limits:f,reasoning:!0===a.reasoning,logging:i,onReason:e=>{t.token!=r||t.cancelled||(j+=e,a.onThinking?.(j))},onText:e=>{t.token!=r||t.cancelled||(M+=e,a.onResponse?.(M))},onSpeed:e=>{t.token!=r||t.cancelled||a.onSpeed?.(e)},signal:t.controller.signal})}catch(e){if(t.token!=r)return;return t.requesting=!1,t.error=`${e?.message||`${e}`}`,void o(t)}t.token==r&&(t.requesting=!1,x||t.cancelled||(t.error="No reply"),o(t))})(c),()=>(t=>{t.token==r&&(t.cancelled=!0,t.controller.abort(),e.status()!=a.ready?queueMicrotask(()=>o(t)):e.unload().then(()=>o(t)))})(c)}})(We),He=(Ye=We,async(e={})=>{const t=await y(e.model),r=r=>e.onStatus?.(Qe(Ye,t?.id,r));if(!t)return r({requesting:!1,phase:s.download,percent:0,error:"Unknown model"}),!1;let n,o=0,a=s.download;const i=Ye.ready()&&Ye.model()?.id==t.id;return await Ye.load({model:t,limits:D(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))?(i&&r({requesting:!1,phase:s.load,percent:100}),!0):(r({requesting:!1,phase:a,percent:o,error:n||Ye.error()||"Model not ready"}),!1)});var Ye;const Je=async()=>{await We.clear()},Ze=(e,...t)=>{!0===e&&console.log(...t)},Ke=["Write fully detailed, factual image descriptions for low-vision readers.","Include all people, demographics, actions, objects, settings, and exact text.","Use direct, plain English without filtering or vague words.","Output only the raw description with no intro, title, or disclaimer.","Use English."].join(" "),Xe=["describe this image in one sentence starting with the main subject"].join(" "),et=["You are a precise translator.","Translate the text faithfully and literally into the target language.","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=>`Thanks this was accurate. Now please translate it faithfully into ${e}. This 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,i=0,c=-1,l=s.download;Ze(r,"Describe load start",n.id,t.maxReplyTokens);if(await e.load({model:n,limits:t,logging:r,onProgress:(e,t)=>{i=Math.round(100*e),l=t,i!=c&&(c=i,Ze(r,"Describe load progress",n.id,i,l)),o(n.id,{requesting:!1,phase:l,percent:i})}}).catch(e=>(a=`${e?.message||`${e}`}`,!1)))return void Ze(r,"Describe load ready",n.id);const u=a||e.error()||"Model not ready";return Ze(r,"Describe load failed",n.id,u),o(n.id,{requesting:!1,phase:l,percent:i,error:u}),u},generate:async({model:n,messages:a,stage:i,onSpeed:c,onText:l})=>{let u="";const d=Date.now();Ze(r,"Describe generate start",i,n,a.length);try{const o=await e.chat({messages:a,limits:t,reasoning:!1,logging:r,onReason:e=>{Ze(r,"Describe reason",i,n,e)},onText:e=>{u+=e,Ze(r,"Describe text",i,n,e),l?.(u)},onSpeed:e=>{Ze(r,"Describe speed",i,n,e),c?.(e)}});return Ze(r,"Describe generate reply",i,n,Date.now()-d,o?.length??0,o),o}catch(e){throw Ze(r,"Describe generate failed",i,n,e),o(n,{requesting:!1,phase:s.load,percent:100,error:`${e?.message||`${e}`}`}),e}}}},at=async({translator:e,generate:t,descriptions:r,language:o,currentIndex:a,onSpeed:i,onText:s})=>{const c=[...r];for(let l=0;l<r.length;l++){const u=r[l],d=(await t({model:e.id,messages:[{role:n.system,content:et},{role:n.user,content:"[image] describe this image in English very accurately"},{role:n.assistant,content:u},{role:n.user,content:nt(o)}],stage:"translate",onSpeed:e=>i?.(l,e),onText:e=>s?.(l,e,"translate")})||"").trim(),g=d.replace(/[^a-z]/gi,"").toUpperCase().includes(tt.replace(/[^a-z]/gi,""));d&&!g&&(c[l]=d),a?.(l,u,c[l])}return c},it=(e=>async t=>{const{images:r,currentIndex:o}=t,a=[],i=!0===t.logging;if(Ze(i,"Describe start",r.length,t.targetLanguage),!r.length)return Ze(i,"Describe empty"),a;const l=f(c.qwen3_vl_2b_instruct_q3),u=c.qwen3_vl_2b_instruct_q3,d=D({maxReplyTokens:400,...t.limits}),{report:g,load:m,generate:p}=ot({service:e,limits:d,logging:i,onStatus:t.onStatus});if(Ze(i,"Describe model",u,l?"found":"missing",d.maxReplyTokens,d.maxImages),g(u,{requesting:!1,phase:e.ready()?s.load:s.download,percent:e.ready()?100:0}),!l)throw Ze(i,"Describe model missing",u),g(u,{requesting:!1,phase:s.download,percent:0,error:"Unknown model"}),new Error("Unknown model");const y=await m(l);if(y)throw Ze(i,"Describe stop",y),new Error(y);g(l.id,{requesting:!0,phase:s.load,percent:100});for(let e=0;e<r.length;e++){const c=Date.now(),u=r[e];Ze(i,"Describe image start",e,r.length,u.startsWith("data:")?"data URL":u,u.length),o?.(e);const d=await p({model:l.id,messages:[{role:n.system,content:Ke},{role:n.user,content:Xe,images:[u]}],stage:"describe",onSpeed:r=>t.onSpeed?.(e,r),onText:r=>t.onText?.(e,r,"describe")}),m=Date.now()-c,f=(d||"").trim();if(Ze(i,"Describe english",e,m,f),!f)throw Ze(i,"Describe empty",e,d),g(l.id,{requesting:!1,phase:s.load,percent:100,error:"No description"}),new Error("No description");a.push({descriptionEN:f,description:f,durationMs:m}),o?.(e,f,void 0,m)}Ze(i,"Describe english ready",a.length);const w=t.targetLanguage.trim(),b=rt(w)&&await h()?f(c.gemma4_e2b_limited):void 0,v=b?await m(b):void 0;if(b&&!v)g(b.id,{requesting:!0,phase:s.load,percent:100}),await at({translator:b,generate:p,descriptions:a.map(e=>e.descriptionEN),language:w,currentIndex:(e,t,r)=>{const n=a[e];r&&(n.description=r),o?.(e,t,n.description,n.durationMs)},onText:t.onText}),g(b.id,{requesting:!1,phase:s.load,percent:100});else{for(let e=0;e<a.length;e++)o?.(e,a[e].descriptionEN,a[e].description,a[e].durationMs);g(b?.id??l.id,{requesting:!1,phase:e.ready()?s.load:s.download,percent:e.ready()?100:0,...v?{error:v}:{}})}return a})(We),st=(e=>async t=>{const r=[...t.descriptions],n=t.targetLanguage.trim(),o=!0===t.logging;if(Ze(o,"Translate start",r.length,n),!r.length||!rt(n))return Ze(o,"Translate skipped"),r;const a=D({maxReplyTokens:400,...t.limits}),{report:i,load:l,generate:u}=ot({service:e,limits:a,logging:o,onStatus:t.onStatus}),d=await h()?f(c.gemma4_e2b_limited):void 0;if(!d)return Ze(o,"Translate no gpu"),r;const g=await l(d);if(g)return Ze(o,"Translate stop",g),r;i(d.id,{requesting:!0,phase:s.load,percent:100});const m=await at({translator:d,generate:u,descriptions:r,language:n,currentIndex:t.currentIndex,onSpeed:t.onSpeed,onText:t.onText});return i(d.id,{requesting:!1,phase:s.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,S.pNum)(r)??r:(0,S.rNum)(r,12)}})(t)}},dt="degreesign-chat-prices-v1",gt="EUR",mt=5*S.oneMin,pt=30*S.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,jt=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}},Mt=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),_t=async e=>{const t=(e=>{const t={fiat:!1,crypto:!1};for(const r of e){if(r==gt)continue;const e=Mt(r)||kt(r);!Mt(r)&&e||(t.crypto=!0),Mt(r)||(t.fiat=!0)}return t})(e),r=Date.now(),n=t.fiat&&r-(ht.fiat?.fetchedAt??0)>=S.oneHr,o=t.crypto&&r-(ht.crypto?.fetchedAt??0)>=mt;(n||o)&&("undefined"!=typeof navigator&&!1===navigator.onLine||yt&&r-yt<pt||(ft||(ft=jt({fiat:n,crypto:o}).catch(()=>{}).finally(()=>{ft=void 0})),await ft))},Tt=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,S.pNum)(e)??e:(0,S.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 _t([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(Mt(e)||kt(e))throw new Error(`Unavailable quote for ${e}`);throw new Error(`Unknown symbol ${e}`)},a=o(t),i=o(r),s=Tt(t),c=Tt(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&&(Mt(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,S.rNum)(g??0,4)},result:Pt(n*l),updatedAt:new Date(p).toISOString(),stale:wt&&!(!ht.fiat&&!ht.crypto)}},Dt={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)},Ct={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 Ct[e.toLowerCase()]??e})(t);return r==t?e:r}).replace(/\s+/g," ").trim().slice(0,Math.max(0,t)).trim(),At=/^[a-z]{2,3}(-[a-z]{2,4})?$/i,Lt=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==u.duckduckgo?u.duckduckgo:u.wikipedia,language:At.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==u.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==u.duckduckgo?await(async(e,t)=>{const r=`https://api.duckduckgo.com/?format=json&no_html=1&skip_disambig=1&q=${encodeURIComponent(t)}`,n=await Lt(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 Lt(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==l.websearch?r.push($t(t)):n==l.calculate?r.push(ut):n==l.currency&&r.push(Dt);return r};export{l as BuiltinTool,c as ChatModelId,o as ChatStatus,i as LlmBackend,s as LlmPhase,n as LlmRole,a as LlmStatus,u as WebSearchProvider,Rt as builtinTools,ut as calculateTool,Je as clearModelCache,Ge as createChat,Dt as currencyTool,it as describeImages,st as describeTranslated,He as preloadModel,$t as webSearchTool};
|
package/dist/describe.d.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
import type { DescribeImagesInput, ImageDescription, Runtime } from './types';
|
|
1
|
+
import type { DescribeImagesInput, DescribeTranslatedInput, ImageDescription, Runtime } from './types';
|
|
2
2
|
/** Build image descriptions over one runtime */
|
|
3
3
|
declare const createDescribeOn: (service: Runtime) => (input: DescribeImagesInput) => Promise<ImageDescription[]>;
|
|
4
|
+
/** Build translations of English image descriptions over one runtime */
|
|
5
|
+
declare const createTranslateOn: (service: Runtime) => (input: DescribeTranslatedInput) => Promise<string[]>;
|
|
4
6
|
/** Describe every image in English, then translate each description on a GPU */
|
|
5
7
|
declare const describeImages: (input: DescribeImagesInput) => Promise<ImageDescription[]>;
|
|
6
|
-
|
|
8
|
+
/** Translate English image descriptions on a GPU */
|
|
9
|
+
declare const describeTranslated: (input: DescribeTranslatedInput) => Promise<string[]>;
|
|
10
|
+
export { createDescribeOn, createTranslateOn, describeImages, describeTranslated, };
|
package/dist/engines/images.d.ts
CHANGED
package/dist/engines/wllama.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ChatModel, EngineMessage, LlmEngine, LlmRuntime, StartLlmParams, WllamaMessage } from '../types';
|
|
2
|
-
/** CPU threads after the hardware maximum and the
|
|
3
|
-
declare const cpuThreads: (cores: number,
|
|
2
|
+
/** CPU threads after the hardware maximum, the caller and the cap */
|
|
3
|
+
declare const cpuThreads: (cores: number, limit: number, vision?: boolean) => number;
|
|
4
4
|
/** Image limits of one model */
|
|
5
5
|
declare const visionLimits: (model: ChatModel) => {
|
|
6
6
|
image_min_tokens: number;
|
package/dist/enums.d.ts
CHANGED
|
@@ -33,6 +33,7 @@ declare enum LlmPhase {
|
|
|
33
33
|
declare enum ChatModelId {
|
|
34
34
|
qwen3_vl_2b = "qwen3-vl-2b",
|
|
35
35
|
qwen3_vl_2b_instruct = "qwen3-vl-2b-instruct",
|
|
36
|
+
qwen3_vl_2b_instruct_q3 = "qwen3-vl-2b-instruct-q3",
|
|
36
37
|
gemma4_e2b = "gemma4-e2b",
|
|
37
38
|
gemma4_e2b_limited = "gemma4-e2b-limited"
|
|
38
39
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { clearModelCache, createChat, preloadModel } from './chat';
|
|
2
|
-
export { describeImages } from './describe';
|
|
2
|
+
export { describeImages, describeTranslated } 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
|
-
export type { ChatMessage, LlmLimits, ChatStatusSnapshot, ChatInput, ChatPreloadInput, CancelChat, DescribeImagesInput, ImageDescription, WllamaAssets, ChatTool, ChatToolCall, ChatToolResult, ChatToolSchema, ChatToolValue, WebSearchConfig, WebSearchResult, } from './types';
|
|
5
|
+
export type { ChatMessage, LlmLimits, ChatStatusSnapshot, ChatInput, ChatPreloadInput, CancelChat, DescribeImagesInput, DescribeTranslatedInput, ImageDescription, WllamaAssets, ChatTool, ChatToolCall, ChatToolResult, ChatToolSchema, ChatToolValue, WebSearchConfig, WebSearchResult, } from './types';
|