@degreesign/chat 0.9.2 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +65 -31
- package/dist/browser/chat.min.mjs +1 -1
- package/dist/describe.d.ts +6 -2
- package/dist/engines/images.d.ts +17 -8
- package/dist/engines/wllama.d.ts +11 -3
- 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 +23 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -124,13 +124,13 @@ 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,
|
|
128
|
-
|
|
129
|
-
WebGPU engine asks LiteRT for the
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
127
|
+
only to a model with vision support, fits each image to 64 to 72 vision
|
|
128
|
+
tokens, snaps both sides to multiples of 32 px, crops the remainder, and caps
|
|
129
|
+
the number with `limits.maxImages`. The WebGPU engine asks LiteRT for the
|
|
130
|
+
smallest Gemma 4 vision budget (70 tokens, 630 patches), so it center-crops to a
|
|
131
|
+
384 x 384 square instead. On a phone or tablet a Gemma request resolves to
|
|
132
|
+
`gemma4_e2b_limited`, the text-only browser build, so images there go through
|
|
133
|
+
`qwen3_vl_2b` instead.
|
|
134
134
|
|
|
135
135
|
Attach a recording with `audio: [dataUrl]`. Gemma 4 E2B accepts WAV, MP3 and
|
|
136
136
|
FLAC on the desktop WebGPU engine and loads its audio encoder on demand. A short
|
|
@@ -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,14 +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.
|
|
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.
|
|
314
316
|
|
|
315
317
|
The describer and translator each receive a system message that puts accuracy
|
|
316
318
|
first: the describer reports only visible detail and the translator preserves
|
|
@@ -349,6 +351,30 @@ final snapshot has `requesting: false`; when the translator cannot load, it also
|
|
|
349
351
|
carries that error and the descriptions stay English. An empty `images` list
|
|
350
352
|
touches no model and reports nothing.
|
|
351
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
|
+
|
|
352
378
|
## Tools
|
|
353
379
|
|
|
354
380
|
Three built-in tools ship as descriptors. They are not connected to the model:
|
|
@@ -400,11 +426,11 @@ search and currency tools fetch over the network; `calculate` does not.
|
|
|
400
426
|
|
|
401
427
|
The first snapshot fires synchronously inside `createChat`. A final snapshot
|
|
402
428
|
with `requesting: false` marks the end of the call. `describeImages` reports the
|
|
403
|
-
same snapshot for each model it loads: `
|
|
429
|
+
same snapshot for each model it loads: `qwen3_vl_2b_instruct_q3` while it
|
|
404
430
|
describes, then `gemma4_e2b_limited` while it translates.
|
|
405
431
|
|
|
406
|
-
A stream that never produces its first chunk ends with an error after
|
|
407
|
-
seconds, or after
|
|
432
|
+
A stream that never produces its first chunk ends with an error after 360
|
|
433
|
+
seconds, or after 840 seconds when the prompt carries an image, because a CPU
|
|
408
434
|
vision prefill takes minutes. Once a chunk has arrived, 30 seconds of silence
|
|
409
435
|
ends the stream and keeps the text already delivered.
|
|
410
436
|
|
|
@@ -423,6 +449,7 @@ without it goes quiet again.
|
|
|
423
449
|
| ------------- | ---- | --------- | ------ | ----- | --- | ------ |
|
|
424
450
|
| `qwen3_vl_2b` | Qwen3-VL 2B | Yes | Yes | No | Yes | No |
|
|
425
451
|
| `qwen3_vl_2b_instruct` | Qwen3-VL 2B Instruct | No | Yes | No | Yes | No |
|
|
452
|
+
| `qwen3_vl_2b_instruct_q3` | Qwen3-VL 2B Instruct Q3 | No | Yes | No | Yes | No |
|
|
426
453
|
| `gemma4_e2b` | Gemma 4 E2B | Yes | Yes | Yes | No | Yes |
|
|
427
454
|
| `gemma4_e2b_limited` | Gemma 4 E2B limited | Yes | No | No | No | Yes |
|
|
428
455
|
|
|
@@ -444,10 +471,13 @@ context on a phone and 8192 on a desktop. Its projector uses the same CPU thread
|
|
|
444
471
|
budget as the text pass, so image turns are slower than the Gemma 4 WebGPU path.
|
|
445
472
|
Use the GPU model when images need to be fast.
|
|
446
473
|
|
|
447
|
-
`
|
|
448
|
-
`describeImages` loads for the English pass
|
|
449
|
-
|
|
450
|
-
|
|
474
|
+
`qwen3_vl_2b_instruct_q3` is the Unsloth Qwen3-VL 2B Instruct build that
|
|
475
|
+
`describeImages` loads for the English pass, its Q3_K_M file. Both instruct
|
|
476
|
+
builds use Qwen's Q8_0 projector, about 445 MB, so the describer totals about
|
|
477
|
+
1.4 GB on the CPU engine. It has no reasoning pass, so it answers an image
|
|
478
|
+
prompt directly. `qwen3_vl_2b_instruct` is the same model in Q4_K_M, about
|
|
479
|
+
200 MB larger, for a host that prefers the higher precision describer and
|
|
480
|
+
names it explicitly.
|
|
451
481
|
|
|
452
482
|
Gemma 4 E2B downloads `gemma-4-E2B-it.litertlm`, about 2.6 GB, on a desktop. It
|
|
453
483
|
runs on the WebGPU engine with its vision and audio encoders in the same file,
|
|
@@ -485,10 +515,10 @@ user: {next turn}
|
|
|
485
515
|
vision or audio support.
|
|
486
516
|
- Images are collected from the newest turns first and capped by `maxImages`
|
|
487
517
|
(default 2). Older image parts are dropped and their text stays.
|
|
488
|
-
- Every image part
|
|
489
|
-
|
|
490
|
-
engine
|
|
491
|
-
|
|
518
|
+
- Every image part keeps its full frame and targets 64 vision tokens, with at
|
|
519
|
+
most 72. Both sides are snapped to multiples of 32 px and the remainder is
|
|
520
|
+
cropped. The WebGPU engine instead center-crops to a 384 x 384 square, the
|
|
521
|
+
smallest Gemma 4 encoder signature.
|
|
492
522
|
- Audio is collected from the newest turns first and capped by `maxAudio`
|
|
493
523
|
(default 1). Older audio parts are dropped and their text stays. WAV, MP3 and
|
|
494
524
|
FLAC are accepted, and a short 16 kHz mono WAV is the best input.
|
|
@@ -512,9 +542,11 @@ onProgress })` contract and return the runtime object with `model`, `backend`,
|
|
|
512
542
|
matches the requested model.
|
|
513
543
|
|
|
514
544
|
The CPU engine derives a raw thread count from the device, then caps it at
|
|
515
|
-
`limits.maxThreads
|
|
516
|
-
|
|
517
|
-
|
|
545
|
+
`limits.maxThreads` and at 3 threads for a text model or 2 threads for a model
|
|
546
|
+
with a vision projector. The vision cap keeps the wasm image path alive: a
|
|
547
|
+
100-token image completes in about 89 seconds with 2 threads, while 3 threads
|
|
548
|
+
stalled past 10 minutes in the headless check. Every CPU model uses one count
|
|
549
|
+
for the whole load.
|
|
518
550
|
|
|
519
551
|
The CPU engine needs cross-origin isolation for its threads. Serve the page with
|
|
520
552
|
both headers:
|
|
@@ -638,6 +670,7 @@ const useReply = () => {
|
|
|
638
670
|
| `ChatInput` | One request: model, messages, budgets, reasoning and callbacks. |
|
|
639
671
|
| `ChatPreloadInput` | Model, limits, logging and status, the subset `preloadModel` needs. |
|
|
640
672
|
| `DescribeImagesInput` | Target language, images, progress callback, limits and logging. |
|
|
673
|
+
| `DescribeTranslatedInput` | English descriptions, target language, progress callback, limits and logging. |
|
|
641
674
|
| `ImageDescription` | `descriptionEN`, the translated `description` and `durationMs`. |
|
|
642
675
|
| `CancelChat` | The function returned by `createChat`. |
|
|
643
676
|
| `ChatMessage` | One prompt turn, `role`, `content` and optional `images` and `audio`. |
|
|
@@ -672,9 +705,10 @@ Yes, on models with vision support. Put image URLs in a user turn's `images`
|
|
|
672
705
|
array. Qwen3-VL 2B accepts images on the CPU engine and Gemma 4 E2B accepts
|
|
673
706
|
images on the desktop WebGPU engine. On a phone or tablet Gemma resolves to
|
|
674
707
|
`gemma4_e2b_limited`, the text-only browser build, so use `qwen3_vl_2b` for
|
|
675
|
-
mobile images. Each image
|
|
676
|
-
|
|
677
|
-
|
|
708
|
+
mobile images. Each image keeps its full frame and targets 64 vision tokens,
|
|
709
|
+
at most 72, with both sides snapped to multiples of 32 px and the remainder
|
|
710
|
+
cropped. The WebGPU engine instead center-crops a 384 x 384 square with the
|
|
711
|
+
smallest Gemma 4 vision budget. A model without vision drops images
|
|
678
712
|
when the turn also has text; an image-only turn reports
|
|
679
713
|
`Model does not accept images`.
|
|
680
714
|
|
|
@@ -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,288),P=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},O=async e=>{if(!e||"function"!=typeof fetch||"function"!=typeof createImageBitmap)return e;try{const t=await fetch(e),r=await createImageBitmap(await t.blob()),n=Math.min(r.width,r.height),o=Math.floor((r.width-n)/2),a=Math.floor((r.height-n)/2),i=((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})(k,k),s=i?i.getContext("2d"):null;if(!i||!s||n<1)return r.close(),e;if(s.drawImage(r,o,a,n,n,0,0,k,k),r.close(),(e=>"undefined"!=typeof OffscreenCanvas&&e instanceof OffscreenCanvas)(i)){const t=await i.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 i.toDataURL("image/jpeg",.85)}catch{return e}};var _=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,_.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=>{const t=[];for(const r of e){if("string"==typeof r.content){t.push(r);continue}const e=[];for(const t of r.content)e.push("image"==t.type?{type:"image",url:await O(t.url)}:t);t.push({role:"user",content:e})}return t})(((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));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 P(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{}}},Pe=ue("wllama-store");let Oe,_e,Se="",Te=!1;const De=e=>`${e.wasm}|${e.compatWasm}|${e.compatWorker}`,Ce=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}},Ne=e=>{const t=e=>(...t)=>{Te&&("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)}},Ee=async()=>{if(Oe)return Oe;const e=await r.e(924).then(()=>r(577)),t=_e||Ce(),n=new e.Wllama({default:t.wasm},{logger:Ne(e.LoggerWithoutDebug)});return _e||(_e=t,Se=De(t)),n.setCompat({wasm:t.compatWasm,worker:t.compatWorker}),Oe=n,n},Ae=async()=>{const e=Oe;Oe=void 0;try{await(e?.exit())}catch{}},Le=(e,t)=>e.name.includes(t)||!!e.metadata?.originalURL?.includes(t),$e=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)}]:[]]:[]},Re=async e=>{const t=$e(e);if(!t.length)return!1;for(const e of t){const t=await Pe.stored(e.url);if(!t?.complete)return!1}return!0},Ue=async(e,t)=>{const r=await e.cacheManager.list();return $e(t).every(e=>r.some(t=>Le(t,e.name)))},qe=async({model:e,signal:t,onProgress:r})=>{const n=$e(e),o=[];for(let e=0;e<n.length;e++){if(t?.aborted)throw new Error("Cancelled");const a=await Pe.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},ze=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 P(t.url)});t.push({role:"user",content:e})}return t},Fe={backend:i.cpu,startLLM:async({model:e,limits:t,onProgress:r,signal:n,logging:o,assets:a})=>{Te=!0===o;const c=g()?4096:8192,l=e.cpu;if(!l)throw new Error("Model has no CPU artifact");const u=Ce(a),d=De(u);Oe&&d!=Se&&await Ae(),_e=u,Se=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 Ee(),h=await Re(e),y=l.mmproj?.file,w=N(l.repo,l.file),b=y?N(l.repo,y):"";if(n?.aborted)throw await Ae(),new Error("Cancelled");if(!h&&y){const e=await p.cacheManager.list(),t=e.some(e=>Le(e,l.file)),r=e.some(e=>Le(e,y));t&&!r&&await p.cacheManager.deleteMany(e=>Le(e,l.file))}const v={n_ctx:c,n_threads:m,reasoning_budget_tokens:t.maxThinkingTokens,n_gpu_layers:0,jinja:!0};try{let t=h?await qe({model:e,signal:n,onProgress:r}):void 0;t||h||await Ue(p,e).catch(()=>!1)||(t=await qe({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 Ae(),e}if(n?.aborted)throw await Ae(),new Error("Cancelled");if(!p.getLoadedContextInfo().n_ctx)throw await Ae(),new Error("Failed to create model context");return{model:e,backend:i.cpu,contextSize:c,chat:t=>(async(e,t,r)=>{if(Te=!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 ze(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 Ae();else try{await p.exit()}catch{}}}},cached:async e=>{try{return!!e.cpu&&(!!await Re(e)||await Ue(await Ee(),e))}catch{return!1}},purge:async()=>{try{await Pe.purge()}catch{}try{const e=await Ee();await e.cacheManager.clear()}catch{}}},Ie=((e={})=>{const t=e.engines?.cpu||Fe,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,P=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 P=++h,O=(async()=>{await(async()=>{try{if("undefined"==typeof navigator)return;await(navigator.storage?.persist?.())}catch{}})();const c=w(e);if(P!=h)return!1;if(!c)return d="Model is not supported on this device",x(a.unsupported),!1;if(await b(),P!=h)return!1;const l=await c.cached(e);if(P!=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)=>{P==h&&v(e,t)}});return P!=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 P!=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==O&&(c=void 0,l=void 0,p=[])});return c=O,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:P,clear:async()=>{const e=c;await P(),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}})(),Ve=(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}:{}}},We=(e=>{let t,r=0;const o=t=>t.input.onStatus?.(Ve(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)}})(Ie),Be=(Ye=Ie,async(e={})=>{const t=await y(e.model),r=r=>e.onStatus?.(Ve(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 He=async()=>{await Ie.clear()},Ge=(e,...t)=>{!0===e&&console.log(...t)},Je=["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(" "),Qe=["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(" "),Ze=["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(" "),Ke="CANNOT_TRANSLATE",Xe=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`,et=(e=>async t=>{const{images:r,currentIndex:o}=t,a=[],i=!0===t.logging;if(Ge(i,"Describe start",r.length,t.targetLanguage),!r.length)return Ge(i,"Describe empty"),a;const l=p(c.qwen3_vl_2b_instruct),u=c.qwen3_vl_2b_instruct,d=D({maxReplyTokens:16384,...t.limits}),m=(r,n)=>t.onStatus?.(Ve(e,r,n)),g=async(t,r)=>{let n,o=0,a=-1,c=s.download;Ge(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,Ge(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 Ge(i,"Describe load ready",t.id);const l=n||e.error()||"Model not ready";return Ge(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();Ge(i,"Describe generate start",n,t,r.length);try{const a=await e.chat({messages:r,limits:d,reasoning:!1,logging:i,onReason:e=>{Ge(i,"Describe reason",n,t,e)},onText:e=>{Ge(i,"Describe text",n,t,e)},onSpeed:e=>{Ge(i,"Describe speed",n,t,e)}});return Ge(i,"Describe generate reply",n,t,Date.now()-o,a?.length??0,a),a}catch(e){throw Ge(i,"Describe generate failed",n,t,e),m(t,{requesting:!1,phase:s.load,percent:100,error:`${e?.message||`${e}`}`}),e}};if(Ge(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 Ge(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 Ge(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];Ge(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:Je},{role:n.user,content:Qe,images:[c]}],"describe"),d=Date.now()-t,g=(u||"").trim();if(Ge(i,"Describe english",e,d,g),!g)throw Ge(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)}Ge(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:Ze},{role:n.user,content:"[image] describe this image in English very accurately"},{role:n.assistant,content:t.descriptionEN},{role:n.user,content:Xe(w)}],"translate")||"").trim(),i=r.replace(/[^a-z]/gi,"").toUpperCase().includes(Ke.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})(Ie),tt=/^[0-9+\-*/%^().]+$/,rt=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},nt={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(!tt.test(t))throw new Error("Unsupported character");const r=rt(t);return{expression:t,result:Math.abs(r)>=1e5?(0,_.pNum)(r)??r:(0,_.rNum)(r,12)}})(t)}},ot="degreesign-chat-prices-v1",at="EUR",it=5*_.oneMin,st=30*_.oneSec;let ct,lt={},ut=0,dt=!1,mt=!1;const gt=e=>{const t={};for(const[r,n]of Object.entries(e??{}))"number"==typeof n&&Number.isFinite(n)&&(t[r.trim().toUpperCase()]=n);return t},ft=(e,t)=>e&&e.sourceAt>t.sourceAt?e:t,pt=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=gt(e.rates?.current),n=gt(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&&(lt.fiat=ft(lt.fiat,a)),i&&(lt.crypto=ft(lt.crypto,i)),ut=0,dt=!1,(()=>{try{if("undefined"==typeof localStorage)return;localStorage.setItem(ot,JSON.stringify(lt))}catch{}})()}catch(e){throw ut=Date.now(),dt=!0,e}},ht=e=>!!lt.crypto&&(e in lt.crypto.prices||e in lt.crypto.yesterday),yt=e=>!!lt.fiat&&(e in lt.fiat.rates||e in lt.fiat.yesterday),wt=async e=>{const t=(e=>{const t={fiat:!1,crypto:!1};for(const r of e){if(r==at)continue;const e=ht(r)||yt(r);!ht(r)&&e||(t.crypto=!0),ht(r)||(t.fiat=!0)}return t})(e),r=Date.now(),n=t.fiat&&r-(lt.fiat?.fetchedAt??0)>=_.oneHr,o=t.crypto&&r-(lt.crypto?.fetchedAt??0)>=it;(n||o)&&("undefined"!=typeof navigator&&!1===navigator.onLine||ut&&r-ut<st||(ct||(ct=pt({fiat:n,crypto:o}).catch(()=>{}).finally(()=>{ct=void 0})),await ct))},bt=e=>{if(e==at)return 1;const t=lt.crypto?.yesterday[e],r=lt.fiat?.yesterday[e];return t||(r?1/r:void 0)},vt=(e,t)=>{if("string"!=typeof e||!e.trim())throw new Error(`Missing ${t}`);return e.trim().toUpperCase()},xt=e=>Math.abs(e)>=1e5?(0,_.pNum)(e)??e:(0,_.rNum)(e,8),jt=async e=>{(()=>{if(!mt){mt=!0;try{if("undefined"==typeof localStorage)return;const e=localStorage.getItem(ot);if(!e)return;const t=JSON.parse(e);lt={...t.fiat?{fiat:t.fiat}:{},...t.crypto?{crypto:t.crypto}:{}}}catch{}}})();const t=vt(e.from,"from"),r=void 0===e.to||null===e.to?at:vt(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 wt([t,r]);const o=e=>{const t=(e=>{if(e==at)return 1;const t=lt.crypto?.prices[e],r=lt.fiat?.rates[e];return t||(r?1/r:void 0)})(e);if(void 0!==t)return t;if(!lt.fiat&&!lt.crypto)throw new Error("Prices unavailable offline");if(ht(e)||yt(e))throw new Error(`Unavailable quote for ${e}`);throw new Error(`Unknown symbol ${e}`)},a=o(t),i=o(r),s=bt(t),c=bt(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!=at&&(ht(r)?lt.crypto&&t.push(lt.crypto.sourceAt):yt(r)&<.fiat&&t.push(lt.fiat.sourceAt));return t})([t,r]),f=g.length?Math.min(...g):Date.now();return{from:t,to:r,amount:n,rate:xt(l),...void 0===u?{}:{previousRate:xt(u),change:xt(d??0),changePercent:(0,_.rNum)(m??0,4)},result:xt(n*l),updatedAt:new Date(f).toISOString(),stale:dt&&!(!lt.fiat&&!lt.crypto)}},Mt={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=>jt(e)},kt={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 kt[e.toLowerCase()]??e})(t);return r==t?e:r}).replace(/\s+/g," ").trim().slice(0,Math.max(0,t)).trim(),_t=/^[a-z]{2,3}(-[a-z]{2,4})?$/i,St=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)}},Tt=(e={})=>{const t=((e={})=>{const t=e.language?.trim()??"";return{provider:e.provider==u.duckduckgo?u.duckduckgo:u.wikipedia,language:_t.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 St(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 St(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}}},Dt=(e,t)=>{const r=[];for(const n of e)n==l.websearch?r.push(Tt(t)):n==l.calculate?r.push(nt):n==l.currency&&r.push(Mt);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,Dt as builtinTools,nt as calculateTool,He as clearModelCache,We as createChat,Mt as currencyTool,et as describeImages,Be as preloadModel,Tt 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},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<=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 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","..."],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=36e4;class V extends Error{}const B=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)}},W=e=>{try{Promise.resolve(e.return?.()).catch(()=>{})}catch{}},Q=async({model:e,logging:t,onReason:r,onText:n,onSpeed:o,start:a,stopped:i,firstTimeoutMs:s=36e4,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 B(a(),s,"Model did not start"))[Symbol.asyncIterator]();for(;;){if(i()){W(e);break}let n;try{n=await B(e.next(),m?c:s,m?"Model stopped responding":"Model did not reply")}catch(r){if(r instanceof V&&(u||d)){l?.(),W(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,O.rNum)(1e3*p/(e-f)))}}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,g||"none",u.length,d.length)),y},Y=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),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 Q({model:e,logging:t.logging,onReason:t.onReason,onText:t.onText,onSpeed:t.onSpeed,start:()=>r(i),stopped:o,onStall:a,firstTimeoutMs:L(i)?84e4:F})},G=33554432,H=new Map;let J=!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(!J)if("undefined"!=typeof navigator&&navigator.storage?.getDirectory)try{return await navigator.storage.getDirectory()}catch{return}else J=!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 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(G-u,o.byteLength-p);await c.write({type:"write",position:u,data:o.subarray(p,p+e)}),p+=e,u+=e,l+=e,u==G&&await m()}l>t&&a(n?l/n:0,s.download)}await m()}catch(e){throw await m(),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=H.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,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+G,d)-1:u+G-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 re(i,{total:d,etag:g,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(f,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",f)}}})(c,r,n,o).finally(()=>{H.delete(a)});return H.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",ge=ue("litert-store"),me={num_output_candidates:1,wait_for_weight_uploads:!0,num_decode_steps_per_sync:3,sequence_batch_size:0,supported_lora_ranks:[],max_top_k:40,enable_decode_logits:!1,enable_external_embeddings:!1,use_submodel:!1,use_autosized_ringbuffers:!0};let pe=!1;const fe=(...e)=>{pe&&console.log(...e)},he=(...e)=>{pe&&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,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=[])}},ke={backend:i.gpu,startLLM:async({model:e,limits:t,onProgress:n,signal:o,logging:a})=>{pe=!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:fe,printErr:he};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 we();let p;const f=m?await m.match(g):void 0;if(f?.body)p=f.body;else{const e=await ge.stored(g);e?.complete&&(p=e.file.stream())}if(!p){const e=await ge.download({url:g,signal:o,onProgress:n}).catch(e=>{if(o?.aborted)throw new Error("Cancelled");if(!le(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=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})(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 ve(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:me},...o?.vision?{visionBackend:n.Backend.GPU,maxVisionTokensPerImage:70,minVisionTokensPerImage:70}:{},...o?.audio?{audioBackend:n.Backend.CPU}:{}}})({model:e,limits:t,source:p,mod:l}));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})=>{pe=!0===n.logging;const a=()=>{try{o.conversation?.cancel()}catch{}o.conversation=void 0,o.sent=[]};try{return await Y({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(),ge.stored(r)]);if(o?.complete)return!0;try{return!(!n||!await n.match(r))}catch{return!1}},purge:async()=>{try{await ge.purge(),"undefined"!=typeof caches&&await caches.delete(de)}catch{}}},_e=ue("wllama-store"),Pe=[c.qwen3_vl_2b_instruct,c.qwen3_vl_2b_instruct_q3],Oe=e=>e.cpu?.mmproj&&Pe.includes(e.id)?{image_min_tokens:16,image_max_tokens:100}:{};let Se,Te,De="",Ce=!1;const Ne=e=>`${e.wasm}|${e.compatWasm}|${e.compatWorker}`,Ee=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}},Ae=e=>{const t=e=>(...t)=>{Ce&&("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)}},Le=async()=>{if(Se)return Se;const e=await r.e(924).then(()=>r(577)),t=Te||Ee(),n=new e.Wllama({default:t.wasm},{logger:Ae(e.LoggerWithoutDebug)});return Te||(Te=t,De=Ne(t)),n.setCompat({wasm:t.compatWasm,worker:t.compatWorker}),Se=n,n},$e=async()=>{const e=Se;Se=void 0;try{await(e?.exit())}catch{}},Re=(e,t)=>e.name.includes(t)||!!e.metadata?.originalURL?.includes(t),qe=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)}]:[]]:[]},Ue=async e=>{const t=qe(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},Ie=async(e,t)=>{const r=await e.cacheManager.list();return qe(t).every(e=>r.some(t=>Re(t,e.name)))},ze=async({model:e,signal:t,onProgress:r})=>{const n=qe(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},Ve={backend:i.cpu,startLLM:async({model:e,limits:t,onProgress:r,signal:n,logging:o,assets:a})=>{Ce=!0===o;const c=m()?4096:8192,l=e.cpu;if(!l)throw new Error("Model has no CPU artifact");const u=Ee(a),d=Ne(u);Se&&d!=De&&await $e(),Te=u,De=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 Le(),f=await Ue(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 $e(),new Error("Cancelled");if(!f&&h){const e=await p.cacheManager.list(),t=e.some(e=>Re(e,l.file)),r=e.some(e=>Re(e,h));t&&!r&&await p.cacheManager.deleteMany(e=>Re(e,l.file))}const b={n_ctx:c,n_threads:g,reasoning_budget_tokens:t.maxThinkingTokens,n_gpu_layers:0,jinja:!0,...Oe(e)};try{let t=f?await ze({model:e,signal:n,onProgress:r}):void 0;t||f||await Ie(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,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 $e(),e}if(n?.aborted)throw await $e(),new Error("Cancelled");if(!p.getLoadedContextInfo().n_ctx)throw await $e(),new Error("Failed to create model context");return{model:e,backend:i.cpu,contextSize:c,chat:t=>(async(e,t,r)=>{if(Ce=!0===r.logging,e.isModelLoaded())return await Y({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(Se==p)await $e();else try{await p.exit()}catch{}}}},cached:async e=>{try{return!!e.cpu&&(!!await Ue(e)||await Ie(await Le(),e))}catch{return!1}},purge:async()=>{try{await _e.purge()}catch{}try{const e=await Le();await e.cacheManager.clear()}catch{}}},Be=((e={})=>{const t=e.engines?.cpu||Ve,r=e.engines?.litert||ke;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,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 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==P&&(c=void 0,l=void 0,f=[])});return c=P,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}})(),We=(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}:{}}},Qe=(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)),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)}})(Be),Ye=(Ge=Be,async(e={})=>{const t=await y(e.model),r=r=>e.onStatus?.(We(Ge,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=Ge.ready()&&Ge.model()?.id==t.id;return await Ge.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||Ge.error()||"Model not ready"}),!1)});var Ge;const He=async()=>{await Be.clear()},Je=(e,...t)=>{!0===e&&console.log(...t)},Ze=["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(" "),Ke=["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 (2 sentences).","Ensure accuracy so a blind person can know exactly what is in the image.","Reply in English."].join(" "),Xe=["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(" "),et="CANNOT_TRANSLATE",tt=e=>{const t=e.trim().toLowerCase();return!!t&&!/^(en|eng|english)([-_]|$)/.test(t)},rt=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`,nt=({service:e,limits:t,logging:r,onStatus:n})=>{const o=(t,r)=>n?.(We(e,t,r));return{report:o,load:async n=>{let a,i=0,c=-1,l=s.download;Je(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,Je(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 Je(r,"Describe load ready",n.id);const u=a||e.error()||"Model not ready";return Je(r,"Describe load failed",n.id,u),o(n.id,{requesting:!1,phase:l,percent:i,error:u}),u},generate:async(n,a,i)=>{const c=Date.now();Je(r,"Describe generate start",i,n,a.length);try{const o=await e.chat({messages:a,limits:t,reasoning:!1,logging:r,onReason:e=>{Je(r,"Describe reason",i,n,e)},onText:e=>{Je(r,"Describe text",i,n,e)},onSpeed:e=>{Je(r,"Describe speed",i,n,e)}});return Je(r,"Describe generate reply",i,n,Date.now()-c,o?.length??0,o),o}catch(e){throw Je(r,"Describe generate failed",i,n,e),o(n,{requesting:!1,phase:s.load,percent:100,error:`${e?.message||`${e}`}`}),e}}}},ot=async({translator:e,generate:t,descriptions:r,language:o,currentIndex:a})=>{const i=[...r];for(let s=0;s<r.length;s++){const c=r[s],l=(await t(e.id,[{role:n.system,content:Xe},{role:n.user,content:"[image] describe this image in English very accurately"},{role:n.assistant,content:c},{role:n.user,content:rt(o)}],"translate")||"").trim(),u=l.replace(/[^a-z]/gi,"").toUpperCase().includes(et.replace(/[^a-z]/gi,""));l&&!u&&(i[s]=l),a?.(s,c,i[s])}return i},at=(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=f(c.qwen3_vl_2b_instruct_q3),u=c.qwen3_vl_2b_instruct_q3,d=D({maxReplyTokens:600,...t.limits}),{report:g,load:m,generate:p}=nt({service:e,limits:d,logging:i,onStatus:t.onStatus});if(Je(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 Je(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 Je(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 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 p(l.id,[{role:n.system,content:Ze},{role:n.user,content:Ke,images:[c]}],"describe"),d=Date.now()-t,m=(u||"").trim();if(Je(i,"Describe english",e,d,m),!m)throw Je(i,"Describe empty",e,u),g(l.id,{requesting:!1,phase:s.load,percent:100,error:"No description"}),new Error("No description");a.push({descriptionEN:m,description:m,durationMs:d}),o?.(e,m,void 0,d)}Je(i,"Describe english ready",a.length);const w=t.targetLanguage.trim(),b=tt(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 ot({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)}}),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})(Be),it=(e=>async t=>{const r=[...t.descriptions],n=t.targetLanguage.trim(),o=!0===t.logging;if(Je(o,"Translate start",r.length,n),!r.length||!tt(n))return Je(o,"Translate skipped"),r;const a=D({maxReplyTokens:600,...t.limits}),{report:i,load:l,generate:u}=nt({service:e,limits:a,logging:o,onStatus:t.onStatus}),d=await h()?f(c.gemma4_e2b_limited):void 0;if(!d)return Je(o,"Translate no gpu"),r;const g=await l(d);if(g)return Je(o,"Translate stop",g),r;i(d.id,{requesting:!0,phase:s.load,percent:100});const m=await ot({translator:d,generate:u,descriptions:r,language:n,currentIndex:t.currentIndex});return i(d.id,{requesting:!1,phase:s.load,percent:100}),m})(Be),st=/^[0-9+\-*/%^().]+$/,ct=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},lt={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(!st.test(t))throw new Error("Unsupported character");const r=ct(t);return{expression:t,result:Math.abs(r)>=1e5?(0,O.pNum)(r)??r:(0,O.rNum)(r,12)}})(t)}},ut="degreesign-chat-prices-v1",dt="EUR",gt=5*O.oneMin,mt=30*O.oneSec;let pt,ft={},ht=0,yt=!1,wt=!1;const bt=e=>{const t={};for(const[r,n]of Object.entries(e??{}))"number"==typeof n&&Number.isFinite(n)&&(t[r.trim().toUpperCase()]=n);return t},vt=(e,t)=>e&&e.sourceAt>t.sourceAt?e:t,xt=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=bt(e.rates?.current),n=bt(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&&(ft.fiat=vt(ft.fiat,a)),i&&(ft.crypto=vt(ft.crypto,i)),ht=0,yt=!1,(()=>{try{if("undefined"==typeof localStorage)return;localStorage.setItem(ut,JSON.stringify(ft))}catch{}})()}catch(e){throw ht=Date.now(),yt=!0,e}},jt=e=>!!ft.crypto&&(e in ft.crypto.prices||e in ft.crypto.yesterday),Mt=e=>!!ft.fiat&&(e in ft.fiat.rates||e in ft.fiat.yesterday),kt=async e=>{const t=(e=>{const t={fiat:!1,crypto:!1};for(const r of e){if(r==dt)continue;const e=jt(r)||Mt(r);!jt(r)&&e||(t.crypto=!0),jt(r)||(t.fiat=!0)}return t})(e),r=Date.now(),n=t.fiat&&r-(ft.fiat?.fetchedAt??0)>=O.oneHr,o=t.crypto&&r-(ft.crypto?.fetchedAt??0)>=gt;(n||o)&&("undefined"!=typeof navigator&&!1===navigator.onLine||ht&&r-ht<mt||(pt||(pt=xt({fiat:n,crypto:o}).catch(()=>{}).finally(()=>{pt=void 0})),await pt))},_t=e=>{if(e==dt)return 1;const t=ft.crypto?.yesterday[e],r=ft.fiat?.yesterday[e];return t||(r?1/r:void 0)},Pt=(e,t)=>{if("string"!=typeof e||!e.trim())throw new Error(`Missing ${t}`);return e.trim().toUpperCase()},Ot=e=>Math.abs(e)>=1e5?(0,O.pNum)(e)??e:(0,O.rNum)(e,8),St=async e=>{(()=>{if(!wt){wt=!0;try{if("undefined"==typeof localStorage)return;const e=localStorage.getItem(ut);if(!e)return;const t=JSON.parse(e);ft={...t.fiat?{fiat:t.fiat}:{},...t.crypto?{crypto:t.crypto}:{}}}catch{}}})();const t=Pt(e.from,"from"),r=void 0===e.to||null===e.to?dt:Pt(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 kt([t,r]);const o=e=>{const t=(e=>{if(e==dt)return 1;const t=ft.crypto?.prices[e],r=ft.fiat?.rates[e];return t||(r?1/r:void 0)})(e);if(void 0!==t)return t;if(!ft.fiat&&!ft.crypto)throw new Error("Prices unavailable offline");if(jt(e)||Mt(e))throw new Error(`Unavailable quote for ${e}`);throw new Error(`Unknown symbol ${e}`)},a=o(t),i=o(r),s=_t(t),c=_t(r),l=a/i,u=s&&c?s/c:void 0,d=void 0===u?void 0:l-u,g=void 0===u?void 0:100*(l/u-1),m=(e=>{const t=[];for(const r of e)r!=dt&&(jt(r)?ft.crypto&&t.push(ft.crypto.sourceAt):Mt(r)&&ft.fiat&&t.push(ft.fiat.sourceAt));return t})([t,r]),p=m.length?Math.min(...m):Date.now();return{from:t,to:r,amount:n,rate:Ot(l),...void 0===u?{}:{previousRate:Ot(u),change:Ot(d??0),changePercent:(0,O.rNum)(g??0,4)},result:Ot(n*l),updatedAt:new Date(p).toISOString(),stale:yt&&!(!ft.fiat&&!ft.crypto)}},Tt={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=>St(e)},Dt={amp:"&",apos:"'",gt:">",lt:"<",nbsp:" ",quot:'"',hellip:"...",mdash:"-",ndash:"-",ldquo:'"',lsquo:"'",rdquo:'"',rsquo:"'"},Ct=(e,t,r,n)=>"number"==typeof e&&Number.isFinite(e)?Math.min(r,Math.max(t,e)):n,Nt=(e,t)=>e.replace(/<[^>]*>/g," ").replace(/&(#x?[0-9a-f]+|[a-z]+);/gi,(e,t)=>{const r=(e=>{if(e.startsWith("#")){const t="x"==e[1]||"X"==e[1],r=parseInt(t?e.slice(2):e.slice(1),t?16:10);return r>0&&r<=1114111?String.fromCodePoint(r):e}return Dt[e.toLowerCase()]??e})(t);return r==t?e:r}).replace(/\s+/g," ").trim().slice(0,Math.max(0,t)).trim(),Et=/^[a-z]{2,3}(-[a-z]{2,4})?$/i,At=async(e,t)=>{const r=new AbortController,n=setTimeout(()=>r.abort(),t);try{const t=await fetch(e,{signal:r.signal});if(!t.ok)throw new Error(`Search failed with ${t.status}`);return await t.json()}catch(e){if(r.signal.aborted)throw new Error(`Search timed out after ${t} ms`);throw e}finally{clearTimeout(n)}},Lt=(e={})=>{const t=((e={})=>{const t=e.language?.trim()??"";return{provider:e.provider==u.duckduckgo?u.duckduckgo:u.wikipedia,language:Et.test(t)?t:"en",limit:Math.round(Ct(e.limit,1,20,3)),snippetLength:Math.round(Ct(e.snippetLength,1,4e3,400)),timeout:Ct(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 At(r,e.timeout),o=[],a=new Set,i=(t,r,n)=>{t&&n&&!a.has(t)&&(a.add(t),o.push({title:Nt(r||n,200),url:t,snippet:Nt(n,e.snippetLength)}))},s=e=>{for(const t of e)t.Topics?s(t.Topics):i(t.FirstURL,t.Text,t.Text)};i(n.AbstractURL,n.Heading||n.AbstractText,n.AbstractText);for(const e of n.Results??[])i(e.FirstURL,e.Text,e.Text);return s(n.RelatedTopics??[]),o.slice(0,e.limit)})(t,r):await(async(e,t)=>{const r=`https://${e.language}.wikipedia.org`,n=`${r}/w/rest.php/v1/search/page?q=${encodeURIComponent(t)}&limit=${e.limit}`,o=await At(n,e.timeout),a=[];for(const t of o.pages??[]){const n=t.key;n&&a.push({title:Nt(t.title??n,200),url:`${r}/wiki/${encodeURIComponent(n)}`,snippet:Nt(`${t.description??""} ${t.excerpt??""}`,e.snippetLength)})}return a})(t,r);return n}}},$t=(e,t)=>{const r=[];for(const n of e)n==l.websearch?r.push(Lt(t)):n==l.calculate?r.push(lt):n==l.currency&&r.push(Tt);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,$t as builtinTools,lt as calculateTool,He as clearModelCache,Qe as createChat,Tt as currencyTool,at as describeImages,it as describeTranslated,Ye as preloadModel,Lt 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
|
@@ -1,10 +1,19 @@
|
|
|
1
|
-
import type { EngineMessage } from '../types';
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import type { EngineMessage, ImageSize } from '../types';
|
|
2
|
+
declare const
|
|
3
|
+
/** Vision token target */
|
|
4
|
+
imageTokens = 64,
|
|
5
|
+
/** Pixels per vision token */
|
|
6
|
+
tokenCell = 32,
|
|
7
|
+
/** Tokens allowed above the target */
|
|
8
|
+
tokenSlack = 8;
|
|
9
|
+
/** Square size the WebGPU engine encodes */
|
|
10
|
+
declare const gpuImageSize: ImageSize;
|
|
4
11
|
/** Decode a data URL or fetch a URL into bytes for an engine */
|
|
5
12
|
declare const contentBuffer: (url: string) => Promise<ArrayBuffer>;
|
|
6
|
-
/**
|
|
7
|
-
declare const
|
|
8
|
-
/**
|
|
9
|
-
declare const
|
|
10
|
-
|
|
13
|
+
/** Full-frame size near the token target */
|
|
14
|
+
declare const visionSize: (width: number, height: number) => ImageSize;
|
|
15
|
+
/** Fit one image URL to the token grid for an engine */
|
|
16
|
+
declare const resizeImageUrl: (url: string, size?: ImageSize) => Promise<string>;
|
|
17
|
+
/** Fit every image part before an engine sees it */
|
|
18
|
+
declare const resizeImages: (messages: EngineMessage[], size?: ImageSize) => Promise<EngineMessage[]>;
|
|
19
|
+
export { gpuImageSize, imageTokens, tokenCell, tokenSlack, visionSize, contentBuffer, resizeImageUrl, resizeImages, };
|
package/dist/engines/wllama.d.ts
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
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
|
+
/** Image limits of one model */
|
|
5
|
+
declare const visionLimits: (model: ChatModel) => {
|
|
6
|
+
image_min_tokens: number;
|
|
7
|
+
image_max_tokens: number;
|
|
8
|
+
} | {
|
|
9
|
+
image_min_tokens?: undefined;
|
|
10
|
+
image_max_tokens?: undefined;
|
|
11
|
+
};
|
|
4
12
|
declare const
|
|
5
13
|
/** Every CPU file of one model, its name and remote URL */
|
|
6
14
|
cpuFiles: (model: ChatModel) => Array<{
|
|
@@ -17,4 +25,4 @@ storedBlobs: ({ model, signal, onProgress, }: {
|
|
|
17
25
|
toWllamaMessages: (messages: EngineMessage[]) => Promise<WllamaMessage[]>,
|
|
18
26
|
/** Start the CPU runtime, the unified engine entry */
|
|
19
27
|
startLLM: ({ model, limits, onProgress, signal, logging, assets: overrides, }: StartLlmParams) => Promise<LlmRuntime>, wllamaEngine: LlmEngine;
|
|
20
|
-
export { cpuFiles, cpuThreads, startLLM, storedBlobs, toWllamaMessages, wllamaEngine, };
|
|
28
|
+
export { cpuFiles, cpuThreads, startLLM, storedBlobs, toWllamaMessages, visionLimits, wllamaEngine, };
|
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';
|