diff --git a/dist/src/docs.d.ts b/dist/src/docs.d.ts new file mode 100644 index 0000000..47adf07 --- /dev/null +++ b/dist/src/docs.d.ts @@ -0,0 +1,7 @@ +/** + * The API's own webpage — served from the deployed worker at `/` (to + * browsers, via content negotiation) and at `/docs` (always). Deployed + * content belongs to the api.interscript.org deployment, not the main + * website. Self-contained HTML: no external assets, system font stack. + */ +export declare function docsPage(openapiPath: string): string; diff --git a/dist/src/docs.js b/dist/src/docs.js new file mode 100644 index 0000000..5b673ec --- /dev/null +++ b/dist/src/docs.js @@ -0,0 +1,87 @@ +/** + * The API's own webpage — served from the deployed worker at `/` (to + * browsers, via content negotiation) and at `/docs` (always). Deployed + * content belongs to the api.interscript.org deployment, not the main + * website. Self-contained HTML: no external assets, system font stack. + */ +const ENDPOINTS = [ + { method: "GET", path: "/v1/info", note: "version + capability summary" }, + { method: "GET", path: "/v1/maps", note: "every transliteration system code" }, + { method: "GET", path: "/v1/maps/{code}", note: "one system's compiled map (JSON IR)" }, + { method: "POST", path: "/v1/transliterate", note: "{system, input} → {output}" }, + { method: "POST", path: "/v1/detect", note: "{input, output} → ranked systems" }, + { method: "GET", path: "/v1/models", note: "neural model index (IMF v1)" }, + { method: "GET", path: "/v1/models/{id}", note: "one model's metadata" }, + { method: "POST", path: "/v1/infer", note: "{model, input} → {output}" }, + { method: "POST", path: "/graphql", note: "GraphQL endpoint (introspection enabled)" }, + { method: "GET", path: "/openapi.json", note: "OpenAPI 3.1 document" }, +]; +function esc(s) { + return s.replace(/&/g, "&").replace(//g, ">"); +} +export function docsPage(openapiPath) { + const rows = ENDPOINTS.map((e) => `${esc(e.method)}${esc(e.path)}${esc(e.note)}`).join("\n"); + return ` + + + + +Interscript API + + + +
+

Interscript API

+

Authority-backed transliteration for every script — REST v1 + GraphQL on the edge.

+ + + + +${rows} + +
MethodEndpointBehavior
+ +
+

Quick start

+
curl -X POST https://api.interscript.org/v1/transliterate \\
+  -H 'Content-Type: application/json' \\
+  -d '{"system":"alalc-ara-Arab-Latn-1997","input":"السلام عليكم"}'
+
+ +
+

Machine-readable

+ +
+
+ + +`; +} diff --git a/dist/src/index.js b/dist/src/index.js index 6528164..6e9d590 100644 --- a/dist/src/index.js +++ b/dist/src/index.js @@ -1,7 +1,7 @@ -var mn=Object.defineProperty;var u=(t,e,n)=>()=>{if(n)throw n[0];try{return t&&(e=t(t=0)),e}catch(r){throw n=[r],r}};var B=(t,e)=>{for(var n in e)mn(t,n,{get:e[n],enumerable:!0})};var pt={};B(pt,{createLitertSession:()=>Ln});async function yn(){return ee||(ee=(async()=>{try{return await import("@litertjs/core")}catch(t){throw ee=void 0,new Error("@litertjs/core is required for LiteRT inference. Install with: npm install @litertjs/core",{cause:t})}})()),ee}async function Ln(t,e={}){let n=e.accelerator??"webgpu",r=e.wasmPath??bn,a=e.inputNames??["src","lengths"],s=e.outputNames??["output"],o=await yn();await o.loadLiteRt(r,{jspi:n==="webnn"});let c=new Blob([new Uint8Array(t)],{type:"application/octet-stream"}),i=URL.createObjectURL(c),l;return l=await o.loadAndCompile(i,{accelerator:n}),new we(l,o,a,s,i)}function wn(t){return t instanceof Float32Array?"float32":t instanceof Int32Array?"int32":t instanceof BigInt64Array?"int64":t instanceof Uint8Array?"uint8":"float32"}var bn,ee,we,ut=u(()=>{"use strict";bn="https://cdn.jsdelivr.net/npm/@litertjs/core@2.5.2/wasm/";we=class{inputNames;outputNames;model;core;blobUrl;disposed=!1;constructor(e,n,r,a,s){this.model=e,this.core=n,this.inputNames=r,this.outputNames=a,this.blobUrl=s}async run(e){if(this.disposed)throw new Error("Session disposed");let n=[];for(let s of this.inputNames){let o=e[s];if(!o)throw new Error(`Missing LiteRT input: ${s}`);n.push(new this.core.Tensor(o.data,o.dims))}let r=await this.model.run(n.length===1?n[0]:n),a={};try{for(let s=0;svn});async function Sn(){try{return await import("onnxruntime-node")}catch(t){throw new Error("onnxruntime-node is required for ML inference in Node. Install with: npm install onnxruntime-node",{cause:t})}}async function vn(t){return Se.create(t)}var Se,mt=u(()=>{"use strict";Se=class t{session;ort;inputNames;outputNames;inputMetadata;constructor(e,n){this.session=e,this.ort=n,this.inputNames=e.inputNames,this.outputNames=e.outputNames;let r=e.inputMetadata;Array.isArray(r)&&(this.inputMetadata=r)}static async create(e){let n=await Sn(),r=await n.InferenceSession.create(e);return new t(r,n)}async run(e){let n={};for(let[s,o]of Object.entries(e))n[s]=new this.ort.Tensor(o.type,o.data,o.dims);let r=await this.session.run(n),a={};for(let[s,o]of Object.entries(r)){let c=o;a[s]={name:s,type:c.type,data:c.data,dims:c.dims}}return a}async dispose(){await this.session.release()}}});var ft={};B(ft,{createWebSession:()=>_n});async function An(){return te||(te=(async()=>{try{let t=await import("onnxruntime-web");return t.env.wasm.simd=!0,t}catch(t){throw te=void 0,new Error("onnxruntime-web is required for ML inference in the browser. Install with: npm install onnxruntime-web",{cause:t})}})()),te}async function _n(t,e={}){return ve.create(t,e)}var te,ve,ht=u(()=>{"use strict";ve=class t{session;ort;inputNames;outputNames;constructor(e,n){this.session=e,this.ort=n,this.inputNames=e.inputNames,this.outputNames=e.outputNames}static async create(e,n={}){let r=await An(),a=n.webgpu===!1?["wasm"]:["webgpu","wasm"],s=await r.InferenceSession.create(e,{executionProviders:a});return new t(s,r)}async run(e){let n={};for(let[s,o]of Object.entries(e))n[s]=new this.ort.Tensor(o.type,o.data,o.dims);let r=await this.session.run(n),a={};for(let[s,o]of Object.entries(r)){let c=o;a[s]={name:s,type:c.type,data:c.data,dims:c.dims}}return a}async dispose(){await this.session.release()}}});function Ae(){let t=globalThis;return t.process?.versions?.node?"node":t.self!==void 0?"web":"unknown"}async function N(t,e={}){if((e.runtime??"onnx")==="litert"){let s={};return e.litertAccelerator!==void 0&&(s.accelerator=e.litertAccelerator),e.inputNames!==void 0&&(s.inputNames=e.inputNames),e.outputNames!==void 0&&(s.outputNames=e.outputNames),(await Promise.resolve().then(()=>(ut(),pt))).createLitertSession(t,s)}if((e.backend??Ae()==="node"?"node":"web")==="node")return(await Promise.resolve().then(()=>(mt(),dt))).createNodeSession(t);let a=e.webgpu===void 0?{}:{webgpu:e.webgpu};return(await Promise.resolve().then(()=>(ht(),ft))).createWebSession(t,a)}var ne=u(()=>{"use strict"});var kn,xn,gt,bt,Nr,yt,Ir,Mn,Lt,En,_e,wt,ke,re,I=u(()=>{"use strict";kn=["\u0652","\u0651","\u064C","\u064D","\u0650","\u064B","\u064E","\u064F"],xn="\u0649\u0639\u0638\u062D\u0631\u0633\u064A\u0634\u0636\u0642 \u062B\u0644\u0635\u0637\u0643\u0622\u0645\u0627\u0625\u0647\u0632\u0621\u0623\u0641\u0624\u063A\u062C\u0626\u062F\u0629\u062E\u0648\u0628\u0630\u062A\u0646",gt="\u0649\u0639\u0638\u062D\u0631\u0633\u064A\u0634\u0636\u0642\u062B\u0644\u0635\u0637\u0643\u0622\u0645\u0627\u0625\u0647\u0632\u0621\u0623\u0641\u0624\u063A\u062C\u0626\u062F\u0629\u062E\u0648\u0628\u0630\u062A\u0646",bt=[...kn,...xn],Nr=Object.freeze({"\u064E":"Fatha","\u064B":"Fathatah","\u064F":"Damma","\u064C":"Dammatan","\u0650":"Kasra","\u064D":"Kasratan","\u0652":"Sukun","\u0651":"Shaddah"}),yt=Object.freeze({"":"No Diacritic","\u064E":"Fatha","\u064B":"Fathatah","\u064F":"Damma","\u064C":"Dammatan","\u0650":"Kasra","\u064D":"Kasratan","\u0652":"Sukun","\u0651":"Shaddah","\u0651\u064E":"Shaddah + Fatha","\u0651\u064B":"Shaddah + Fathatah","\u0651\u064F":"Shaddah + Damma","\u0651\u064C":"Shaddah + Dammatan","\u0651\u0650":"Shaddah + Kasra","\u0651\u064D":"Shaddah + Kasratan"}),Ir=Object.freeze(Object.fromEntries(Object.keys(yt).map((t,e)=>[t,e]))),Mn="P",Lt=[Mn,...Object.keys(yt),""],En="\u0628\u0636.\u063A\u0649\u0647\u0638\u062E\u0629\u061F:\u0637\u0633\u060C\u061B\u0641\u0646\u062F\u0624\u0644\u0648\u0626\u0622\u0643-\u064A\u0630\u0627\u0635\u0634\u062D\u0632\u0621\u0645\u0623\u062C\u0625 \u062A\u0631\u0642\u0639\u062B",_e="P",wt=[_e,...En],ke=Object.freeze(Object.fromEntries(wt.map((t,e)=>[t,e]))),re=wt});function St(t){return t.replace(/\s+/g," ")}function ae(t){return St(t).trim()}function xe(t){return ae(Array.from(t).filter(e=>Tn.has(e)).join(""))}var Tn,Me=u(()=>{"use strict";I();Tn=new Set(bt)});var q,Ee=u(()=>{"use strict";I();Me();q=class{inputSymbolToId=ke;inputIdToSymbol=re;inputPadId;startSymbolId;cleanerType;reverse;constructor(e={}){this.cleanerType=e.cleaner??"arabic",this.reverse=e.reverseInput??!1,this.inputPadId=ke[_e],this.startSymbolId=e.startSymbol?0:null}clean(e){return this.cleanerType==="arabic"?xe(e):ae(e)}removeDiacritics(e){return Array.from(e).filter(n=>!(!(n in this.inputSymbolToId)&&/[ً-ْ]/.test(n))).join("")}inputToSequence(e){let n=this.reverse?Array.from(e).reverse():Array.from(e),r=[];for(let a of n){let s=this.inputSymbolToId[a];s!==void 0&&r.push(s)}return r}}});function Nn(t,e){let n=[],r=0;for(let a=0;a!Cn.has(i)),r=Array.from(e),a=Nn(n,r),s="",o=0,c=0;for(let{idxDia:i,idxOri:l}of a){if(c{"use strict";I();Cn=new Set(["\u0652","\u0651","\u064C","\u064D","\u0650","\u064B","\u064E","\u064F"]),Rn=new Set(gt)});function In(t,e){let n=t.dims,r=n[n.length-1],a=[],s=t.data;for(let o=0;oi&&(i=d,c=p)}a.push(c)}return a}function On(t,e,n){let r="";for(let a=0;a{"use strict";Ee();Ce();I();O={maxLen:200,batchSize:1,textEncoder:"ArabicEncoderWithStartSymbol",textCleaner:"valid_arabic_cleaners"},Re=class{kind="rababa";session;encoder;config;constructor(e,n){this.session=e,this.config=n,this.encoder=new q({cleaner:n.textCleaner==="valid_arabic_cleaners"?"arabic":"basic",startSymbol:n.textEncoder==="ArabicEncoderWithStartSymbol"})}async diacritize(e){let n=e;n.length>this.config.maxLen&&(n=n.slice(0,this.config.maxLen));let r=this.encoder.clean(n),a=this.stripDiacritics(r),s=this.encoder.inputToSequence(a);if(s.length===0)return n;let o=this.config.batchSize,c=this.config.maxLen,i=this.encoder.inputPadId,l=[];for(let _=0;_BigInt(_))),dims:[o,c]},d={name:"lengths",type:"int64",data:new BigInt64Array(Array(o).fill(BigInt(c))),dims:[o]},b=(await this.session.run({src:p,lengths:d}))[this.session.outputNames[0]];if(!b)throw new Error("Rababa model produced no output");let x=In(b,s.length),v=On(s,x,this.encoder.inputPadId);return Te(r,v)}async transform(e){return this.diacritize(e)}stripDiacritics(e){return Array.from(e).filter(n=>!/[ً-ْ]/.test(n)).join("")}async dispose(){await this.session.dispose()}}});var At={};B(At,{rababa:()=>Fn,rababaReverse:()=>qn,resetRababaConfigs:()=>$n,setRababaConfig:()=>jn});function jn(t,e){Oe.set(t,e)}function $n(){Oe=new Map(Object.entries(vt))}function Dn(t){let e=Oe.get(t);if(!e)throw new Error(`No rababa config registered under '${t}'. Register one via setRababaConfig() before invoking rababa.`);return e}function Bn(t){return{maxLen:Number(t.max_len??t.maxLen??200),batchSize:Number(t.batch_size??t.batchSize??32),textEncoder:t.text_encoder??"ArabicEncoderWithStartSymbol",textCleaner:t.text_cleaner??"valid_arabic_cleaners"}}async function Un(t){let e=Ie.get(t);if(!e){let n=Dn(t);e=(async()=>{let r=await Pn(n.model),a=await N(r),s=Bn(n.config);return se({session:a,artifacts:{},config:s})})(),Ie.set(t,e),e.catch(()=>Ie.delete(t))}return e}async function Pn(t){if(t.startsWith("file:")||t.startsWith(".")){let{readFile:n}=await import("node:fs/promises"),r=t.startsWith("file:")?t.slice(5):t;return new Uint8Array(await n(r))}let e=await fetch(t);if(!e.ok)throw new Error(`Failed to fetch ${t}: ${e.status}`);return new Uint8Array(await e.arrayBuffer())}async function Fn(t,e={}){let n=e.config??"200";return(await Un(n)).diacritize(t)}function qn(t){return t.replace(/[ًٌٍَُِّْ]/g,"")}var vt,Oe,Ie,_t=u(()=>{"use strict";ne();Ne();vt=Object.freeze({200:Object.freeze({model:"https://github.com/secryst/rababa-models/releases/download/0.1/diacritization_model_arabic.onnx",config:Object.freeze({session_name:"base",text_encoder:"ArabicEncoderWithStartSymbol",text_cleaner:"valid_arabic_cleaners",max_len:200,batch_size:32})})}),Oe=new Map(Object.entries(vt));Ie=new Map});function xt(t){kt=t.replace(/\/$/,"")}function oe(){return kt}var kt,ze=u(()=>{"use strict";kt="https://cdn.jsdelivr.net/gh/interscript/ml-models@main/npm/models"});function Et(t){je=t,E=null}function Tt(t){Mt=t,E=null}function Vn(){return`${oe()}/npm/models/manifest.json`}async function $e(){if(E)return E;if(je)return E=je,E;let t=Mt??Vn(),e=await fetch(t);if(!e.ok)throw new Error(`Failed to load model manifest from ${t}: ${e.status} ${e.statusText}`);let n=await e.json();return E=n,n}async function H(t,e){let n=await $e(),r=e.startsWith(`${t}_`)?e:`${t}_${e}`;return n.models[r]??n.models[e]??null}function G(t,e="q8",n="onnx"){let r=Ct(t,e,n),a=t.cdn_base.replace("{version}",t.version),s=t.github_base.replace("{version}",t.version);return{primary:`${a}${r}`,fallback:`${s}${r}`,assetName:r}}function ie(t,e="q8",n="onnx"){return[`${Ct(t,e,n)}.sha256`,"vocab.json","config.json"]}function Ct(t,e,n="onnx"){return`${Kn(t)}${Hn[e]}${Gn[n]}`}function Kn(t){let n=t.github_base.match(/([^/]+)-v\{version\}\/$/)?.[1];if(n)return n;throw new Error(`Cannot extract task name from manifest entry. github_base=${t.github_base}`)}var Hn,Gn,E,je,Mt,De=u(()=>{"use strict";ze();Hn={fp32:"",q8:"-q8",q4:"-q4",fp16:"-fp16"},Gn={onnx:".onnx",tflite:".tflite"},E=null,je=null,Mt=null});async function Nt(t,e={}){let n=e.variant??"q8",r=e.format??"onnx",a=e.webgpu??!0,s=t.url??await Wn(t,n,r),o=await Rt(s),c=await Jn(t,n,r),i={};await Promise.all(c.map(async({filename:d,url:S})=>{try{let b=await Rt(S);d.endsWith(".json")||d.endsWith(".yaml")||d.endsWith(".yml")||d.endsWith(".sha256")?i[d]=new TextDecoder().decode(b):i[d]=b}catch{}}));let l={webgpu:a};return r==="tflite"&&(l.runtime="litert",e.litertAccelerator!==void 0&&(l.litertAccelerator=e.litertAccelerator),e.inputNames!==void 0&&(l.inputNames=e.inputNames),e.outputNames!==void 0&&(l.outputNames=e.outputNames)),{session:await N(o,l),artifacts:i}}async function Wn(t,e,n){let r=await H(t.kind,t.id);if(!r)throw new Error(`No manifest entry for kind=${t.kind} id=${t.id}. Pass an explicit \`url\` on the ModelRef or pin a task version in the manifest.`);let{primary:a}=G(r,e,n);return a}async function Jn(t,e,n){if(t.url)return[];let r=await H(t.kind,t.id);if(!r)return[];let{primary:a,assetName:s}=G(r,e,n),o=a.slice(0,a.lastIndexOf("/")+1);return ie(r,e,n).map(c=>({filename:c,url:`${o}${c.startsWith(s),c}`}))}async function Rt(t){if(t.startsWith("file:")||t.startsWith(".")&&typeof process<"u"&&process.versions?.node){let{readFile:n}=await import("node:fs/promises"),r=t.startsWith("file:")?t.slice(5):t;return new Uint8Array(await n(r))}let e=await fetch(t);if(!e.ok)throw new Error(`Failed to fetch ${t}: ${e.status} ${e.statusText}`);return new Uint8Array(await e.arrayBuffer())}var It=u(()=>{"use strict";ne();De()});function z(t,e){if(ce.has(t))throw new Error(`Model kind "${t}" is already registered`);ce.set(t,e)}function Yn(t){return`${t.kind}/${t.id}/${t.url??"_default"}`}async function Ot(t){let e=Yn(t),n=V.get(e);if(n)return n;let r=ce.get(t.kind);if(!r)throw new Error(`Unknown model kind: "${t.kind}". Register a factory via registerModel("${t.kind}", factory).`);let a=(async()=>{let{session:s,artifacts:o}=await Nt(t);return r({session:s,artifacts:o})})();return V.set(e,a),a.catch(()=>V.delete(e)),a}function zt(){return[...ce.keys()]}async function jt(){let t=[...V.values()];V.clear(),await Promise.allSettled(t.map(async e=>{try{await(await e).dispose()}catch{}}))}var ce,V,le=u(()=>{"use strict";It();ce=new Map;V=new Map});var $t=u(()=>{"use strict";le();Ne();Ee();Ce();Me();I();z("rababa",async t=>se(t))});function Be(t){let e=t.split(` -`),n=null,r=[],a=[];for(let s of e){let o=s.trimEnd();if(o==="input:"){n="input";continue}if(o==="target:"){n="target";continue}let c=o.match(/^\s+-\s+"?(.+?)"?\s*$/);if(c&&n){let i=c[1];n==="input"?r.push(i):a.push(i)}}return{input:r,target:a}}function Ue(t){return{input:new K(t.input),target:new K(t.target)}}var K,Pe=u(()=>{"use strict";K=class{stoi;itos;length;constructor(e,n=[]){let r=[...n,...e];this.itos=r,this.stoi=Object.freeze(Object.fromEntries(r.map((a,s)=>[a,s]))),this.length=r.length}encode(e){return this.stoi[e]??-1}decode(e){return this.itos[e]??""}encodeSequence(e){return Array.from(e).map(n=>this.encode(n))}decodeSequence(e){return e.map(n=>this.decode(n)).join("")}}});function Dt(t){let e=new Uint8Array(t*t);for(let n=0;nn===e?0:1))}function qe(t,e,n,r){let a=Dt(e),s=Fe(n),o=Fe(r);return{tgt_mask:{name:"tgt_mask",type:"int8",data:a,dims:[e,e]},src_key_padding_mask:{name:"src_key_padding_mask",type:"int8",data:s,dims:[1,t]},tgt_key_padding_mask:{name:"tgt_key_padding_mask",type:"int8",data:o,dims:[1,e]},memory_key_padding_mask:{name:"memory_key_padding_mask",type:"int8",data:s,dims:[1,t]}}}var He=u(()=>{"use strict"});async function Pt(t){let e=t.artifacts["vocabs.yaml"];if(!e)throw new Error("Secryst model missing vocabs.yaml");let n=typeof e=="string"?e:new TextDecoder().decode(e),r=Be(n),{input:a,target:s}=Ue(r);return new Ge(t.session,a,s)}var Qn,Bt,Ut,Ge,Ft=u(()=>{"use strict";Pe();He();Qn=100,Bt="",Ut="",Ge=class{kind="secryst";session;inputVocab;targetVocab;constructor(e,n,r){this.session=e,this.inputVocab=n,this.targetVocab=r}async translate(e,n=Qn){let r=[this.inputVocab.encode(Bt),...this.inputVocab.encodeSequence(e),this.inputVocab.encode(Ut)].filter(o=>o>=0),a=[this.targetVocab.encode(Bt)],s=this.targetVocab.encode(Ut);for(let o=0;oBigInt(f))),dims:[1,r.length]},tgt:{name:"tgt",type:"int64",data:new BigInt64Array(a.map(f=>BigInt(f))),dims:[1,a.length]},...c},p=(await this.session.run(i))[this.session.outputNames[0]];if(!p)throw new Error("Secryst model produced no output");let d=p.dims,S=d[d.length-1],b=p.data,x=o*S,v=0,_=-1/0;for(let f=0;f_&&(_=Q,v=f)}if(v===s)break;a.push(v)}return this.targetVocab.decodeSequence(a.slice(1))}async transform(e){let n=e.split(` +var hn=Object.defineProperty;var d=(e,t,n)=>()=>{if(n)throw n[0];try{return e&&(t=e(e=0)),t}catch(r){throw n=[r],r}};var B=(e,t)=>{for(var n in t)hn(e,n,{get:t[n],enumerable:!0})};var ut={};B(ut,{createLitertSession:()=>Sn});async function wn(){return ee||(ee=(async()=>{try{return await import("@litertjs/core")}catch(e){throw ee=void 0,new Error("@litertjs/core is required for LiteRT inference. Install with: npm install @litertjs/core",{cause:e})}})()),ee}async function Sn(e,t={}){let n=t.accelerator??"webgpu",r=t.wasmPath??Ln,a=t.inputNames??["src","lengths"],s=t.outputNames??["output"],o=await wn();await o.loadLiteRt(r,{jspi:n==="webnn"});let c=new Blob([new Uint8Array(e)],{type:"application/octet-stream"}),i=URL.createObjectURL(c),l;return l=await o.loadAndCompile(i,{accelerator:n}),new Se(l,o,a,s,i)}function vn(e){return e instanceof Float32Array?"float32":e instanceof Int32Array?"int32":e instanceof BigInt64Array?"int64":e instanceof Uint8Array?"uint8":"float32"}var Ln,ee,Se,mt=d(()=>{"use strict";Ln="https://cdn.jsdelivr.net/npm/@litertjs/core@2.5.2/wasm/";Se=class{inputNames;outputNames;model;core;blobUrl;disposed=!1;constructor(t,n,r,a,s){this.model=t,this.core=n,this.inputNames=r,this.outputNames=a,this.blobUrl=s}async run(t){if(this.disposed)throw new Error("Session disposed");let n=[];for(let s of this.inputNames){let o=t[s];if(!o)throw new Error(`Missing LiteRT input: ${s}`);n.push(new this.core.Tensor(o.data,o.dims))}let r=await this.model.run(n.length===1?n[0]:n),a={};try{for(let s=0;skn});async function An(){try{return await import("onnxruntime-node")}catch(e){throw new Error("onnxruntime-node is required for ML inference in Node. Install with: npm install onnxruntime-node",{cause:e})}}async function kn(e){return ve.create(e)}var ve,ht=d(()=>{"use strict";ve=class e{session;ort;inputNames;outputNames;inputMetadata;constructor(t,n){this.session=t,this.ort=n,this.inputNames=t.inputNames,this.outputNames=t.outputNames;let r=t.inputMetadata;Array.isArray(r)&&(this.inputMetadata=r)}static async create(t){let n=await An(),r=await n.InferenceSession.create(t);return new e(r,n)}async run(t){let n={};for(let[s,o]of Object.entries(t))n[s]=new this.ort.Tensor(o.type,o.data,o.dims);let r=await this.session.run(n),a={};for(let[s,o]of Object.entries(r)){let c=o;a[s]={name:s,type:c.type,data:c.data,dims:c.dims}}return a}async dispose(){await this.session.release()}}});var gt={};B(gt,{createWebSession:()=>xn});async function _n(){return te||(te=(async()=>{try{let e=await import("onnxruntime-web");return e.env.wasm.simd=!0,e}catch(e){throw te=void 0,new Error("onnxruntime-web is required for ML inference in the browser. Install with: npm install onnxruntime-web",{cause:e})}})()),te}async function xn(e,t={}){return Ae.create(e,t)}var te,Ae,bt=d(()=>{"use strict";Ae=class e{session;ort;inputNames;outputNames;constructor(t,n){this.session=t,this.ort=n,this.inputNames=t.inputNames,this.outputNames=t.outputNames}static async create(t,n={}){let r=await _n(),a=n.webgpu===!1?["wasm"]:["webgpu","wasm"],s=await r.InferenceSession.create(t,{executionProviders:a});return new e(s,r)}async run(t){let n={};for(let[s,o]of Object.entries(t))n[s]=new this.ort.Tensor(o.type,o.data,o.dims);let r=await this.session.run(n),a={};for(let[s,o]of Object.entries(r)){let c=o;a[s]={name:s,type:c.type,data:c.data,dims:c.dims}}return a}async dispose(){await this.session.release()}}});function ke(){let e=globalThis;return e.process?.versions?.node?"node":e.self!==void 0?"web":"unknown"}async function R(e,t={}){if((t.runtime??"onnx")==="litert"){let s={};return t.litertAccelerator!==void 0&&(s.accelerator=t.litertAccelerator),t.inputNames!==void 0&&(s.inputNames=t.inputNames),t.outputNames!==void 0&&(s.outputNames=t.outputNames),(await Promise.resolve().then(()=>(mt(),ut))).createLitertSession(e,s)}if((t.backend??ke()==="node"?"node":"web")==="node")return(await Promise.resolve().then(()=>(ht(),ft))).createNodeSession(e);let a=t.webgpu===void 0?{}:{webgpu:t.webgpu};return(await Promise.resolve().then(()=>(bt(),gt))).createWebSession(e,a)}var ne=d(()=>{"use strict"});var Tn,En,yt,Lt,jr,wt,$r,Mn,St,Cn,_e,vt,xe,re,N=d(()=>{"use strict";Tn=["\u0652","\u0651","\u064C","\u064D","\u0650","\u064B","\u064E","\u064F"],En="\u0649\u0639\u0638\u062D\u0631\u0633\u064A\u0634\u0636\u0642 \u062B\u0644\u0635\u0637\u0643\u0622\u0645\u0627\u0625\u0647\u0632\u0621\u0623\u0641\u0624\u063A\u062C\u0626\u062F\u0629\u062E\u0648\u0628\u0630\u062A\u0646",yt="\u0649\u0639\u0638\u062D\u0631\u0633\u064A\u0634\u0636\u0642\u062B\u0644\u0635\u0637\u0643\u0622\u0645\u0627\u0625\u0647\u0632\u0621\u0623\u0641\u0624\u063A\u062C\u0626\u062F\u0629\u062E\u0648\u0628\u0630\u062A\u0646",Lt=[...Tn,...En],jr=Object.freeze({"\u064E":"Fatha","\u064B":"Fathatah","\u064F":"Damma","\u064C":"Dammatan","\u0650":"Kasra","\u064D":"Kasratan","\u0652":"Sukun","\u0651":"Shaddah"}),wt=Object.freeze({"":"No Diacritic","\u064E":"Fatha","\u064B":"Fathatah","\u064F":"Damma","\u064C":"Dammatan","\u0650":"Kasra","\u064D":"Kasratan","\u0652":"Sukun","\u0651":"Shaddah","\u0651\u064E":"Shaddah + Fatha","\u0651\u064B":"Shaddah + Fathatah","\u0651\u064F":"Shaddah + Damma","\u0651\u064C":"Shaddah + Dammatan","\u0651\u0650":"Shaddah + Kasra","\u0651\u064D":"Shaddah + Kasratan"}),$r=Object.freeze(Object.fromEntries(Object.keys(wt).map((e,t)=>[e,t]))),Mn="P",St=[Mn,...Object.keys(wt),""],Cn="\u0628\u0636.\u063A\u0649\u0647\u0638\u062E\u0629\u061F:\u0637\u0633\u060C\u061B\u0641\u0646\u062F\u0624\u0644\u0648\u0626\u0622\u0643-\u064A\u0630\u0627\u0635\u0634\u062D\u0632\u0621\u0645\u0623\u062C\u0625 \u062A\u0631\u0642\u0639\u062B",_e="P",vt=[_e,...Cn],xe=Object.freeze(Object.fromEntries(vt.map((e,t)=>[e,t]))),re=vt});function At(e){return e.replace(/\s+/g," ")}function ae(e){return At(e).trim()}function Te(e){return ae(Array.from(e).filter(t=>In.has(t)).join(""))}var In,Ee=d(()=>{"use strict";N();In=new Set(Lt)});var q,Me=d(()=>{"use strict";N();Ee();q=class{inputSymbolToId=xe;inputIdToSymbol=re;inputPadId;startSymbolId;cleanerType;reverse;constructor(t={}){this.cleanerType=t.cleaner??"arabic",this.reverse=t.reverseInput??!1,this.inputPadId=xe[_e],this.startSymbolId=t.startSymbol?0:null}clean(t){return this.cleanerType==="arabic"?Te(t):ae(t)}removeDiacritics(t){return Array.from(t).filter(n=>!(!(n in this.inputSymbolToId)&&/[ً-ْ]/.test(n))).join("")}inputToSequence(t){let n=this.reverse?Array.from(t).reverse():Array.from(t),r=[];for(let a of n){let s=this.inputSymbolToId[a];s!==void 0&&r.push(s)}return r}}});function On(e,t){let n=[],r=0;for(let a=0;a!Rn.has(i)),r=Array.from(t),a=On(n,r),s="",o=0,c=0;for(let{idxDia:i,idxOri:l}of a){if(c{"use strict";N();Rn=new Set(["\u0652","\u0651","\u064C","\u064D","\u0650","\u064B","\u064E","\u064F"]),Nn=new Set(yt)});function zn(e,t){let n=e.dims,r=n[n.length-1],a=[],s=e.data;for(let o=0;oi&&(i=u,c=p)}a.push(c)}return a}function jn(e,t,n){let r="";for(let a=0;a{"use strict";Me();Ie();N();O={maxLen:200,batchSize:1,textEncoder:"ArabicEncoderWithStartSymbol",textCleaner:"valid_arabic_cleaners"},Re=class{kind="rababa";session;encoder;config;constructor(t,n){this.session=t,this.config=n,this.encoder=new q({cleaner:n.textCleaner==="valid_arabic_cleaners"?"arabic":"basic",startSymbol:n.textEncoder==="ArabicEncoderWithStartSymbol"})}async diacritize(t){let n=t;n.length>this.config.maxLen&&(n=n.slice(0,this.config.maxLen));let r=this.encoder.clean(n),a=this.stripDiacritics(r),s=this.encoder.inputToSequence(a);if(s.length===0)return n;let o=this.config.batchSize,c=this.config.maxLen,i=this.encoder.inputPadId,l=[];for(let k=0;kBigInt(k))),dims:[o,c]},u={name:"lengths",type:"int64",data:new BigInt64Array(Array(o).fill(BigInt(c))),dims:[o]},y=(await this.session.run({src:p,lengths:u}))[this.session.outputNames[0]];if(!y)throw new Error("Rababa model produced no output");let x=zn(y,s.length),v=jn(s,x,this.encoder.inputPadId);return Ce(r,v)}async transform(t){return this.diacritize(t)}stripDiacritics(t){return Array.from(t).filter(n=>!/[ً-ْ]/.test(n)).join("")}async dispose(){await this.session.dispose()}}});var _t={};B(_t,{rababa:()=>Gn,rababaReverse:()=>Hn,resetRababaConfigs:()=>Bn,setRababaConfig:()=>Dn});function Dn(e,t){ze.set(e,t)}function Bn(){ze=new Map(Object.entries(kt))}function Pn(e){let t=ze.get(e);if(!t)throw new Error(`No rababa config registered under '${e}'. Register one via setRababaConfig() before invoking rababa.`);return t}function Un(e){return{maxLen:Number(e.max_len??e.maxLen??200),batchSize:Number(e.batch_size??e.batchSize??32),textEncoder:e.text_encoder??"ArabicEncoderWithStartSymbol",textCleaner:e.text_cleaner??"valid_arabic_cleaners"}}async function Fn(e){let t=Oe.get(e);if(!t){let n=Pn(e);t=(async()=>{let r=await qn(n.model),a=await R(r),s=Un(n.config);return se({session:a,artifacts:{},config:s})})(),Oe.set(e,t),t.catch(()=>Oe.delete(e))}return t}async function qn(e){if(e.startsWith("file:")||e.startsWith(".")){let{readFile:n}=await import("node:fs/promises"),r=e.startsWith("file:")?e.slice(5):e;return new Uint8Array(await n(r))}let t=await fetch(e);if(!t.ok)throw new Error(`Failed to fetch ${e}: ${t.status}`);return new Uint8Array(await t.arrayBuffer())}async function Gn(e,t={}){let n=t.config??"200";return(await Fn(n)).diacritize(e)}function Hn(e){return e.replace(/[ًٌٍَُِّْ]/g,"")}var kt,ze,Oe,xt=d(()=>{"use strict";ne();Ne();kt=Object.freeze({200:Object.freeze({model:"https://github.com/secryst/rababa-models/releases/download/0.1/diacritization_model_arabic.onnx",config:Object.freeze({session_name:"base",text_encoder:"ArabicEncoderWithStartSymbol",text_cleaner:"valid_arabic_cleaners",max_len:200,batch_size:32})})}),ze=new Map(Object.entries(kt));Oe=new Map});function Et(e){Tt=e.replace(/\/$/,"")}function oe(){return Tt}var Tt,je=d(()=>{"use strict";Tt="https://cdn.jsdelivr.net/gh/interscript/ml-models@main/npm/models"});function Ct(e){$e=e,E=null}function It(e){Mt=e,E=null}function Wn(){return`${oe()}/npm/models/manifest.json`}async function De(){if(E)return E;if($e)return E=$e,E;let e=Mt??Wn(),t=await fetch(e);if(!t.ok)throw new Error(`Failed to load model manifest from ${e}: ${t.status} ${t.statusText}`);let n=await t.json();return E=n,n}async function G(e,t){let n=await De(),r=t.startsWith(`${e}_`)?t:`${e}_${t}`;return n.models[r]??n.models[t]??null}function H(e,t="q8",n="onnx"){let r=Rt(e,t,n),a=e.cdn_base.replace("{version}",e.version),s=e.github_base.replace("{version}",e.version);return{primary:`${a}${r}`,fallback:`${s}${r}`,assetName:r}}function ie(e,t="q8",n="onnx"){return[`${Rt(e,t,n)}.sha256`,"vocab.json","config.json"]}function Rt(e,t,n="onnx"){return`${Qn(e)}${Vn[t]}${Kn[n]}`}function Qn(e){let n=e.github_base.match(/([^/]+)-v\{version\}\/$/)?.[1];if(n)return n;throw new Error(`Cannot extract task name from manifest entry. github_base=${e.github_base}`)}var Vn,Kn,E,$e,Mt,Be=d(()=>{"use strict";je();Vn={fp32:"",q8:"-q8",q4:"-q4",fp16:"-fp16"},Kn={onnx:".onnx",tflite:".tflite"},E=null,$e=null,Mt=null});async function Ot(e,t={}){let n=t.variant??"q8",r=t.format??"onnx",a=t.webgpu??!0,s=e.url??await Jn(e,n,r),o=await Nt(s),c=await Yn(e,n,r),i={};await Promise.all(c.map(async({filename:u,url:S})=>{try{let y=await Nt(S);u.endsWith(".json")||u.endsWith(".yaml")||u.endsWith(".yml")||u.endsWith(".sha256")?i[u]=new TextDecoder().decode(y):i[u]=y}catch{}}));let l={webgpu:a};return r==="tflite"&&(l.runtime="litert",t.litertAccelerator!==void 0&&(l.litertAccelerator=t.litertAccelerator),t.inputNames!==void 0&&(l.inputNames=t.inputNames),t.outputNames!==void 0&&(l.outputNames=t.outputNames)),{session:await R(o,l),artifacts:i}}async function Jn(e,t,n){let r=await G(e.kind,e.id);if(!r)throw new Error(`No manifest entry for kind=${e.kind} id=${e.id}. Pass an explicit \`url\` on the ModelRef or pin a task version in the manifest.`);let{primary:a}=H(r,t,n);return a}async function Yn(e,t,n){if(e.url)return[];let r=await G(e.kind,e.id);if(!r)return[];let{primary:a,assetName:s}=H(r,t,n),o=a.slice(0,a.lastIndexOf("/")+1);return ie(r,t,n).map(c=>({filename:c,url:`${o}${c.startsWith(s),c}`}))}async function Nt(e){if(e.startsWith("file:")||e.startsWith(".")&&typeof process<"u"&&process.versions?.node){let{readFile:n}=await import("node:fs/promises"),r=e.startsWith("file:")?e.slice(5):e;return new Uint8Array(await n(r))}let t=await fetch(e);if(!t.ok)throw new Error(`Failed to fetch ${e}: ${t.status} ${t.statusText}`);return new Uint8Array(await t.arrayBuffer())}var zt=d(()=>{"use strict";ne();Be()});function z(e,t){if(ce.has(e))throw new Error(`Model kind "${e}" is already registered`);ce.set(e,t)}function Xn(e){return`${e.kind}/${e.id}/${e.url??"_default"}`}async function jt(e){let t=Xn(e),n=V.get(t);if(n)return n;let r=ce.get(e.kind);if(!r)throw new Error(`Unknown model kind: "${e.kind}". Register a factory via registerModel("${e.kind}", factory).`);let a=(async()=>{let{session:s,artifacts:o}=await Ot(e);return r({session:s,artifacts:o})})();return V.set(t,a),a.catch(()=>V.delete(t)),a}function $t(){return[...ce.keys()]}async function Dt(){let e=[...V.values()];V.clear(),await Promise.allSettled(e.map(async t=>{try{await(await t).dispose()}catch{}}))}var ce,V,le=d(()=>{"use strict";zt();ce=new Map;V=new Map});var Bt=d(()=>{"use strict";le();Ne();Me();Ie();Ee();N();z("rababa",async e=>se(e))});function Pe(e){let t=e.split(` +`),n=null,r=[],a=[];for(let s of t){let o=s.trimEnd();if(o==="input:"){n="input";continue}if(o==="target:"){n="target";continue}let c=o.match(/^\s+-\s+"?(.+?)"?\s*$/);if(c&&n){let i=c[1];n==="input"?r.push(i):a.push(i)}}return{input:r,target:a}}function Ue(e){return{input:new K(e.input),target:new K(e.target)}}var K,Fe=d(()=>{"use strict";K=class{stoi;itos;length;constructor(t,n=[]){let r=[...n,...t];this.itos=r,this.stoi=Object.freeze(Object.fromEntries(r.map((a,s)=>[a,s]))),this.length=r.length}encode(t){return this.stoi[t]??-1}decode(t){return this.itos[t]??""}encodeSequence(t){return Array.from(t).map(n=>this.encode(n))}decodeSequence(t){return t.map(n=>this.decode(n)).join("")}}});function Pt(e){let t=new Uint8Array(e*e);for(let n=0;nn===t?0:1))}function Ge(e,t,n,r){let a=Pt(t),s=qe(n),o=qe(r);return{tgt_mask:{name:"tgt_mask",type:"int8",data:a,dims:[t,t]},src_key_padding_mask:{name:"src_key_padding_mask",type:"int8",data:s,dims:[1,e]},tgt_key_padding_mask:{name:"tgt_key_padding_mask",type:"int8",data:o,dims:[1,t]},memory_key_padding_mask:{name:"memory_key_padding_mask",type:"int8",data:s,dims:[1,e]}}}var He=d(()=>{"use strict"});async function qt(e){let t=e.artifacts["vocabs.yaml"];if(!t)throw new Error("Secryst model missing vocabs.yaml");let n=typeof t=="string"?t:new TextDecoder().decode(t),r=Pe(n),{input:a,target:s}=Ue(r);return new Ve(e.session,a,s)}var Zn,Ut,Ft,Ve,Gt=d(()=>{"use strict";Fe();He();Zn=100,Ut="",Ft="",Ve=class{kind="secryst";session;inputVocab;targetVocab;constructor(t,n,r){this.session=t,this.inputVocab=n,this.targetVocab=r}async translate(t,n=Zn){let r=[this.inputVocab.encode(Ut),...this.inputVocab.encodeSequence(t),this.inputVocab.encode(Ft)].filter(o=>o>=0),a=[this.targetVocab.encode(Ut)],s=this.targetVocab.encode(Ft);for(let o=0;oBigInt(f))),dims:[1,r.length]},tgt:{name:"tgt",type:"int64",data:new BigInt64Array(a.map(f=>BigInt(f))),dims:[1,a.length]},...c},p=(await this.session.run(i))[this.session.outputNames[0]];if(!p)throw new Error("Secryst model produced no output");let u=p.dims,S=u[u.length-1],y=p.data,x=o*S,v=0,k=-1/0;for(let f=0;fk&&(k=Y,v=f)}if(v===s)break;a.push(v)}return this.targetVocab.decodeSequence(a.slice(1))}async transform(t){let n=t.split(` `),r=[];for(let a of n)r.push(await this.translate(a));return r.join(` -`)}async dispose(){await this.session.dispose()}}});var qt=u(()=>{"use strict";le();Ft();Pe();He();z("secryst",async t=>Pt(t))});var Ht={};B(Ht,{artifactUrls:()=>G,createSession:()=>N,detectBackend:()=>Ae,getModelBase:()=>oe,loadManifest:()=>$e,loadModel:()=>Ot,registerModel:()=>z,registeredKinds:()=>zt,resetModels:()=>jt,resolveManifestEntry:()=>H,setInlineManifest:()=>Et,setManifestUrl:()=>Tt,setModelBase:()=>xt,sidecarFilenames:()=>ie});var Gt=u(()=>{"use strict";le();ne();ze();De();$t();qt()});import{createYoga as dr,createSchema as mr}from"graphql-yoga";import{Hono as fr}from"hono";import{cors as hr}from"hono/cors";var ye=` +`)}async dispose(){await this.session.dispose()}}});var Ht=d(()=>{"use strict";le();Gt();Fe();He();z("secryst",async e=>qt(e))});var Vt={};B(Vt,{artifactUrls:()=>H,createSession:()=>R,detectBackend:()=>ke,getModelBase:()=>oe,loadManifest:()=>De,loadModel:()=>jt,registerModel:()=>z,registeredKinds:()=>$t,resetModels:()=>Dt,resolveManifestEntry:()=>G,setInlineManifest:()=>Ct,setManifestUrl:()=>It,setModelBase:()=>Et,sidecarFilenames:()=>ie});var Kt=d(()=>{"use strict";le();ne();je();Be();Bt();Ht()});import{createYoga as gr,createSchema as br}from"graphql-yoga";import{Hono as yr}from"hono";import{cors as Lr}from"hono/cors";var Le=` type DetectionResult { mapName: String distance: Float @@ -13,4 +13,67 @@ var mn=Object.defineProperty;var u=(t,e,n)=>()=>{if(n)throw n[0];try{return t&&( transliterate(systemCode: String!, input: String!): String detect(input: String!, output: String!): [DetectionResult] } -`;import{Hono as ur}from"hono";var y=class extends Error{cause;constructor(e,n){super(e,n),this.name=new.target.name,this.cause=n?.cause}},g=class extends y{systemCode;constructor(e){super(`Map not found: ${e}`),this.systemCode=e}},T=class extends y{},A=class extends y{},C=class extends y{dependency;constructor(e){super(`Map dependency missing: ${e}`),this.dependency=e}};var X=class{strategies;cache=new Map;known=new Map;options;constructor(e,n={}){this.strategies=e,this.options=n}load(e){let n=this.cache.get(e);if(n)return n;let r=this.known.get(e);if(r)return this.cache.set(e,r),r;for(let a of this.strategies){let s=a(e);if(s&&typeof s.then!="function"){let o=s;return this.cache.set(e,o),this.known.set(e,o),this.options.onLoaded?.(e,o),o}}throw new g(e)}async loadAsync(e){let n=this.cache.get(e);if(n)return n;let r=this.known.get(e);if(r)return this.cache.set(e,r),r;for(let a of this.strategies){let s=await a(e);if(s)return this.cache.set(e,s),this.known.set(e,s),this.options.onLoaded?.(e,s),s}throw new g(e)}clear(){this.cache.clear()}loadedMaps(){return Array.from(this.known.keys())}register(e,n){this.known.set(e,n),this.cache.set(e,n)}};var U=class t{current;map;loader;aliasCache=new Map;functions;constructor(e,n,r){this.map=e,this.current=n,this.functions=e.functions,this.loader=r}resolveAlias(e){if(this.aliasCache.has(e))return this.aliasCache.get(e);let n=this.map.aliases.get(e);if(!n&&this.loader)for(let r of this.map.dependencies)try{let s=this.loader.load(r).aliases.get(e);if(s){n=s;break}}catch{}return n&&this.aliasCache.set(e,n),n}withMap(e){return new t(e,this.current,this.loader)}loadDependency(e){if(!this.loader)throw new Error(`Cannot resolve dependency ${e}: no loader configured`);return this.loader.load(e)}};function Le(){return{children:new Map,match:null}}function Xe(t){let e=Le();for(let[n,r]of t){if(n.length===0)continue;let a=e;for(let c=0;c0?(n+=c,a+=o):(n+=t[a],a+=1)}return n}function P(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function et(t){return t.toLowerCase()}function tt(t){return t.toUpperCase()}function nt(t,e={}){let n=e.wordSeparator??" ";return n===""?t.charAt(0).toUpperCase()+t.slice(1).toLowerCase():t.split(n).map(r=>r.length===0?r:r.charAt(0).toUpperCase()+r.slice(1).toLowerCase()).join(n)}function rt(t,e={}){let n=e.separator??" ";return t.split("").join(n)}function at(t){return t.normalize("NFC")}function st(t){return t.normalize("NFD")}function ot(t,e){if(e.length===0)return t;let n=e.map((a,s)=>`(?<__r${s}>${a.pattern})`),r=new RegExp(n.join("|"),"gmu");return t.replace(r,(...a)=>{let s=a[a.length-1];for(let o=0;om(a,e).re),r=t.of.length>0?m(t.of[0],e).literal:"";return{re:`(?:${n.join("|")})`,literal:r}}case"any_char_class":{if(t.range){let[n,r]=t.range;return{re:`[${P(n)}-${P(r)}]`,literal:n??""}}return t.chars&&t.chars.length>0?{re:`[${t.chars.map(r=>P(r)).join("")}]`,literal:t.chars[0]}:{re:"[^]",literal:""}}case"group":{let n=t.items.map(s=>m(s,e)),r=n.map(s=>s.re).join(""),a=n.map(s=>s.literal).join("");return{re:`(?:${r})`,literal:a}}case"repeat":{let n=m(t.item,e).re,{min:r,max:a}=t,s=a===null?1/0:a,o=s===1/0?r===0?"*":"+":`{${r},${s}}`;return{re:`(?:${n})${o}`,literal:""}}case"stage_ref":return{re:"",literal:""}}}function F(t,e){switch(t.kind){case"string":return t.value;case"alias":{let n=Z[t.name];if(n)return n.literal===""?null:n.literal;let r=e.resolveAlias(t.name);return r?F(r,e):null}case"capture_group":case"capture_ref":case"repeat":case"stage_ref":return null;case"any_char_class":return t.chars&&t.chars.length>0?t.chars[0]:t.range?t.range[0]:null;case"any":return t.of.length===0?null:F(t.of[0],e);case"group":{let n="";for(let r of t.items){let a=F(r,e);if(a===null)return null;n+=a}return n}}}function R(t,e){switch(t.kind){case"string":return[t.value];case"alias":{if(Z[t.name])return null;let r=e.resolveAlias(t.name);return r?R(r,e):null}case"any_char_class":{if(t.chars)return[...t.chars];if(t.range){let[n,r]=t.range,a=n.codePointAt(0),s=r.codePointAt(0),o=[];for(let c=a;c<=s;c++)o.push(String.fromCodePoint(c));return o}return null}case"any":{let n=[];for(let r of t.of){let a=R(r,e);if(a===null)return null;n.push(...a)}return n}case"group":{let n=[""];for(let r of t.items){let a=R(r,e);if(a===null)return null;let s=[];for(let o of n)for(let c of a)s.push(o+c);n=s}return n}default:return null}}function w(t,e){switch(t.kind){case"string":return t.value.length;case"capture_group":return w(t.data,e);case"capture_ref":return 1;case"alias":{if(t.name==="none")return 0;if(Z[t.name])return 1;let n=e.resolveAlias(t.name);return n?w(n,e):1}case"any":return t.of.reduce((n,r)=>Math.max(n,w(r,e)),0);case"any_char_class":return 1;case"group":return t.items.reduce((n,r)=>n+w(r,e),0);case"repeat":return w(t.item,e);case"stage_ref":return 1}}var Z=Object.freeze({any_character:{re:".",literal:""},none:{re:"",literal:""},space:{re:" ",literal:" "},whitespace:{re:"\\s+",literal:" "},boundary:{re:"(?:(?nt(t,e??{}),separate:(t,e)=>rt(t,e??{}),compose:at,decompose:st};function it(t,e){let n=t.functions.get(e)?.impl;if(n)return n;let r=fn[e];if(r)return r}var hn={sub:(t,e)=>gn(t,e),run:(t,e)=>{let n=t.docName?e.loadDependency(t.docName):e.map,r=n.stages.find(s=>s.name===t.stage);if(!r)throw new A(`Stage not found: ${t.stage}`);let a=e.withMap(n);for(let s of r.rules)M(s,a);e.current=a.current},funcall:(t,e)=>{let n=it(e,t.name);if(!n)throw new A(`Unknown function: ${t.name}`);e.current=n(e.current,t.kwargs??{})},parallel:(t,e)=>{let n=[],r=[];for(let o of t.rules)o.kind==="sub"&&o.from?n.push(o):r.push(o);let a=o=>!o.before&&!o.after&&!o.notBefore&&!o.notAfter&&R(o.from,e)!==null;if(n.some(o=>!a(o))){let c=n.map((i,l)=>({rule:i,idx:l,len:w(i.from,e)+(i.before?w(i.before,e):0)+(i.after?w(i.after,e):0)+(i.notBefore?w(i.notBefore,e):0)+(i.notAfter?w(i.notAfter,e):0)+(i.priority??0)})).sort((i,l)=>l.len-i.len||i.idx-l.idx).map(({rule:i})=>{let l=m(i.from,e),p=i.before?m(i.before,e).re:"",d=i.after?m(i.after,e).re:"",S=i.notBefore?m(i.notBefore,e).re:"",b=i.notAfter?m(i.notAfter,e).re:"",x=[p?`(?<=${p})`:"",S?`(?ct(v,f,Q):v}});e.current=ot(e.current,c)}else{let o=[];for(let c of n){if(c.to&&c.to.kind==="funcall_inline")continue;let i=c.to?F(c.to,e):"";if(i===null)continue;let l=R(c.from,e);if(l!==null)for(let p of l)o.push([p,i])}o.length>0&&(e.current=Ze(e.current,Xe(o)))}for(let o of r)M(o,e)},sequential:(t,e)=>{for(let n of t.rules)M(n,e)}};function gn(t,e){if(!t.from)throw new A("Sub rule missing 'from'");let n=m(t.from,e),r=t.before?m(t.before,e).re:"",a=t.after?m(t.after,e).re:"",s=t.notBefore?m(t.notBefore,e).re:"",o=t.notAfter?m(t.notAfter,e).re:"",c=[];r&&c.push(`(?<=${r})`),s&&c.push(`(?{let p=l;return(d,...S)=>ct(p,d,S)})():l)}function ct(t,e,n){return t.replace(/\$(\d+)/g,(r,a)=>{let s=parseInt(a,10);return n[s-1]??e})}function lt(t,e){if(!t)return"";if(t.kind==="funcall_inline"){let r=it(e,t.name);if(!r)throw new A(`Unknown inline function: ${t.name}`);return a=>r(a)}return m(t,e).literal}function M(t,e){let n=hn[t.kind];n(t,e)}var Ve=new Set(["rababa","secryst"]);function Vt(t){for(let e of t){if(e.kind==="funcall"&&Ve.has(e.name))return!0;if(e.kind==="parallel"||e.kind==="sequential"){for(let n of e.rules)if(n.kind==="funcall"&&Ve.has(n.name))return!0}}return!1}function W(t,e,n,r){let a=t.stages.find(o=>o.name===e);if(!a)return n;if(Vt(a.rules))throw new Error(`Stage "${e}" contains ML function calls (rababa/secryst). Use transliterateAsync() instead of transliterate().`);let s=new U(t,n,r);for(let o of a.rules)M(o,s);return s.current}async function Kt(t,e,n,r){let a=t.stages.find(o=>o.name===e);if(!a)return n;if(!Vt(a.rules))return W(t,e,n,r);let s=new U(t,n,r);for(let o of a.rules)await Xn(o,s);return s.current}async function Xn(t,e){if(t.kind==="funcall"){await Zn(t,e);return}M(t,e)}async function Zn(t,e){if(t.name==="rababa"){let{rababa:n}=await Promise.resolve().then(()=>(_t(),At));e.current=await n(e.current,t.kwargs);return}if(Ve.has(t.name)){let{loadModel:n}=await Promise.resolve().then(()=>(Gt(),Ht)),r=t.kwargs?.config??t.kwargs?.model??"default",a=await n({kind:t.name,id:r});e.current=await a.transform(e.current);return}M({kind:"funcall",name:t.name,kwargs:t.kwargs},e)}function er(t,e){if(t===e)return 0;if(t.length===0)return e.length;if(e.length===0)return t.length;let n=new Array(e.length+1),r=new Array(e.length+1);for(let a=0;a<=e.length;a++)n[a]=a;for(let a=1;a<=t.length;a++){r[0]=a;for(let s=1;s<=e.length;s++){let o=t[a-1]===e[s-1]?0:1;r[s]=Math.min(n[s]+1,r[s-1]+1,n[s-1]+o)}[n,r]=[r,n]}return n[e.length]}function tr(t){let e=t.replace(/[.+?^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*");return new RegExp(`^${e}$`)}function Wt(t,e,n,r={},a){let s=[],o=r.mapPattern?tr(r.mapPattern):null,c=a??n.loadedMaps();for(let i of c){if(o&&!o.test(i))continue;let l;try{let p=n.load(i);l=W(p,"main",t,n)}catch(p){if(p instanceof y)continue;throw p}s.push({mapName:i,distance:er(l,e)})}return s.sort((i,l)=>i.distance-l.distance)}function Ke(t){let e={schemaVersion:t.schemaVersion,systemCode:t.systemCode,dependencies:t.dependencies,stages:t.stages,aliases:new Map(Object.entries(t.aliases)),functions:new Map};return t.metadata&&(e.metadata=t.metadata),e}var nr="main",ue=class{loader;defaultStage;constructor(e={}){this.loader=new X(e.strategies??[]),this.defaultStage=e.defaultStage??nr}loadMap(e){let n=this.loader.load(e);for(let r of n.dependencies)try{this.loader.load(r)}catch(a){throw a instanceof g?new C(r):a}return n}async loadMapAsync(e){let n=await this.loader.loadAsync(e),r=new Set,a=[...n.dependencies];for(;a.length>0;){let s=a.shift();if(!r.has(s)){r.add(s);try{let o=await this.loader.loadAsync(s);for(let c of o.dependencies)r.has(c)||a.push(c)}catch(o){throw o instanceof g?new C(s):o}}}return n}transliterate(e,n,r){try{let a=this.loadMap(e),s=r??this.defaultStage;return W(a,s,n,this.loader)}catch(a){throw a instanceof y?a:new T(`Transliteration failed for ${e}: ${a.message}`,{cause:a})}}async transliterateAsync(e,n,r){try{let a=await this.loadMapAsync(e),s=r??this.defaultStage;return await Kt(a,s,n,this.loader)}catch(a){throw a instanceof y?a:new T(`Transliteration failed for ${e}: ${a.message}`,{cause:a})}}loadedMaps(){return this.loader.loadedMaps()}getLoader(){return this.loader}detect(e,n,r={},a){return Wt(e,n,this.loader,r,a)}},pe;function Jt(t){pe=new ue(t)}function rr(){return pe||(pe=new ue),pe}function We(t,e,n){return rr().transliterateAsync(t,e,n)}var Yt=["acadsin-zho-Hani-Latn-2002","alalc-amh-Ethi-Latn-1997","alalc-amh-Ethi-Latn-2011","alalc-ara-Arab-Latn-1997","alalc-asm-Deva-Latn-1997","alalc-asm-Deva-Latn-2012","alalc-aze-Arab-Latn-1997","alalc-aze-Cyrl-Latn-1997","alalc-bel-Cyrl-Latn-1997","alalc-ben-Beng-Latn-1997","alalc-ben-Beng-Latn-2017","alalc-bul-Cyrl-Latn-1997","alalc-div-Thaa-Latn-1997","alalc-div-Thaa-Latn-2012","alalc-ell-Grek-Latn-1997","alalc-ell-Grek-Latn-2010","alalc-fas-Arab-Latn-1997","alalc-guj-Gujr-Latn-1997","alalc-guj-Gujr-Latn-2011","alalc-hin-Deva-Latn-1997","alalc-hin-Deva-Latn-2011","alalc-kan-Kana-Latn-1997","alalc-kan-Kana-Latn-2011","alalc-kat-Geok-Latn-1997","alalc-kat-Geok-Latn-2011","alalc-kat-Geor-Latn-1997","alalc-kat-Geor-Latn-2011","alalc-kor-Hang-Latn-1997","alalc-mal-Mlym-Latn-1997","alalc-mal-Mlym-Latn-2012","alalc-mar-Deva-Latn-1997","alalc-mar-Deva-Latn-2011","alalc-mkd-Cyrl-Latn-1997","alalc-mkd-Cyrl-Latn-2013","alalc-mon-Cyrl-Latn-1997","alalc-ori-Orya-Latn-1997","alalc-ori-Orya-Latn-2011","alalc-pan-Guru-Latn-1997","alalc-pan-Guru-Latn-2011","alalc-pli-Deva-Latn-2012","alalc-pra-Deva-Latn-2012","alalc-rus-Cyrl-Latn-1997","alalc-rus-Cyrl-Latn-2012","alalc-san-Deva-Latn-2012","alalc-sin-Sinh-Latn-1997","alalc-sin-Sinh-Latn-2011","alalc-srp-Cyrl-Latn-1997","alalc-srp-Cyrl-Latn-2013","alalc-tam-Taml-Latn-1997","alalc-tam-Taml-Latn-2011","alalc-tel-Telu-Latn-1997","alalc-tel-Telu-Latn-2011","alalc-tir-Ethi-Latn-1997","alalc-tir-Ethi-Latn-2011","alalc-ukr-Cyrl-Latn-1997","alalc-ukr-Cyrl-Latn-2011","apcbg-bul-Cyrl-Latn-1995","az-aze-Cyrl-Latn-1939","az-aze-Cyrl-Latn-1958","bas-rus-Cyrl-Latn-2017-bss","bas-rus-Cyrl-Latn-2017-oss","bgn-jpn-Hrkt-Latn-1962","bgn-kor-Hang-Latn-1943","bgn-kor-Kore-Latn-1943","bgna-bul-Cyrl-Latn-2006","bgna-bul-Cyrl-Latn-2009","bgnpcgn-amh-Ethi-Latn-1967","bgnpcgn-ara-Arab-Latn-1956","bgnpcgn-arm-Armn-Latn-1981","bgnpcgn-aze-Cyrl-Latn-1993","bgnpcgn-bak-Cyrl-Latn-2007","bgnpcgn-bal-Arab-Latn-2008","bgnpcgn-bel-Cyrl-Latn-1979","bgnpcgn-bul-Cyrl-Latn-1952","bgnpcgn-bul-Cyrl-Latn-2013","bgnpcgn-che-Cyrl-Latn-2008","bgnpcgn-deu-Latn-Latn-2000","bgnpcgn-div-Thaa-Latn-1972","bgnpcgn-div-Thaa-Latn-1988","bgnpcgn-ell-Grek-Latn-1962","bgnpcgn-ell-Grek-Latn-1996","bgnpcgn-fao-Latn-Latn-1964","bgnpcgn-fao-Latn-Latn-1968","bgnpcgn-fas-Arab-Latn-1956","bgnpcgn-isl-Latn-Latn-1964","bgnpcgn-isl-Latn-Latn-1968","bgnpcgn-jpn-Hrkt-Latn-1976","bgnpcgn-kat-Geor-Latn-1981","bgnpcgn-kat-Geor-Latn-2009","bgnpcgn-kaz-Cyrl-Latn-1979","bgnpcgn-kir-Cyrl-Latn-1979","bgnpcgn-kor-Hang-Latn-kn-1945","bgnpcgn-kor-Hang-Latn-rok-2011","bgnpcgn-kor-Kore-Latn-rok-2011","bgnpcgn-kur-Arab-Latn-2007","bgnpcgn-mkd-Cyrl-Latn-1981","bgnpcgn-mkd-Cyrl-Latn-2013","bgnpcgn-mon-Cyrl-Latn-1964","bgnpcgn-nep-Deva-Latn-2011","bgnpcgn-per-Arab-Latn-1958","bgnpcgn-prs-Arab-Latn-2007","bgnpcgn-prs-Arab-Latn-yaghoubi","bgnpcgn-pus-Arab-Latn-1968","bgnpcgn-ron-Cyrl-Latn-2002","bgnpcgn-rue-Cyrl-Latn-2016","bgnpcgn-rus-Cyrl-Latn-1947","bgnpcgn-sme-Latn-Latn-1984","bgnpcgn-srp-Cyrl-Latn-1962","bgnpcgn-srp-Cyrl-Latn-2005","bgnpcgn-tat-Cyrl-Latn-2007","bgnpcgn-tgk-Cyrl-Latn-1994","bgnpcgn-tir-Ethi-Latn-2007","bgnpcgn-ukr-Cyrl-Latn-1965","bgnpcgn-ukr-Cyrl-Latn-2019","bgnpcgn-urd-Arab-Latn-2007","bgnpcgn-uzb-Cyrl-Latn-1979","bgnpcgn-uzb-Cyrl-Latn-2000","bgnpcgn-zho-Hans-Latn-1979","bis-asm-Beng-Latn-13194-1991","bis-ben-Beng-Latn-13194-1991","bis-dev-Deva-Latn-13194-1991","bis-guj-Gujr-Latn-13194-1991","bis-kan-Kana-Latn-13194-1991","bis-mlm-Mlym-Latn-13194-1991","bis-ori-Orya-Latn-13194-1991","bis-pnj-Guru-Latn-13194-1991","bis-tel-Telu-Latn-13194-1991","bis-tml-Taml-Latn-13194-1991","by-bel-Cyrl-Latn-1998","by-bel-Cyrl-Latn-2007","din-grc-Grek-Latn-31634-2011-t1","din-hin-Deva-Latn-33904-2018","din-kat-Geor-Latn-32707-2010","din-mar-Deva-Latn-33904-2018","din-nep-Deva-Latn-33904-2018","din-pli-Deva-Latn-33904-2018","din-pra-Deva-Latn-33904-2018","din-san-Deva-Latn-33904-2018","din-tam-Taml-Latn-33903-2016","dos-nep-Deva-Latn-1997","elot-ell-Grek-Latn-743-1982-tl","elot-ell-Grek-Latn-743-1982-ts","elot-ell-Grek-Latn-743-2001-tl","elot-ell-Grek-Latn-743-2001-ts","ggg-kat-Geor-Latn-2002","gki-bel-Cyrl-Latn-1992","gki-bel-Cyrl-Latn-2000","gost-rus-Cyrl-Latn-16876-71-1983","gost-rus-Cyrl-Latn-7.79-2000-2002","hk-yue-Hani-Latn-1888","icao-bel-Cyrl-Latn-9303","icao-bul-Cyrl-Latn-9303","icao-fas-Arab-Latn-9303","icao-heb-Hebr-Latn-9303","icao-mkd-Cyrl-Latn-9303","icao-rus-Cyrl-Latn-9303","icao-srp-Cyrl-Latn-9303","icao-ukr-Cyrl-Latn-9303","iso-ara-Arab-Latn-233-1984","iso-ara-Arab-Latn-233-2-1993","iso-asm-Beng-Latn-15919-2001","iso-ben-Beng-Latn-15919-2001","iso-ell-Grek-Latn-843-1997-t1","iso-ell-Grek-Latn-843-1997-t2","iso-guj-Gujr-Latn-15919-2001","iso-hin-Deva-Latn-15919-2001","iso-inc-Deva-Latn-15919-2001","iso-jpn-Hrkt-Latn-3602-1989","iso-kan-Kana-Latn-15919-2001","iso-kat-Geor-Latn-9984-1996","iso-kor-Hang-Latn-1996-method1","iso-kor-Hang-Latn-1996-method2","iso-mal-Mlym-Latn-15919-2001","iso-mar-Deva-Latn-15919-2001","iso-nep-Deva-Latn-15919-2001","iso-ori-Orya-Latn-15919-2001","iso-pan-Guru-Latn-15919-2001","iso-pli-Beng-Latn-15919-2001","iso-pli-Deva-Latn-15919-2001","iso-pli-Sinh-Latn-15919-2001","iso-pli-Thai-Latn-15919-2001","iso-pra-Deva-Latn-15919-2001","iso-prs-Arab-Latn-233-3-1999","iso-rus-Cyrl-Latn-9-1995","iso-san-Deva-Latn-15919-2001","iso-tam-Taml-Latn-15919-2001","iso-tel-Telu-Latn-15919-2001","iso-tha-Thai-Latn-11940-1998","kp-kor-Hang-Latn-2002","lshk-yue-Hani-Latn-jyutping-1993","masm-mon-Cyrl-Latn-5217-2012","masm-mon-Latn-Cyrl-5217-2012","mext-jpn-Hrkt-Latn-1954","moct-kor-Hang-Latn-2000","mofa-jpn-Hrkt-Latn-1989","mv-div-Thaa-Latn-1987","mvd-bel-Cyrl-Latn-2008","mvd-bel-Cyrl-Latn-2010","mvd-rus-Cyrl-Latn-2008","mvd-rus-Cyrl-Latn-2010","odni-ara-Arab-Latn-2004","odni-ara-Arab-Latn-2015","odni-aze-Cyrl-Latn-2015","odni-bel-Cyrl-Latn-2015","odni-bul-Cyrl-Latn-2005","odni-bul-Cyrl-Latn-2015","odni-che-Cyrl-Latn-2015","odni-fas-Arab-Latn-2004","odni-fas-Arab-Latn-2015","odni-hin-Deva-Latn-2004","odni-hin-Deva-Latn-2015","odni-kat-Geor-Latn-2015","odni-kaz-Cyrl-Latn-2015","odni-kir-Cyrl-Latn-2015","odni-kor-Hang-Latn-2015","odni-mkd-Cyrl-Latn-2005","odni-mkd-Cyrl-Latn-2015","odni-prs-Arab-Latn-2004","odni-prs-Arab-Latn-2015","odni-pus-Arab-Latn-2011","odni-rus-Cyrl-Latn-2015","odni-srp-Cyrl-Latn-2005","odni-srp-Cyrl-Latn-2015","odni-tat-Cyrl-Latn-2015","odni-tgk-Cyrl-Latn-2015","odni-tuk-Cyrl-Latn-2015","odni-uig-Cyrl-Latn-2015","odni-ukr-Cyrl-Latn-2015","odni-urd-Arab-Latn-2015","odni-uzb-Cyrl-Latn-2015","posix","sac-zho-Hans-Latn-1979","sasm-mon-Mong-Latn-general-1978","sasm-mon-Mong-Latn-phonetic-1978","ses-ara-Arab-Latn-1930","stategeocadastre-ukr-Cyrl-Latn-1993","ua-ukr-Cyrl-Latn-1996","ua-ukr-Cyrl-Latn-2007","ua-ukr-Cyrl-Latn-2010","un-amh-Ethi-Latn-2016","un-ara-Arab-Latn-1971","un-ara-Arab-Latn-1972","un-ara-Arab-Latn-2017","un-asm-Beng-Latn-1972","un-bel-Cyrl-Latn-2007","un-ben-Beng-Latn-2016","un-bul-Cyrl-Latn-1977","un-ell-Grek-Latn-1987-phonetic","un-ell-Grek-Latn-1987-tl","un-ell-Grek-Latn-1987-ts","un-guj-Gujr-Latn-1972","un-hin-Deva-Latn-2016","un-kan-Kana-Latn-2016","un-mal-Mlym-Latn-1972","un-mar-Deva-Latn-2016","un-mkd-Cyrl-Latn-1977","un-mon-Mong-Latn-general-2013","un-mon-Mong-Latn-phonetic-2013","un-nep-Deva-Latn-1972","un-nep-Deva-Latn-2013","un-ori-Orya-Latn-1972","un-pan-Guru-Latn-1972","un-prs-Arab-Latn-1967","un-rus-Cyrl-Latn-1987","un-sin-Sinh-Latn-1972","un-srp-Cyrl-Latn-1997","un-tam-Taml-Latn-1972","un-tel-Telu-Latn-1972","un-ukr-Cyrl-Latn-1998","un-ukr-Cyrl-Latn-2012","un-urd-Arab-Latn-1972","unicode","var-Cyrl","var-amh-Ethi-Latn-eae-2003","var-ara-Arab-Arab-rababa","var-gez-Ethi-Latn-eae-2003","var-hin-Deva-Latn-hunterian-1872","var-jpn-Hrkt-Latn-hepburn-1886","var-jpn-Hrkt-Latn-hepburn-1954","var-kor","var-kor-Hang-Hang-jamo","var-kor-Hang-Latn-mr-1939","var-kor-Kore-Hang-2013","var-kor-Kore-Latn-mr-1939","var-mar-Deva-Latn-hunterian-1872","var-mon-Mong-Latn-1930","var-mon-Mong-Latn-lessing","var-mon-Mong-Latn-vpmc","var-pra-Deva-Latn-iast-1912","var-san-Deva-Latn-iast-1912","var-zho-Hani-Latn-wd-1979"];var ar=new Set(["unicode","posix","var-Cyrl","var-kor"]),sr=new Set(["var-ara-Arab-Arab-rababa"]),Xt=Yt.filter(t=>!ar.has(t)),or=Xt.filter(t=>!sr.has(t)),Qt=new Map;function k(){return Xt}function Zt(){return or}async function en(t,e){let n=Qt.get(e);if(n)return n;let r=await t.fetch(new Request(`https://assets.internal/${e}.json`));if(!r.ok)throw new g(e);let a=await r.json(),s=Ke(a);return Qt.set(e,s),s}var tn;function nn(t){if(tn===t)return;Jt({strategies:[n=>en(t,n)]}),tn=t}async function rn(t,e,n){return nn(t),We(e,n)}function ir(t,e){if(t===e)return 0;if(!t.length)return e.length;if(!e.length)return t.length;let n=Array.from({length:e.length+1},(r,a)=>a);for(let r=1;r<=t.length;r++){let a=[r];for(let s=1;s<=e.length;s++)a[s]=Math.min(n[s]+1,a[s-1]+1,n[s-1]+(t[r-1]===e[s-1]?0:1));n=a}return n[e.length]}async function an(t,e,n){nn(t);let r=[];for(let a of Zt())try{let s=await We(a,e);r.push({mapName:a,distance:ir(s,n)})}catch{continue}return r.sort((a,s)=>a.distance-s.distance)}var j=class extends Error{constructor(n){super(`Input is too long (max ${n} characters)`);this.max=n;this.name="InputTooLongError"}max},$=class extends Error{constructor(n){super(`Couldn't locate ${n}`);this.systemCode=n;this.name="MapNotFoundError"}systemCode};var D={input_max_size:1e6},de=12e4;var fe="3.0.0-cloudflare.1",Je;function J(t){Je=t}var me;function sn(t,e){me=t&&e?{endpoint:t,token:e}:void 0}var cr={"var-ara-Arab-Arab-rababa":"ara-diac-1.0"};async function lr(t,e){if(!me)throw new Error("ML inference unavailable \u2014 ML_ENDPOINT/ML_TOKEN not set");let n=await fetch(`${me.endpoint}/infer`,{method:"POST",headers:{"content-type":"application/json","x-api-key":me.token},body:JSON.stringify({model:t,input:e}),signal:AbortSignal.timeout(de)}).catch(()=>null);if(!n||!n.ok)throw new Error("ML inference upstream failed");let r=await n.json().catch(()=>null);if(!r||typeof r.output!="string")throw new Error("ML inference returned no output");return r.output}function on(){if(!Je)throw new Error("ASSETS binding missing \u2014 see README deployment notes");return Je}async function cn(){return JSON.stringify({version:fe,engine:"interscript-ts@native-interpreter"})}function ln(){return[...k()]}async function he(t,e){if(e.length>D.input_max_size)throw new j(D.input_max_size);let n=cr[t];if(n)return lr(n,e);try{return await rn(on(),t,e)}catch(r){throw r instanceof g?new $(t):r}}async function ge(t,e){return an(on(),t,e)}var pn={version:1,models:[{id:"khm-latn-1.0",task:"translit",scripts:["Khmr","Latn"],precision:"fp32",filename:"khm-latn-1.0-fp32.zip",url:"https://github.com/interscript/interscript-ml/releases/download/khm-latn-1.0/khm-latn-1.0-fp32.zip",parts:null,sha256:"55993d473a2ed9489058779cad7e115db05e4020085b71616468cfae4f2f65cb",size:1418009977,metrics:[{name:"cer",value:27.42,source:"secryst/docs/RESULTS.md#khmer-transliteration-2026-08-14"},{name:"em",value:59.66,source:"secryst/docs/RESULTS.md#khmer-transliteration-2026-08-14"}],parity:{samples:895,cer_delta:0},license:"BSD-3-Clause"},{id:"urd-g2p-1.0",task:"g2p",scripts:["Arab","IPA"],precision:"fp32",filename:"urd-g2p-1.0-fp32.zip",url:"https://github.com/interscript/interscript-ml/releases/download/urd-g2p-1.0/urd-g2p-1.0-fp32.zip",parts:null,sha256:"9f0a248c7116aa7f6b9ac125fb9684a3556f3b8ce8b64567c05a5e7e7a018ebf",size:1418039605,metrics:[{name:"cer",value:14.77,source:"rababa-urdu/docs/RESULTS.md#g2p-urdu-text--ipa"},{name:"em",value:33.6,source:"rababa-urdu/docs/RESULTS.md#g2p-urdu-text--ipa"}],parity:{samples:12699,cer_delta:0},license:"BSD-3-Clause"},{id:"urd-diac-1.0",task:"diacritization",scripts:["Arab","Arab"],precision:"fp32",filename:"urd-diac-1.0-fp32.zip",url:"https://github.com/interscript/interscript-ml/releases/download/urd-diac-1.0/urd-diac-1.0-fp32.zip",parts:null,sha256:"c299ea44a4da4851a52283f8e42d2fb6f8c7a9c443ba7eb0270f97372e10b8ea",size:1417851421,metrics:[{name:"cer",value:3.74,source:"rababa-urdu/docs/RESULTS.md#diacritization-urdu-text--text--haraqat"}],parity:{samples:11940,cer_delta:0},license:"BSD-3-Clause"},{id:"heb-diac-1.0",task:"diacritization",scripts:["Hebr","Hebr"],precision:"fp32",filename:"heb-diac-1.0-fp32.zip",url:null,parts:[{url:"https://github.com/interscript/interscript-ml/releases/download/heb-diac-1.0/heb-diac-1.0-fp32.zip.part-00",sha256:"5497f70cc3c96829e65f1eb0cc401c2d1ffeb4fa909acd4def824c2e019cbc37",size:15e8},{url:"https://github.com/interscript/interscript-ml/releases/download/heb-diac-1.0/heb-diac-1.0-fp32.zip.part-01",sha256:"a7d2011ab4f9326a86e234cc49cb50daf82949e51efbf03a21d5796c46465e9d",size:1281139753}],sha256:"b32fa239e0c56708b6004942de4b9e6e9f265e7cc3828f41d560e96386e20dd8",size:2781139753,metrics:[{name:"der_greedy",value:29,source:"rababa/docs/RESULTS.md#hebrew-diacritization"},{name:"der_beam4",value:17.46,source:"rababa/docs/RESULTS.md#hebrew-diacritization"}],parity:{samples:600,cer_delta:0},license:"BSD-3-Clause"},{id:"tha-g2p-base-1.0",task:"g2p",scripts:["Thai","IPA"],precision:"fp32",filename:"tha-g2p-base-1.0-fp32.zip",url:null,parts:[{url:"https://github.com/interscript/interscript-ml/releases/download/tha-g2p-base-1.0/tha-g2p-base-1.0-fp32.zip.part-00",sha256:"c4525414e5dec91a54d055ca9f1acd51c198f81fbfc55977aa82c1fb038d58d7",size:15e8},{url:"https://github.com/interscript/interscript-ml/releases/download/tha-g2p-base-1.0/tha-g2p-base-1.0-fp32.zip.part-01",sha256:"f5d11fbd75f92e8b5471add867418e2dd4f49a5e258b9ded2f3b5ffa630abe24",size:1281174343}],sha256:"f341a5868867a9847d3f897d1fcc4d1d63b9a59b8913871bcf4ecab48f4fa895",size:2781174343,metrics:[{name:"per_teacher",value:1.25,source:"interscript/interscript-ml docs/RESULTS.md#tha-g2p-base-1.0"},{name:"per_student",value:3.53,source:"interscript/interscript-ml docs/RESULTS.md#tha-g2p-base-1.0"}],parity:{samples:1219,cer_delta:0},license:"BSD-3-Clause"},{id:"tha-g2p-small-1.0",task:"g2p",scripts:["Thai","IPA"],precision:"int8",filename:"tha-g2p-small-1.0-int8.zip",url:"https://github.com/interscript/interscript-ml/releases/download/tha-g2p-small-1.0/tha-g2p-small-1.0-int8.zip",parts:null,sha256:"f2cfa93a42d98aabf08fdc82dfc6bd1574e21993f36558aa581fbe29e0588a94",size:257468517,metrics:[{name:"per_teacher",value:4.43,source:"interscript/interscript-ml docs/RESULTS.md#tha-g2p-small-1.0"},{name:"per_student_beam4",value:12.06,source:"interscript/interscript-ml docs/RESULTS.md#tha-g2p-small-1.0"},{name:"per_student",value:2.85,source:"interscript/interscript-ml docs/RESULTS.md#tha-g2p-small-1.0"}],parity:{samples:1219,cer_delta:.0803},license:null},{id:"tha-g2p-small-1.0-int4",task:"g2p",scripts:["Thai","IPA"],precision:"int4",filename:"tha-g2p-small-1.0-int4.zip",url:"https://github.com/interscript/interscript-ml/releases/download/tha-g2p-small-1.0/tha-g2p-small-1.0-int4.zip",parts:null,sha256:"e5d12a3d65c6ac39fa08f52c975c99ff7a51c3e7b7aca7fbb461d2de2345e4cb",size:201958073,metrics:[{name:"per_teacher",value:4.43,source:"interscript/interscript-ml docs/RESULTS.md#tha-g2p-small-1.0"},{name:"per_student_beam4",value:12.06,source:"interscript/interscript-ml docs/RESULTS.md#tha-g2p-small-1.0"},{name:"per_student",value:2.85,source:"interscript/interscript-ml docs/RESULTS.md#tha-g2p-small-1.0"}],parity:{samples:600,cer_delta:.0734},license:"BSD-3-Clause"},{id:"heb-diac-small-1.0",task:"diacritization",scripts:["Hebr","Hebr"],precision:"fp32",filename:"heb-diac-small-1.0-fp32.zip",url:"https://github.com/interscript/interscript-ml/releases/download/heb-diac-small-1.0/heb-diac-small-1.0-fp32.zip",parts:null,sha256:"905c53873d5a62bbe6252c6ec0ecef5f37e96e78cb01e8cd99b6b24c4d4d74ad",size:1418663344,metrics:[{name:"der_teacher_greedy",value:24.79,source:"interscript/interscript-ml docs/RESULTS.md#heb-diac-small-1.0"},{name:"der_student_greedy",value:30.37,source:"interscript/interscript-ml docs/RESULTS.md#heb-diac-small-1.0"}],parity:{samples:1864,cer_delta:0},license:null},{id:"fas-g2p-1.0",task:"g2p",scripts:["Arab","Latn"],precision:"fp32",filename:"fas-g2p-1.0-fp32.zip",url:null,parts:[{url:"https://github.com/interscript/interscript-ml/releases/download/fas-g2p-1.0/fas-g2p-1.0-fp32.zip.part-00",sha256:"6c475e53f3c7ef3edcef5a24d2d81f51d13ddf4c417de98440943c9a32b03e55",size:15e8},{url:"https://github.com/interscript/interscript-ml/releases/download/fas-g2p-1.0/fas-g2p-1.0-fp32.zip.part-01",sha256:"c5656c649412f41e201c567e002514d31390b636d4650d9dcb6dfed1973fb3d5",size:1280254270}],sha256:"b53fd69196127efcc596935d24e135b3c897006872c1646c674e70f3c0d9a0e3",size:2780254270,metrics:[{name:"cer",value:1.6,source:"interscript/interscript-ml docs/RESULTS.md#fas-g2p-1.0"},{name:"sb_homograph_ezafe_norm",value:77.34,source:"interscript/interscript-ml docs/RESULTS.md#fas-g2p-1.0"}],parity:{samples:1e3,cer_delta:0},license:"BSD-3-Clause"},{id:"ara-diac-small-1.0",task:"diacritization",scripts:["Arab","Arab"],precision:"fp32",filename:"ara-diac-small-1.0-fp32.zip",url:"https://github.com/interscript/interscript-ml/releases/download/ara-diac-small-1.0/ara-diac-small-1.0-fp32.zip",parts:null,sha256:"8b149beb04294a2e482af876a34ae0fca3e87412606116fae1a376845fd4111a",size:1418126835,metrics:[{name:"der_teacher_greedy",value:1.3205,source:"interscript/interscript-ml docs/RESULTS.md#ara-diac-small-1.0"},{name:"der_student_greedy",value:3.658,source:"interscript/interscript-ml docs/RESULTS.md#ara-diac-small-1.0"},{name:"der_teacher_fullset",value:2.5815,source:"interscript/interscript-ml docs/RESULTS.md#ara-diac-small-1.0"},{name:"der_student_fullset",value:8.259,source:"interscript/interscript-ml docs/RESULTS.md#ara-diac-small-1.0"}],parity:{samples:800,cer_delta:0},license:"BSD-3-Clause"},{id:"heb-diac-1.1",task:"diacritization",scripts:["Hebr","Hebr"],precision:"fp32",filename:"heb.zip",url:null,parts:[{url:"https://github.com/interscript/interscript-ml/releases/download/heb-diac-1.1/heb.zip.part-00",sha256:"8dac0d62e9b0ac4b137412eaf3a542953f11575f12f66f76cb93d3f5d788fc1b",size:15e8},{url:"https://github.com/interscript/interscript-ml/releases/download/heb-diac-1.1/heb.zip.part-01",sha256:"230c5ab731ea5f001f802d60b9e9a328c10b43bc311a19ef1974f114384313ed",size:1280987905}],sha256:"f0022dde8d06e46e8f08cf0b2f7bbb887a05ed686b90f1d5aa82ca3ef690a0b0",size:2780987905,metrics:[{name:"der_greedy",value:16.44,source:"rababa/docs/RESULTS.md#hebrew-diacritization"},{name:"der_beam4",value:16.43,source:"rababa/docs/RESULTS.md#hebrew-diacritization"}],parity:{samples:500,cer_delta:0},license:"BSD-3-Clause"},{id:"ara-diac-1.0",task:"diacritization",scripts:["Arab","Arab"],precision:"fp32",filename:"ara-diac-1.0-fp32.zip",url:null,parts:[{url:"https://github.com/interscript/interscript-ml/releases/download/ara-diac-1.0/ara-diac-1.0-fp32.zip.part-00",sha256:"6282a9291fb45ac7fcc3abe79d33b5913e91f87dcff8b305bf1d57ed98a3ed0b",size:15e8},{url:"https://github.com/interscript/interscript-ml/releases/download/ara-diac-1.0/ara-diac-1.0-fp32.zip.part-01",sha256:"7e7254a89ec75493871f6f61a993315097dad1bb0ba63c4584453c309e8cb906",size:1280311342}],sha256:"9e6d9777fe2474b150450774aaa1c9e8a9051b502b184fde298b91636dcfdac6",size:2780311342,metrics:[{name:"der_total_greedy",value:2.5793,source:"rababa/docs/RESULTS.md#r6-verdict-table-sadeeddiac-25-2026-08-21"},{name:"der_morph_greedy",value:1.5317,source:"rababa/docs/RESULTS.md#r6-verdict-table-sadeeddiac-25-2026-08-21"}],parity:{samples:500,cer_delta:0},license:"BSD-3-Clause"},{id:"ara-diac-small-1.0-int8",task:"diacritization",scripts:["Arab","Arab"],precision:"int8",filename:"ara-diac-small-1.0-int8.zip",url:"https://github.com/interscript/interscript-ml/releases/download/ara-diac-small-1.0/ara-diac-small-1.0-int8.zip",parts:null,sha256:"af247d837bee7e755b5287102cfb715c48dc90c2cf41ec1c41e7238e1a72b678",size:256959713,metrics:[{name:"der_teacher_greedy",value:1.3205,source:"interscript/interscript-ml docs/RESULTS.md#ara-diac-small-1.0"},{name:"der_student_greedy",value:3.658,source:"interscript/interscript-ml docs/RESULTS.md#ara-diac-small-1.0"},{name:"der_teacher_fullset",value:2.5815,source:"interscript/interscript-ml docs/RESULTS.md#ara-diac-small-1.0"},{name:"der_student_fullset",value:8.259,source:"interscript/interscript-ml docs/RESULTS.md#ara-diac-small-1.0"}],parity:{samples:800,cer_delta:0},license:"BSD-3-Clause"}]};var Ye=pn;function be(){return Ye.models}function Qe(t){return Ye.models.find(e=>e.id===t)}var un=Ye.version;var dn={openapi:"3.1.0",info:{title:"Interscript API",version:"1.0.0",description:"Transliteration and neural text processing. Maps run in-edge on the interscript-ts native interpreter (289 systems); neural models (diacritization, grapheme-to-phoneme) run on Interscript's inference service. GraphQL remains available at POST /graphql.",license:{name:"BSD-3-Clause"}},servers:[{url:"https://api.interscript.org"}],tags:[{name:"service"},{name:"maps"},{name:"transliteration"},{name:"models"},{name:"inference"}],paths:{"/":{get:{tags:["service"],summary:"Service index",responses:{200:{$ref:"#/components/responses/Ok"}}}},"/v1/info":{get:{tags:["service"],summary:"Version and capability summary",responses:{200:{$ref:"#/components/responses/Ok"}}}},"/v1/maps":{get:{tags:["maps"],summary:"Every bundled transliteration system code",responses:{200:{$ref:"#/components/responses/Ok"}}}},"/v1/maps/{code}":{get:{tags:["maps"],summary:"One system's compiled map (JSON IR)",parameters:[{name:"code",in:"path",required:!0,schema:{type:"string"}}],responses:{200:{$ref:"#/components/responses/Ok"},404:{$ref:"#/components/responses/NotFound"}}}},"/v1/transliterate":{post:{tags:["transliteration"],summary:"Transliterate text with a system",requestBody:{required:!0,content:{"application/json":{schema:{$ref:"#/components/schemas/TransliterateRequest"},examples:{gek:{value:{system:"ungegn-kor-Kore-Latn-1939",input:"\uD3C9\uC591"}}}}}},responses:{200:{description:"Transliterated output",content:{"application/json":{schema:{$ref:"#/components/schemas/TransliterateResponse"}}}},404:{$ref:"#/components/responses/NotFound"},413:{$ref:"#/components/responses/Error"}}}},"/v1/detect":{post:{tags:["transliteration"],summary:"Rank systems by how well they map input to output",requestBody:{required:!0,content:{"application/json":{schema:{$ref:"#/components/schemas/DetectRequest"}}}},responses:{200:{$ref:"#/components/responses/Ok"}}}},"/v1/models":{get:{tags:["models"],summary:"The neural model index (IMF v1)",responses:{200:{$ref:"#/components/responses/Ok"}}}},"/v1/models/{id}":{get:{tags:["models"],summary:"One model's full entry (metrics, parity, download)",parameters:[{name:"id",in:"path",required:!0,schema:{type:"string"}}],responses:{200:{$ref:"#/components/responses/Ok"},404:{$ref:"#/components/responses/NotFound"}}}},"/v1/infer":{post:{tags:["inference"],summary:"Run a neural model (diacritization or G2P)",description:"Proxy to Interscript's inference service. Only models whose task is diacritization or g2p are served; see GET /v1/models for the catalog.",requestBody:{required:!0,content:{"application/json":{schema:{$ref:"#/components/schemas/InferRequest"},examples:{hebrew:{value:{model:"heb-diac-1.0",input:"\u05E9\u05DC\u05D5\u05DD \u05E2\u05DC\u05D9\u05DB\u05DD"},summary:"Hebrew nikud restoration"},urdu:{value:{model:"urd-g2p-1.0",input:"\u0627\u0631\u062F\u0648"},summary:"Urdu grapheme-to-phoneme"}}}}},responses:{200:{description:"Model output",content:{"application/json":{schema:{$ref:"#/components/schemas/InferResponse"}}}},404:{$ref:"#/components/responses/NotFound"},502:{$ref:"#/components/responses/Error"},503:{$ref:"#/components/responses/Error"}}}}},components:{schemas:{Error:{type:"object",properties:{error:{type:"object",properties:{code:{type:"string"},message:{type:"string"}}}}},TransliterateRequest:{type:"object",required:["system","input"],properties:{system:{type:"string",description:"A system code from GET /v1/maps",examples:["ungegn-kor-Kore-Latn-1939"]},input:{type:"string",maxLength:1e6}}},TransliterateResponse:{type:"object",properties:{system:{type:"string"},input:{type:"string"},output:{type:"string"}}},DetectRequest:{type:"object",required:["input","output"],properties:{input:{type:"string"},output:{type:"string"}}},InferRequest:{type:"object",required:["model","input"],properties:{model:{type:"string",description:"A model id from GET /v1/models",examples:["heb-diac-1.0"]},input:{type:"string",maxLength:4e3}}},InferResponse:{type:"object",properties:{model:{type:"string"},task:{type:"string",enum:["diacritization","g2p"]},input:{type:"string"},output:{type:"string"}}}},responses:{Ok:{description:"Success",content:{"application/json":{schema:{type:"object"}}}},NotFound:{description:"Unknown system or model",content:{"application/json":{schema:{$ref:"#/components/schemas/Error"}}}},Error:{description:"Error",content:{"application/json":{schema:{$ref:"#/components/schemas/Error"}}}}}}};function h(t,e,n){return Response.json({error:{code:e,message:n}},{status:t})}var L=new ur;L.get("/",t=>t.json({name:"Interscript API",version:"v1",openapi:"/openapi.json",endpoints:["GET /v1/info","GET /v1/maps","GET /v1/maps/{code}","POST /v1/transliterate","POST /v1/detect","GET /v1/models","GET /v1/models/{id}","POST /v1/infer","POST /graphql"]}));L.get("/openapi.json",t=>t.json(dn));L.get("/v1/info",t=>t.json({api_version:"1.0.0",engine_version:fe,engine:"interscript-ts@native-interpreter",maps:k().length,models:be().length,models_index_version:un,limits:D}));L.get("/v1/maps",t=>t.json({count:k().length,maps:k()}));L.get("/v1/maps/:code",async t=>{let e=t.env?.ASSETS;if(!e)return h(503,"assets_missing","ASSETS binding not configured");let n=t.req.param("code");if(!k().includes(n))return h(404,"map_not_found",`Couldn't locate ${n}`);let r=await e.fetch(`https://assets.internal/${n}.json`);return r.ok?new Response(r.body,{headers:{"content-type":"application/json; charset=utf-8"}}):h(404,"map_not_found",`Couldn't locate ${n}`)});L.post("/v1/transliterate",async t=>{let e=t.env?.ASSETS;if(!e)return h(503,"assets_missing","ASSETS binding not configured");J(e);let n=await t.req.json().catch(()=>null);if(!n||typeof n!="object")return h(400,"bad_request","body must be JSON {system, input}");let{system:r,input:a}=n;if(typeof r!="string"||typeof a!="string")return h(400,"bad_request","system and input must be strings");try{let s=await he(r,a);return t.json({system:r,input:a,output:s})}catch(s){return s instanceof j?h(413,"input_too_long",s.message):s instanceof $?h(404,"map_not_found",s.message):h(500,"engine_error",String(s))}});L.post("/v1/detect",async t=>{let e=t.env?.ASSETS;if(!e)return h(503,"assets_missing","ASSETS binding not configured");J(e);let n=await t.req.json().catch(()=>null),{input:r,output:a}=n??{};if(typeof r!="string"||typeof a!="string")return h(400,"bad_request","input and output must be strings");let s=await ge(r,a);return t.json({count:s.length,results:s})});L.get("/v1/models",t=>t.json({count:be().length,models:be()}));L.get("/v1/models/:id",t=>{let e=Qe(t.req.param("id"));return e?t.json(e):h(404,"model_not_found",`Couldn't locate ${t.req.param("id")}`)});L.post("/v1/infer",async t=>{let e=await t.req.json().catch(()=>null),{model:n,input:r}=e??{};if(typeof n!="string"||typeof r!="string")return h(400,"bad_request","body must be JSON {model, input}");if(!Qe(n))return h(404,"model_not_found",`Couldn't locate ${n}`);let{ML_ENDPOINT:a,ML_TOKEN:s}=t.env??{};if(!a||!s)return h(503,"inference_unconfigured","ML_ENDPOINT/ML_TOKEN are not set on this deployment");let o=await fetch(`${a}/infer`,{method:"POST",headers:{"content-type":"application/json","x-api-key":s},body:JSON.stringify({model:n,input:r}),signal:AbortSignal.timeout(de)}).catch(()=>null);if(!o||!o.ok){let i=o?await o.text().catch(()=>""):"upstream unreachable";return h(502,"inference_upstream",i.slice(0,500))}let c=await o.json();return t.json({model:n,task:c.task,input:r,output:c.output})});var gr=dr({schema:mr({typeDefs:ye,resolvers:{Query:{info:()=>cn(),systemCodes:()=>ln(),transliterate:(t,e)=>he(e.systemCode,e.input),detect:(t,e)=>ge(e.input,e.output)}}}),graphqlEndpoint:"*",landingPage:!1,maskedErrors:!1}),Y=new fr;Y.use("*",hr({origin:"*",allowMethods:["GET","POST","OPTIONS"]}));Y.route("/",L);Y.all("*",async t=>{let e=t.env;e?.ASSETS&&J(e.ASSETS),sn(e?.ML_ENDPOINT,e?.ML_TOKEN);let n;try{n=t.executionCtx}catch{n=void 0}let r=t.req.raw,a=(r.headers.get("content-type")??"").toLowerCase();if(r.method==="POST"&&!a.includes("application/json")){let s=await r.text(),o=!1;try{JSON.parse(s),o=!0}catch{}s.trim()&&!o&&(r=new Request(r.url,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({query:s})}))}return gr.fetch(r,t.env,n)});var br=Y;export{fe as API_VERSION,D as LIMITS,Y as app,br as default,ye as typeDefs}; +`;import{Hono as fr}from"hono";var L=class extends Error{cause;constructor(t,n){super(t,n),this.name=new.target.name,this.cause=n?.cause}},g=class extends L{systemCode;constructor(t){super(`Map not found: ${t}`),this.systemCode=t}},M=class extends L{},A=class extends L{},C=class extends L{dependency;constructor(t){super(`Map dependency missing: ${t}`),this.dependency=t}};var X=class{strategies;cache=new Map;known=new Map;options;constructor(t,n={}){this.strategies=t,this.options=n}load(t){let n=this.cache.get(t);if(n)return n;let r=this.known.get(t);if(r)return this.cache.set(t,r),r;for(let a of this.strategies){let s=a(t);if(s&&typeof s.then!="function"){let o=s;return this.cache.set(t,o),this.known.set(t,o),this.options.onLoaded?.(t,o),o}}throw new g(t)}async loadAsync(t){let n=this.cache.get(t);if(n)return n;let r=this.known.get(t);if(r)return this.cache.set(t,r),r;for(let a of this.strategies){let s=await a(t);if(s)return this.cache.set(t,s),this.known.set(t,s),this.options.onLoaded?.(t,s),s}throw new g(t)}clear(){this.cache.clear()}loadedMaps(){return Array.from(this.known.keys())}register(t,n){this.known.set(t,n),this.cache.set(t,n)}};var P=class e{current;map;loader;aliasCache=new Map;functions;constructor(t,n,r){this.map=t,this.current=n,this.functions=t.functions,this.loader=r}resolveAlias(t){if(this.aliasCache.has(t))return this.aliasCache.get(t);let n=this.map.aliases.get(t);if(!n&&this.loader)for(let r of this.map.dependencies)try{let s=this.loader.load(r).aliases.get(t);if(s){n=s;break}}catch{}return n&&this.aliasCache.set(t,n),n}withMap(t){return new e(t,this.current,this.loader)}loadDependency(t){if(!this.loader)throw new Error(`Cannot resolve dependency ${t}: no loader configured`);return this.loader.load(t)}};function we(){return{children:new Map,match:null}}function et(e){let t=we();for(let[n,r]of e){if(n.length===0)continue;let a=t;for(let c=0;c0?(n+=c,a+=o):(n+=e[a],a+=1)}return n}function U(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function nt(e){return e.toLowerCase()}function rt(e){return e.toUpperCase()}function at(e,t={}){let n=t.wordSeparator??" ";return n===""?e.charAt(0).toUpperCase()+e.slice(1).toLowerCase():e.split(n).map(r=>r.length===0?r:r.charAt(0).toUpperCase()+r.slice(1).toLowerCase()).join(n)}function st(e,t={}){let n=t.separator??" ";return e.split("").join(n)}function ot(e){return e.normalize("NFC")}function it(e){return e.normalize("NFD")}function ct(e,t){if(t.length===0)return e;let n=t.map((a,s)=>`(?<__r${s}>${a.pattern})`),r=new RegExp(n.join("|"),"gmu");return e.replace(r,(...a)=>{let s=a[a.length-1];for(let o=0;om(a,t).re),r=e.of.length>0?m(e.of[0],t).literal:"";return{re:`(?:${n.join("|")})`,literal:r}}case"any_char_class":{if(e.range){let[n,r]=e.range;return{re:`[${U(n)}-${U(r)}]`,literal:n??""}}return e.chars&&e.chars.length>0?{re:`[${e.chars.map(r=>U(r)).join("")}]`,literal:e.chars[0]}:{re:"[^]",literal:""}}case"group":{let n=e.items.map(s=>m(s,t)),r=n.map(s=>s.re).join(""),a=n.map(s=>s.literal).join("");return{re:`(?:${r})`,literal:a}}case"repeat":{let n=m(e.item,t).re,{min:r,max:a}=e,s=a===null?1/0:a,o=s===1/0?r===0?"*":"+":`{${r},${s}}`;return{re:`(?:${n})${o}`,literal:""}}case"stage_ref":return{re:"",literal:""}}}function F(e,t){switch(e.kind){case"string":return e.value;case"alias":{let n=Z[e.name];if(n)return n.literal===""?null:n.literal;let r=t.resolveAlias(e.name);return r?F(r,t):null}case"capture_group":case"capture_ref":case"repeat":case"stage_ref":return null;case"any_char_class":return e.chars&&e.chars.length>0?e.chars[0]:e.range?e.range[0]:null;case"any":return e.of.length===0?null:F(e.of[0],t);case"group":{let n="";for(let r of e.items){let a=F(r,t);if(a===null)return null;n+=a}return n}}}function I(e,t){switch(e.kind){case"string":return[e.value];case"alias":{if(Z[e.name])return null;let r=t.resolveAlias(e.name);return r?I(r,t):null}case"any_char_class":{if(e.chars)return[...e.chars];if(e.range){let[n,r]=e.range,a=n.codePointAt(0),s=r.codePointAt(0),o=[];for(let c=a;c<=s;c++)o.push(String.fromCodePoint(c));return o}return null}case"any":{let n=[];for(let r of e.of){let a=I(r,t);if(a===null)return null;n.push(...a)}return n}case"group":{let n=[""];for(let r of e.items){let a=I(r,t);if(a===null)return null;let s=[];for(let o of n)for(let c of a)s.push(o+c);n=s}return n}default:return null}}function w(e,t){switch(e.kind){case"string":return e.value.length;case"capture_group":return w(e.data,t);case"capture_ref":return 1;case"alias":{if(e.name==="none")return 0;if(Z[e.name])return 1;let n=t.resolveAlias(e.name);return n?w(n,t):1}case"any":return e.of.reduce((n,r)=>Math.max(n,w(r,t)),0);case"any_char_class":return 1;case"group":return e.items.reduce((n,r)=>n+w(r,t),0);case"repeat":return w(e.item,t);case"stage_ref":return 1}}var Z=Object.freeze({any_character:{re:".",literal:""},none:{re:"",literal:""},space:{re:" ",literal:" "},whitespace:{re:"\\s+",literal:" "},boundary:{re:"(?:(?at(e,t??{}),separate:(e,t)=>st(e,t??{}),compose:ot,decompose:it};function lt(e,t){let n=e.functions.get(t)?.impl;if(n)return n;let r=gn[t];if(r)return r}var bn={sub:(e,t)=>yn(e,t),run:(e,t)=>{let n=e.docName?t.loadDependency(e.docName):t.map,r=n.stages.find(s=>s.name===e.stage);if(!r)throw new A(`Stage not found: ${e.stage}`);let a=t.withMap(n);for(let s of r.rules)T(s,a);t.current=a.current},funcall:(e,t)=>{let n=lt(t,e.name);if(!n)throw new A(`Unknown function: ${e.name}`);t.current=n(t.current,e.kwargs??{})},parallel:(e,t)=>{let n=[],r=[];for(let o of e.rules)o.kind==="sub"&&o.from?n.push(o):r.push(o);let a=o=>!o.before&&!o.after&&!o.notBefore&&!o.notAfter&&I(o.from,t)!==null;if(n.some(o=>!a(o))){let c=n.map((i,l)=>({rule:i,idx:l,len:w(i.from,t)+(i.before?w(i.before,t):0)+(i.after?w(i.after,t):0)+(i.notBefore?w(i.notBefore,t):0)+(i.notAfter?w(i.notAfter,t):0)+(i.priority??0)})).sort((i,l)=>l.len-i.len||i.idx-l.idx).map(({rule:i})=>{let l=m(i.from,t),p=i.before?m(i.before,t).re:"",u=i.after?m(i.after,t).re:"",S=i.notBefore?m(i.notBefore,t).re:"",y=i.notAfter?m(i.notAfter,t).re:"",x=[p?`(?<=${p})`:"",S?`(?pt(v,f,Y):v}});t.current=ct(t.current,c)}else{let o=[];for(let c of n){if(c.to&&c.to.kind==="funcall_inline")continue;let i=c.to?F(c.to,t):"";if(i===null)continue;let l=I(c.from,t);if(l!==null)for(let p of l)o.push([p,i])}o.length>0&&(t.current=tt(t.current,et(o)))}for(let o of r)T(o,t)},sequential:(e,t)=>{for(let n of e.rules)T(n,t)}};function yn(e,t){if(!e.from)throw new A("Sub rule missing 'from'");let n=m(e.from,t),r=e.before?m(e.before,t).re:"",a=e.after?m(e.after,t).re:"",s=e.notBefore?m(e.notBefore,t).re:"",o=e.notAfter?m(e.notAfter,t).re:"",c=[];r&&c.push(`(?<=${r})`),s&&c.push(`(?{let p=l;return(u,...S)=>pt(p,u,S)})():l)}function pt(e,t,n){return e.replace(/\$(\d+)/g,(r,a)=>{let s=parseInt(a,10);return n[s-1]??t})}function dt(e,t){if(!e)return"";if(e.kind==="funcall_inline"){let r=lt(t,e.name);if(!r)throw new A(`Unknown inline function: ${e.name}`);return a=>r(a)}return m(e,t).literal}function T(e,t){let n=bn[e.kind];n(e,t)}var Ke=new Set(["rababa","secryst"]);function Wt(e){for(let t of e){if(t.kind==="funcall"&&Ke.has(t.name))return!0;if(t.kind==="parallel"||t.kind==="sequential"){for(let n of t.rules)if(n.kind==="funcall"&&Ke.has(n.name))return!0}}return!1}function W(e,t,n,r){let a=e.stages.find(o=>o.name===t);if(!a)return n;if(Wt(a.rules))throw new Error(`Stage "${t}" contains ML function calls (rababa/secryst). Use transliterateAsync() instead of transliterate().`);let s=new P(e,n,r);for(let o of a.rules)T(o,s);return s.current}async function Qt(e,t,n,r){let a=e.stages.find(o=>o.name===t);if(!a)return n;if(!Wt(a.rules))return W(e,t,n,r);let s=new P(e,n,r);for(let o of a.rules)await er(o,s);return s.current}async function er(e,t){if(e.kind==="funcall"){await tr(e,t);return}T(e,t)}async function tr(e,t){if(e.name==="rababa"){let{rababa:n}=await Promise.resolve().then(()=>(xt(),_t));t.current=await n(t.current,e.kwargs);return}if(Ke.has(e.name)){let{loadModel:n}=await Promise.resolve().then(()=>(Kt(),Vt)),r=e.kwargs?.config??e.kwargs?.model??"default",a=await n({kind:e.name,id:r});t.current=await a.transform(t.current);return}T({kind:"funcall",name:e.name,kwargs:e.kwargs},t)}function nr(e,t){if(e===t)return 0;if(e.length===0)return t.length;if(t.length===0)return e.length;let n=new Array(t.length+1),r=new Array(t.length+1);for(let a=0;a<=t.length;a++)n[a]=a;for(let a=1;a<=e.length;a++){r[0]=a;for(let s=1;s<=t.length;s++){let o=e[a-1]===t[s-1]?0:1;r[s]=Math.min(n[s]+1,r[s-1]+1,n[s-1]+o)}[n,r]=[r,n]}return n[t.length]}function rr(e){let t=e.replace(/[.+?^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*");return new RegExp(`^${t}$`)}function Jt(e,t,n,r={},a){let s=[],o=r.mapPattern?rr(r.mapPattern):null,c=a??n.loadedMaps();for(let i of c){if(o&&!o.test(i))continue;let l;try{let p=n.load(i);l=W(p,"main",e,n)}catch(p){if(p instanceof L)continue;throw p}s.push({mapName:i,distance:nr(l,t)})}return s.sort((i,l)=>i.distance-l.distance)}function We(e){let t={schemaVersion:e.schemaVersion,systemCode:e.systemCode,dependencies:e.dependencies,stages:e.stages,aliases:new Map(Object.entries(e.aliases)),functions:new Map};return e.metadata&&(t.metadata=e.metadata),t}var ar="main",de=class{loader;defaultStage;constructor(t={}){this.loader=new X(t.strategies??[]),this.defaultStage=t.defaultStage??ar}loadMap(t){let n=this.loader.load(t);for(let r of n.dependencies)try{this.loader.load(r)}catch(a){throw a instanceof g?new C(r):a}return n}async loadMapAsync(t){let n=await this.loader.loadAsync(t),r=new Set,a=[...n.dependencies];for(;a.length>0;){let s=a.shift();if(!r.has(s)){r.add(s);try{let o=await this.loader.loadAsync(s);for(let c of o.dependencies)r.has(c)||a.push(c)}catch(o){throw o instanceof g?new C(s):o}}}return n}transliterate(t,n,r){try{let a=this.loadMap(t),s=r??this.defaultStage;return W(a,s,n,this.loader)}catch(a){throw a instanceof L?a:new M(`Transliteration failed for ${t}: ${a.message}`,{cause:a})}}async transliterateAsync(t,n,r){try{let a=await this.loadMapAsync(t),s=r??this.defaultStage;return await Qt(a,s,n,this.loader)}catch(a){throw a instanceof L?a:new M(`Transliteration failed for ${t}: ${a.message}`,{cause:a})}}loadedMaps(){return this.loader.loadedMaps()}getLoader(){return this.loader}detect(t,n,r={},a){return Jt(t,n,this.loader,r,a)}},pe;function Yt(e){pe=new de(e)}function sr(){return pe||(pe=new de),pe}function Qe(e,t,n){return sr().transliterateAsync(e,t,n)}var Xt=["acadsin-zho-Hani-Latn-2002","alalc-amh-Ethi-Latn-1997","alalc-amh-Ethi-Latn-2011","alalc-ara-Arab-Latn-1997","alalc-asm-Deva-Latn-1997","alalc-asm-Deva-Latn-2012","alalc-aze-Arab-Latn-1997","alalc-aze-Cyrl-Latn-1997","alalc-bel-Cyrl-Latn-1997","alalc-ben-Beng-Latn-1997","alalc-ben-Beng-Latn-2017","alalc-bul-Cyrl-Latn-1997","alalc-div-Thaa-Latn-1997","alalc-div-Thaa-Latn-2012","alalc-ell-Grek-Latn-1997","alalc-ell-Grek-Latn-2010","alalc-fas-Arab-Latn-1997","alalc-guj-Gujr-Latn-1997","alalc-guj-Gujr-Latn-2011","alalc-hin-Deva-Latn-1997","alalc-hin-Deva-Latn-2011","alalc-kan-Kana-Latn-1997","alalc-kan-Kana-Latn-2011","alalc-kat-Geok-Latn-1997","alalc-kat-Geok-Latn-2011","alalc-kat-Geor-Latn-1997","alalc-kat-Geor-Latn-2011","alalc-kor-Hang-Latn-1997","alalc-mal-Mlym-Latn-1997","alalc-mal-Mlym-Latn-2012","alalc-mar-Deva-Latn-1997","alalc-mar-Deva-Latn-2011","alalc-mkd-Cyrl-Latn-1997","alalc-mkd-Cyrl-Latn-2013","alalc-mon-Cyrl-Latn-1997","alalc-ori-Orya-Latn-1997","alalc-ori-Orya-Latn-2011","alalc-pan-Guru-Latn-1997","alalc-pan-Guru-Latn-2011","alalc-pli-Deva-Latn-2012","alalc-pra-Deva-Latn-2012","alalc-rus-Cyrl-Latn-1997","alalc-rus-Cyrl-Latn-2012","alalc-san-Deva-Latn-2012","alalc-sin-Sinh-Latn-1997","alalc-sin-Sinh-Latn-2011","alalc-srp-Cyrl-Latn-1997","alalc-srp-Cyrl-Latn-2013","alalc-tam-Taml-Latn-1997","alalc-tam-Taml-Latn-2011","alalc-tel-Telu-Latn-1997","alalc-tel-Telu-Latn-2011","alalc-tir-Ethi-Latn-1997","alalc-tir-Ethi-Latn-2011","alalc-ukr-Cyrl-Latn-1997","alalc-ukr-Cyrl-Latn-2011","apcbg-bul-Cyrl-Latn-1995","az-aze-Cyrl-Latn-1939","az-aze-Cyrl-Latn-1958","bas-rus-Cyrl-Latn-2017-bss","bas-rus-Cyrl-Latn-2017-oss","bgn-jpn-Hrkt-Latn-1962","bgn-kor-Hang-Latn-1943","bgn-kor-Kore-Latn-1943","bgna-bul-Cyrl-Latn-2006","bgna-bul-Cyrl-Latn-2009","bgnpcgn-amh-Ethi-Latn-1967","bgnpcgn-ara-Arab-Latn-1956","bgnpcgn-arm-Armn-Latn-1981","bgnpcgn-aze-Cyrl-Latn-1993","bgnpcgn-bak-Cyrl-Latn-2007","bgnpcgn-bal-Arab-Latn-2008","bgnpcgn-bel-Cyrl-Latn-1979","bgnpcgn-bul-Cyrl-Latn-1952","bgnpcgn-bul-Cyrl-Latn-2013","bgnpcgn-che-Cyrl-Latn-2008","bgnpcgn-deu-Latn-Latn-2000","bgnpcgn-div-Thaa-Latn-1972","bgnpcgn-div-Thaa-Latn-1988","bgnpcgn-ell-Grek-Latn-1962","bgnpcgn-ell-Grek-Latn-1996","bgnpcgn-fao-Latn-Latn-1964","bgnpcgn-fao-Latn-Latn-1968","bgnpcgn-fas-Arab-Latn-1956","bgnpcgn-isl-Latn-Latn-1964","bgnpcgn-isl-Latn-Latn-1968","bgnpcgn-jpn-Hrkt-Latn-1976","bgnpcgn-kat-Geor-Latn-1981","bgnpcgn-kat-Geor-Latn-2009","bgnpcgn-kaz-Cyrl-Latn-1979","bgnpcgn-kir-Cyrl-Latn-1979","bgnpcgn-kor-Hang-Latn-kn-1945","bgnpcgn-kor-Hang-Latn-rok-2011","bgnpcgn-kor-Kore-Latn-rok-2011","bgnpcgn-kur-Arab-Latn-2007","bgnpcgn-mkd-Cyrl-Latn-1981","bgnpcgn-mkd-Cyrl-Latn-2013","bgnpcgn-mon-Cyrl-Latn-1964","bgnpcgn-nep-Deva-Latn-2011","bgnpcgn-per-Arab-Latn-1958","bgnpcgn-prs-Arab-Latn-2007","bgnpcgn-prs-Arab-Latn-yaghoubi","bgnpcgn-pus-Arab-Latn-1968","bgnpcgn-ron-Cyrl-Latn-2002","bgnpcgn-rue-Cyrl-Latn-2016","bgnpcgn-rus-Cyrl-Latn-1947","bgnpcgn-sme-Latn-Latn-1984","bgnpcgn-srp-Cyrl-Latn-1962","bgnpcgn-srp-Cyrl-Latn-2005","bgnpcgn-tat-Cyrl-Latn-2007","bgnpcgn-tgk-Cyrl-Latn-1994","bgnpcgn-tir-Ethi-Latn-2007","bgnpcgn-ukr-Cyrl-Latn-1965","bgnpcgn-ukr-Cyrl-Latn-2019","bgnpcgn-urd-Arab-Latn-2007","bgnpcgn-uzb-Cyrl-Latn-1979","bgnpcgn-uzb-Cyrl-Latn-2000","bgnpcgn-zho-Hans-Latn-1979","bis-asm-Beng-Latn-13194-1991","bis-ben-Beng-Latn-13194-1991","bis-dev-Deva-Latn-13194-1991","bis-guj-Gujr-Latn-13194-1991","bis-kan-Kana-Latn-13194-1991","bis-mlm-Mlym-Latn-13194-1991","bis-ori-Orya-Latn-13194-1991","bis-pnj-Guru-Latn-13194-1991","bis-tel-Telu-Latn-13194-1991","bis-tml-Taml-Latn-13194-1991","by-bel-Cyrl-Latn-1998","by-bel-Cyrl-Latn-2007","din-grc-Grek-Latn-31634-2011-t1","din-hin-Deva-Latn-33904-2018","din-kat-Geor-Latn-32707-2010","din-mar-Deva-Latn-33904-2018","din-nep-Deva-Latn-33904-2018","din-pli-Deva-Latn-33904-2018","din-pra-Deva-Latn-33904-2018","din-san-Deva-Latn-33904-2018","din-tam-Taml-Latn-33903-2016","dos-nep-Deva-Latn-1997","elot-ell-Grek-Latn-743-1982-tl","elot-ell-Grek-Latn-743-1982-ts","elot-ell-Grek-Latn-743-2001-tl","elot-ell-Grek-Latn-743-2001-ts","ggg-kat-Geor-Latn-2002","gki-bel-Cyrl-Latn-1992","gki-bel-Cyrl-Latn-2000","gost-rus-Cyrl-Latn-16876-71-1983","gost-rus-Cyrl-Latn-7.79-2000-2002","hk-yue-Hani-Latn-1888","icao-bel-Cyrl-Latn-9303","icao-bul-Cyrl-Latn-9303","icao-fas-Arab-Latn-9303","icao-heb-Hebr-Latn-9303","icao-mkd-Cyrl-Latn-9303","icao-rus-Cyrl-Latn-9303","icao-srp-Cyrl-Latn-9303","icao-ukr-Cyrl-Latn-9303","iso-ara-Arab-Latn-233-1984","iso-ara-Arab-Latn-233-2-1993","iso-asm-Beng-Latn-15919-2001","iso-ben-Beng-Latn-15919-2001","iso-ell-Grek-Latn-843-1997-t1","iso-ell-Grek-Latn-843-1997-t2","iso-guj-Gujr-Latn-15919-2001","iso-hin-Deva-Latn-15919-2001","iso-inc-Deva-Latn-15919-2001","iso-jpn-Hrkt-Latn-3602-1989","iso-kan-Kana-Latn-15919-2001","iso-kat-Geor-Latn-9984-1996","iso-kor-Hang-Latn-1996-method1","iso-kor-Hang-Latn-1996-method2","iso-mal-Mlym-Latn-15919-2001","iso-mar-Deva-Latn-15919-2001","iso-nep-Deva-Latn-15919-2001","iso-ori-Orya-Latn-15919-2001","iso-pan-Guru-Latn-15919-2001","iso-pli-Beng-Latn-15919-2001","iso-pli-Deva-Latn-15919-2001","iso-pli-Sinh-Latn-15919-2001","iso-pli-Thai-Latn-15919-2001","iso-pra-Deva-Latn-15919-2001","iso-prs-Arab-Latn-233-3-1999","iso-rus-Cyrl-Latn-9-1995","iso-san-Deva-Latn-15919-2001","iso-tam-Taml-Latn-15919-2001","iso-tel-Telu-Latn-15919-2001","iso-tha-Thai-Latn-11940-1998","kp-kor-Hang-Latn-2002","lshk-yue-Hani-Latn-jyutping-1993","masm-mon-Cyrl-Latn-5217-2012","masm-mon-Latn-Cyrl-5217-2012","mext-jpn-Hrkt-Latn-1954","moct-kor-Hang-Latn-2000","mofa-jpn-Hrkt-Latn-1989","mv-div-Thaa-Latn-1987","mvd-bel-Cyrl-Latn-2008","mvd-bel-Cyrl-Latn-2010","mvd-rus-Cyrl-Latn-2008","mvd-rus-Cyrl-Latn-2010","odni-ara-Arab-Latn-2004","odni-ara-Arab-Latn-2015","odni-aze-Cyrl-Latn-2015","odni-bel-Cyrl-Latn-2015","odni-bul-Cyrl-Latn-2005","odni-bul-Cyrl-Latn-2015","odni-che-Cyrl-Latn-2015","odni-fas-Arab-Latn-2004","odni-fas-Arab-Latn-2015","odni-hin-Deva-Latn-2004","odni-hin-Deva-Latn-2015","odni-kat-Geor-Latn-2015","odni-kaz-Cyrl-Latn-2015","odni-kir-Cyrl-Latn-2015","odni-kor-Hang-Latn-2015","odni-mkd-Cyrl-Latn-2005","odni-mkd-Cyrl-Latn-2015","odni-prs-Arab-Latn-2004","odni-prs-Arab-Latn-2015","odni-pus-Arab-Latn-2011","odni-rus-Cyrl-Latn-2015","odni-srp-Cyrl-Latn-2005","odni-srp-Cyrl-Latn-2015","odni-tat-Cyrl-Latn-2015","odni-tgk-Cyrl-Latn-2015","odni-tuk-Cyrl-Latn-2015","odni-uig-Cyrl-Latn-2015","odni-ukr-Cyrl-Latn-2015","odni-urd-Arab-Latn-2015","odni-uzb-Cyrl-Latn-2015","posix","sac-zho-Hans-Latn-1979","sasm-mon-Mong-Latn-general-1978","sasm-mon-Mong-Latn-phonetic-1978","ses-ara-Arab-Latn-1930","stategeocadastre-ukr-Cyrl-Latn-1993","ua-ukr-Cyrl-Latn-1996","ua-ukr-Cyrl-Latn-2007","ua-ukr-Cyrl-Latn-2010","un-amh-Ethi-Latn-2016","un-ara-Arab-Latn-1971","un-ara-Arab-Latn-1972","un-ara-Arab-Latn-2017","un-asm-Beng-Latn-1972","un-bel-Cyrl-Latn-2007","un-ben-Beng-Latn-2016","un-bul-Cyrl-Latn-1977","un-ell-Grek-Latn-1987-phonetic","un-ell-Grek-Latn-1987-tl","un-ell-Grek-Latn-1987-ts","un-guj-Gujr-Latn-1972","un-hin-Deva-Latn-2016","un-kan-Kana-Latn-2016","un-mal-Mlym-Latn-1972","un-mar-Deva-Latn-2016","un-mkd-Cyrl-Latn-1977","un-mon-Mong-Latn-general-2013","un-mon-Mong-Latn-phonetic-2013","un-nep-Deva-Latn-1972","un-nep-Deva-Latn-2013","un-ori-Orya-Latn-1972","un-pan-Guru-Latn-1972","un-prs-Arab-Latn-1967","un-rus-Cyrl-Latn-1987","un-sin-Sinh-Latn-1972","un-srp-Cyrl-Latn-1997","un-tam-Taml-Latn-1972","un-tel-Telu-Latn-1972","un-ukr-Cyrl-Latn-1998","un-ukr-Cyrl-Latn-2012","un-urd-Arab-Latn-1972","unicode","var-Cyrl","var-amh-Ethi-Latn-eae-2003","var-ara-Arab-Arab-rababa","var-gez-Ethi-Latn-eae-2003","var-hin-Deva-Latn-hunterian-1872","var-jpn-Hrkt-Latn-hepburn-1886","var-jpn-Hrkt-Latn-hepburn-1954","var-kor","var-kor-Hang-Hang-jamo","var-kor-Hang-Latn-mr-1939","var-kor-Kore-Hang-2013","var-kor-Kore-Latn-mr-1939","var-mar-Deva-Latn-hunterian-1872","var-mon-Mong-Latn-1930","var-mon-Mong-Latn-lessing","var-mon-Mong-Latn-vpmc","var-pra-Deva-Latn-iast-1912","var-san-Deva-Latn-iast-1912","var-zho-Hani-Latn-wd-1979"];var or=new Set(["unicode","posix","var-Cyrl","var-kor"]),ir=new Set(["var-ara-Arab-Arab-rababa"]),en=Xt.filter(e=>!or.has(e)),cr=en.filter(e=>!ir.has(e)),Zt=new Map;function _(){return en}function tn(){return cr}async function nn(e,t){let n=Zt.get(t);if(n)return n;let r=await e.fetch(new Request(`https://assets.internal/${t}.json`));if(!r.ok)throw new g(t);let a=await r.json(),s=We(a);return Zt.set(t,s),s}var rn;function an(e){if(rn===e)return;Yt({strategies:[n=>nn(e,n)]}),rn=e}async function sn(e,t,n){return an(e),Qe(t,n)}function lr(e,t){if(e===t)return 0;if(!e.length)return t.length;if(!t.length)return e.length;let n=Array.from({length:t.length+1},(r,a)=>a);for(let r=1;r<=e.length;r++){let a=[r];for(let s=1;s<=t.length;s++)a[s]=Math.min(n[s]+1,a[s-1]+1,n[s-1]+(e[r-1]===t[s-1]?0:1));n=a}return n[t.length]}async function on(e,t,n){an(e);let r=[];for(let a of tn())try{let s=await Qe(a,t);r.push({mapName:a,distance:lr(s,n)})}catch{continue}return r.sort((a,s)=>a.distance-s.distance)}var j=class extends Error{constructor(n){super(`Input is too long (max ${n} characters)`);this.max=n;this.name="InputTooLongError"}max},$=class extends Error{constructor(n){super(`Couldn't locate ${n}`);this.systemCode=n;this.name="MapNotFoundError"}systemCode};var D={input_max_size:1e6},ue=12e4;var fe="3.0.0-cloudflare.1",Je;function Q(e){Je=e}var me;function cn(e,t){me=e&&t?{endpoint:e,token:t}:void 0}var pr={"var-ara-Arab-Arab-rababa":"ara-diac-1.0"};async function dr(e,t){if(!me)throw new Error("ML inference unavailable \u2014 ML_ENDPOINT/ML_TOKEN not set");let n=await fetch(`${me.endpoint}/infer`,{method:"POST",headers:{"content-type":"application/json","x-api-key":me.token},body:JSON.stringify({model:e,input:t}),signal:AbortSignal.timeout(ue)}).catch(()=>null);if(!n||!n.ok)throw new Error("ML inference upstream failed");let r=await n.json().catch(()=>null);if(!r||typeof r.output!="string")throw new Error("ML inference returned no output");return r.output}function ln(){if(!Je)throw new Error("ASSETS binding missing \u2014 see README deployment notes");return Je}async function pn(){return JSON.stringify({version:fe,engine:"interscript-ts@native-interpreter"})}function dn(){return[..._()]}async function he(e,t){if(t.length>D.input_max_size)throw new j(D.input_max_size);let n=pr[e];if(n)return dr(n,t);try{return await sn(ln(),e,t)}catch(r){throw r instanceof g?new $(e):r}}async function ge(e,t){return on(ln(),e,t)}var un={version:1,models:[{id:"khm-latn-1.0",task:"translit",scripts:["Khmr","Latn"],precision:"fp32",filename:"khm-latn-1.0-fp32.zip",url:"https://github.com/interscript/interscript-ml/releases/download/khm-latn-1.0/khm-latn-1.0-fp32.zip",parts:null,sha256:"55993d473a2ed9489058779cad7e115db05e4020085b71616468cfae4f2f65cb",size:1418009977,metrics:[{name:"cer",value:27.42,source:"secryst/docs/RESULTS.md#khmer-transliteration-2026-08-14"},{name:"em",value:59.66,source:"secryst/docs/RESULTS.md#khmer-transliteration-2026-08-14"}],parity:{samples:895,cer_delta:0},license:"BSD-3-Clause"},{id:"urd-g2p-1.0",task:"g2p",scripts:["Arab","IPA"],precision:"fp32",filename:"urd-g2p-1.0-fp32.zip",url:"https://github.com/interscript/interscript-ml/releases/download/urd-g2p-1.0/urd-g2p-1.0-fp32.zip",parts:null,sha256:"9f0a248c7116aa7f6b9ac125fb9684a3556f3b8ce8b64567c05a5e7e7a018ebf",size:1418039605,metrics:[{name:"cer",value:14.77,source:"rababa-urdu/docs/RESULTS.md#g2p-urdu-text--ipa"},{name:"em",value:33.6,source:"rababa-urdu/docs/RESULTS.md#g2p-urdu-text--ipa"}],parity:{samples:12699,cer_delta:0},license:"BSD-3-Clause"},{id:"urd-diac-1.0",task:"diacritization",scripts:["Arab","Arab"],precision:"fp32",filename:"urd-diac-1.0-fp32.zip",url:"https://github.com/interscript/interscript-ml/releases/download/urd-diac-1.0/urd-diac-1.0-fp32.zip",parts:null,sha256:"c299ea44a4da4851a52283f8e42d2fb6f8c7a9c443ba7eb0270f97372e10b8ea",size:1417851421,metrics:[{name:"cer",value:3.74,source:"rababa-urdu/docs/RESULTS.md#diacritization-urdu-text--text--haraqat"}],parity:{samples:11940,cer_delta:0},license:"BSD-3-Clause"},{id:"heb-diac-1.0",task:"diacritization",scripts:["Hebr","Hebr"],precision:"fp32",filename:"heb-diac-1.0-fp32.zip",url:null,parts:[{url:"https://github.com/interscript/interscript-ml/releases/download/heb-diac-1.0/heb-diac-1.0-fp32.zip.part-00",sha256:"5497f70cc3c96829e65f1eb0cc401c2d1ffeb4fa909acd4def824c2e019cbc37",size:15e8},{url:"https://github.com/interscript/interscript-ml/releases/download/heb-diac-1.0/heb-diac-1.0-fp32.zip.part-01",sha256:"a7d2011ab4f9326a86e234cc49cb50daf82949e51efbf03a21d5796c46465e9d",size:1281139753}],sha256:"b32fa239e0c56708b6004942de4b9e6e9f265e7cc3828f41d560e96386e20dd8",size:2781139753,metrics:[{name:"der_greedy",value:29,source:"rababa/docs/RESULTS.md#hebrew-diacritization"},{name:"der_beam4",value:17.46,source:"rababa/docs/RESULTS.md#hebrew-diacritization"}],parity:{samples:600,cer_delta:0},license:"BSD-3-Clause"},{id:"tha-g2p-base-1.0",task:"g2p",scripts:["Thai","IPA"],precision:"fp32",filename:"tha-g2p-base-1.0-fp32.zip",url:null,parts:[{url:"https://github.com/interscript/interscript-ml/releases/download/tha-g2p-base-1.0/tha-g2p-base-1.0-fp32.zip.part-00",sha256:"c4525414e5dec91a54d055ca9f1acd51c198f81fbfc55977aa82c1fb038d58d7",size:15e8},{url:"https://github.com/interscript/interscript-ml/releases/download/tha-g2p-base-1.0/tha-g2p-base-1.0-fp32.zip.part-01",sha256:"f5d11fbd75f92e8b5471add867418e2dd4f49a5e258b9ded2f3b5ffa630abe24",size:1281174343}],sha256:"f341a5868867a9847d3f897d1fcc4d1d63b9a59b8913871bcf4ecab48f4fa895",size:2781174343,metrics:[{name:"per_teacher",value:1.25,source:"interscript/interscript-ml docs/RESULTS.md#tha-g2p-base-1.0"},{name:"per_student",value:3.53,source:"interscript/interscript-ml docs/RESULTS.md#tha-g2p-base-1.0"}],parity:{samples:1219,cer_delta:0},license:"BSD-3-Clause"},{id:"tha-g2p-small-1.0",task:"g2p",scripts:["Thai","IPA"],precision:"int8",filename:"tha-g2p-small-1.0-int8.zip",url:"https://github.com/interscript/interscript-ml/releases/download/tha-g2p-small-1.0/tha-g2p-small-1.0-int8.zip",parts:null,sha256:"f2cfa93a42d98aabf08fdc82dfc6bd1574e21993f36558aa581fbe29e0588a94",size:257468517,metrics:[{name:"per_teacher",value:4.43,source:"interscript/interscript-ml docs/RESULTS.md#tha-g2p-small-1.0"},{name:"per_student_beam4",value:12.06,source:"interscript/interscript-ml docs/RESULTS.md#tha-g2p-small-1.0"},{name:"per_student",value:2.85,source:"interscript/interscript-ml docs/RESULTS.md#tha-g2p-small-1.0"}],parity:{samples:1219,cer_delta:.0803},license:null},{id:"tha-g2p-small-1.0-int4",task:"g2p",scripts:["Thai","IPA"],precision:"int4",filename:"tha-g2p-small-1.0-int4.zip",url:"https://github.com/interscript/interscript-ml/releases/download/tha-g2p-small-1.0/tha-g2p-small-1.0-int4.zip",parts:null,sha256:"e5d12a3d65c6ac39fa08f52c975c99ff7a51c3e7b7aca7fbb461d2de2345e4cb",size:201958073,metrics:[{name:"per_teacher",value:4.43,source:"interscript/interscript-ml docs/RESULTS.md#tha-g2p-small-1.0"},{name:"per_student_beam4",value:12.06,source:"interscript/interscript-ml docs/RESULTS.md#tha-g2p-small-1.0"},{name:"per_student",value:2.85,source:"interscript/interscript-ml docs/RESULTS.md#tha-g2p-small-1.0"}],parity:{samples:600,cer_delta:.0734},license:"BSD-3-Clause"},{id:"heb-diac-small-1.0",task:"diacritization",scripts:["Hebr","Hebr"],precision:"fp32",filename:"heb-diac-small-1.0-fp32.zip",url:"https://github.com/interscript/interscript-ml/releases/download/heb-diac-small-1.0/heb-diac-small-1.0-fp32.zip",parts:null,sha256:"905c53873d5a62bbe6252c6ec0ecef5f37e96e78cb01e8cd99b6b24c4d4d74ad",size:1418663344,metrics:[{name:"der_teacher_greedy",value:24.79,source:"interscript/interscript-ml docs/RESULTS.md#heb-diac-small-1.0"},{name:"der_student_greedy",value:30.37,source:"interscript/interscript-ml docs/RESULTS.md#heb-diac-small-1.0"}],parity:{samples:1864,cer_delta:0},license:null},{id:"fas-g2p-1.0",task:"g2p",scripts:["Arab","Latn"],precision:"fp32",filename:"fas-g2p-1.0-fp32.zip",url:null,parts:[{url:"https://github.com/interscript/interscript-ml/releases/download/fas-g2p-1.0/fas-g2p-1.0-fp32.zip.part-00",sha256:"6c475e53f3c7ef3edcef5a24d2d81f51d13ddf4c417de98440943c9a32b03e55",size:15e8},{url:"https://github.com/interscript/interscript-ml/releases/download/fas-g2p-1.0/fas-g2p-1.0-fp32.zip.part-01",sha256:"c5656c649412f41e201c567e002514d31390b636d4650d9dcb6dfed1973fb3d5",size:1280254270}],sha256:"b53fd69196127efcc596935d24e135b3c897006872c1646c674e70f3c0d9a0e3",size:2780254270,metrics:[{name:"cer",value:1.6,source:"interscript/interscript-ml docs/RESULTS.md#fas-g2p-1.0"},{name:"sb_homograph_ezafe_norm",value:77.34,source:"interscript/interscript-ml docs/RESULTS.md#fas-g2p-1.0"}],parity:{samples:1e3,cer_delta:0},license:"BSD-3-Clause"},{id:"ara-diac-small-1.0",task:"diacritization",scripts:["Arab","Arab"],precision:"fp32",filename:"ara-diac-small-1.0-fp32.zip",url:"https://github.com/interscript/interscript-ml/releases/download/ara-diac-small-1.0/ara-diac-small-1.0-fp32.zip",parts:null,sha256:"8b149beb04294a2e482af876a34ae0fca3e87412606116fae1a376845fd4111a",size:1418126835,metrics:[{name:"der_teacher_greedy",value:1.3205,source:"interscript/interscript-ml docs/RESULTS.md#ara-diac-small-1.0"},{name:"der_student_greedy",value:3.658,source:"interscript/interscript-ml docs/RESULTS.md#ara-diac-small-1.0"},{name:"der_teacher_fullset",value:2.5815,source:"interscript/interscript-ml docs/RESULTS.md#ara-diac-small-1.0"},{name:"der_student_fullset",value:8.259,source:"interscript/interscript-ml docs/RESULTS.md#ara-diac-small-1.0"}],parity:{samples:800,cer_delta:0},license:"BSD-3-Clause"},{id:"heb-diac-1.1",task:"diacritization",scripts:["Hebr","Hebr"],precision:"fp32",filename:"heb.zip",url:null,parts:[{url:"https://github.com/interscript/interscript-ml/releases/download/heb-diac-1.1/heb.zip.part-00",sha256:"8dac0d62e9b0ac4b137412eaf3a542953f11575f12f66f76cb93d3f5d788fc1b",size:15e8},{url:"https://github.com/interscript/interscript-ml/releases/download/heb-diac-1.1/heb.zip.part-01",sha256:"230c5ab731ea5f001f802d60b9e9a328c10b43bc311a19ef1974f114384313ed",size:1280987905}],sha256:"f0022dde8d06e46e8f08cf0b2f7bbb887a05ed686b90f1d5aa82ca3ef690a0b0",size:2780987905,metrics:[{name:"der_greedy",value:16.44,source:"rababa/docs/RESULTS.md#hebrew-diacritization"},{name:"der_beam4",value:16.43,source:"rababa/docs/RESULTS.md#hebrew-diacritization"}],parity:{samples:500,cer_delta:0},license:"BSD-3-Clause"},{id:"ara-diac-1.0",task:"diacritization",scripts:["Arab","Arab"],precision:"fp32",filename:"ara-diac-1.0-fp32.zip",url:null,parts:[{url:"https://github.com/interscript/interscript-ml/releases/download/ara-diac-1.0/ara-diac-1.0-fp32.zip.part-00",sha256:"6282a9291fb45ac7fcc3abe79d33b5913e91f87dcff8b305bf1d57ed98a3ed0b",size:15e8},{url:"https://github.com/interscript/interscript-ml/releases/download/ara-diac-1.0/ara-diac-1.0-fp32.zip.part-01",sha256:"7e7254a89ec75493871f6f61a993315097dad1bb0ba63c4584453c309e8cb906",size:1280311342}],sha256:"9e6d9777fe2474b150450774aaa1c9e8a9051b502b184fde298b91636dcfdac6",size:2780311342,metrics:[{name:"der_total_greedy",value:2.5793,source:"rababa/docs/RESULTS.md#r6-verdict-table-sadeeddiac-25-2026-08-21"},{name:"der_morph_greedy",value:1.5317,source:"rababa/docs/RESULTS.md#r6-verdict-table-sadeeddiac-25-2026-08-21"}],parity:{samples:500,cer_delta:0},license:"BSD-3-Clause"},{id:"ara-diac-small-1.0-int8",task:"diacritization",scripts:["Arab","Arab"],precision:"int8",filename:"ara-diac-small-1.0-int8.zip",url:"https://github.com/interscript/interscript-ml/releases/download/ara-diac-small-1.0/ara-diac-small-1.0-int8.zip",parts:null,sha256:"af247d837bee7e755b5287102cfb715c48dc90c2cf41ec1c41e7238e1a72b678",size:256959713,metrics:[{name:"der_teacher_greedy",value:1.3205,source:"interscript/interscript-ml docs/RESULTS.md#ara-diac-small-1.0"},{name:"der_student_greedy",value:3.658,source:"interscript/interscript-ml docs/RESULTS.md#ara-diac-small-1.0"},{name:"der_teacher_fullset",value:2.5815,source:"interscript/interscript-ml docs/RESULTS.md#ara-diac-small-1.0"},{name:"der_student_fullset",value:8.259,source:"interscript/interscript-ml docs/RESULTS.md#ara-diac-small-1.0"}],parity:{samples:800,cer_delta:0},license:"BSD-3-Clause"}]};var Ye=un;function be(){return Ye.models}function Xe(e){return Ye.models.find(t=>t.id===e)}var mn=Ye.version;var fn={openapi:"3.1.0",info:{title:"Interscript API",version:"1.0.0",description:"Transliteration and neural text processing. Maps run in-edge on the interscript-ts native interpreter (289 systems); neural models (diacritization, grapheme-to-phoneme) run on Interscript's inference service. GraphQL remains available at POST /graphql.",license:{name:"BSD-3-Clause"}},servers:[{url:"https://api.interscript.org"}],tags:[{name:"service"},{name:"maps"},{name:"transliteration"},{name:"models"},{name:"inference"}],paths:{"/":{get:{tags:["service"],summary:"Service index",responses:{200:{$ref:"#/components/responses/Ok"}}}},"/v1/info":{get:{tags:["service"],summary:"Version and capability summary",responses:{200:{$ref:"#/components/responses/Ok"}}}},"/v1/maps":{get:{tags:["maps"],summary:"Every bundled transliteration system code",responses:{200:{$ref:"#/components/responses/Ok"}}}},"/v1/maps/{code}":{get:{tags:["maps"],summary:"One system's compiled map (JSON IR)",parameters:[{name:"code",in:"path",required:!0,schema:{type:"string"}}],responses:{200:{$ref:"#/components/responses/Ok"},404:{$ref:"#/components/responses/NotFound"}}}},"/v1/transliterate":{post:{tags:["transliteration"],summary:"Transliterate text with a system",requestBody:{required:!0,content:{"application/json":{schema:{$ref:"#/components/schemas/TransliterateRequest"},examples:{gek:{value:{system:"ungegn-kor-Kore-Latn-1939",input:"\uD3C9\uC591"}}}}}},responses:{200:{description:"Transliterated output",content:{"application/json":{schema:{$ref:"#/components/schemas/TransliterateResponse"}}}},404:{$ref:"#/components/responses/NotFound"},413:{$ref:"#/components/responses/Error"}}}},"/v1/detect":{post:{tags:["transliteration"],summary:"Rank systems by how well they map input to output",requestBody:{required:!0,content:{"application/json":{schema:{$ref:"#/components/schemas/DetectRequest"}}}},responses:{200:{$ref:"#/components/responses/Ok"}}}},"/v1/models":{get:{tags:["models"],summary:"The neural model index (IMF v1)",responses:{200:{$ref:"#/components/responses/Ok"}}}},"/v1/models/{id}":{get:{tags:["models"],summary:"One model's full entry (metrics, parity, download)",parameters:[{name:"id",in:"path",required:!0,schema:{type:"string"}}],responses:{200:{$ref:"#/components/responses/Ok"},404:{$ref:"#/components/responses/NotFound"}}}},"/v1/infer":{post:{tags:["inference"],summary:"Run a neural model (diacritization or G2P)",description:"Proxy to Interscript's inference service. Only models whose task is diacritization or g2p are served; see GET /v1/models for the catalog.",requestBody:{required:!0,content:{"application/json":{schema:{$ref:"#/components/schemas/InferRequest"},examples:{hebrew:{value:{model:"heb-diac-1.0",input:"\u05E9\u05DC\u05D5\u05DD \u05E2\u05DC\u05D9\u05DB\u05DD"},summary:"Hebrew nikud restoration"},urdu:{value:{model:"urd-g2p-1.0",input:"\u0627\u0631\u062F\u0648"},summary:"Urdu grapheme-to-phoneme"}}}}},responses:{200:{description:"Model output",content:{"application/json":{schema:{$ref:"#/components/schemas/InferResponse"}}}},404:{$ref:"#/components/responses/NotFound"},502:{$ref:"#/components/responses/Error"},503:{$ref:"#/components/responses/Error"}}}}},components:{schemas:{Error:{type:"object",properties:{error:{type:"object",properties:{code:{type:"string"},message:{type:"string"}}}}},TransliterateRequest:{type:"object",required:["system","input"],properties:{system:{type:"string",description:"A system code from GET /v1/maps",examples:["ungegn-kor-Kore-Latn-1939"]},input:{type:"string",maxLength:1e6}}},TransliterateResponse:{type:"object",properties:{system:{type:"string"},input:{type:"string"},output:{type:"string"}}},DetectRequest:{type:"object",required:["input","output"],properties:{input:{type:"string"},output:{type:"string"}}},InferRequest:{type:"object",required:["model","input"],properties:{model:{type:"string",description:"A model id from GET /v1/models",examples:["heb-diac-1.0"]},input:{type:"string",maxLength:4e3}}},InferResponse:{type:"object",properties:{model:{type:"string"},task:{type:"string",enum:["diacritization","g2p"]},input:{type:"string"},output:{type:"string"}}}},responses:{Ok:{description:"Success",content:{"application/json":{schema:{type:"object"}}}},NotFound:{description:"Unknown system or model",content:{"application/json":{schema:{$ref:"#/components/schemas/Error"}}}},Error:{description:"Error",content:{"application/json":{schema:{$ref:"#/components/schemas/Error"}}}}}}};var mr=[{method:"GET",path:"/v1/info",note:"version + capability summary"},{method:"GET",path:"/v1/maps",note:"every transliteration system code"},{method:"GET",path:"/v1/maps/{code}",note:"one system's compiled map (JSON IR)"},{method:"POST",path:"/v1/transliterate",note:"{system, input} \u2192 {output}"},{method:"POST",path:"/v1/detect",note:"{input, output} \u2192 ranked systems"},{method:"GET",path:"/v1/models",note:"neural model index (IMF v1)"},{method:"GET",path:"/v1/models/{id}",note:"one model's metadata"},{method:"POST",path:"/v1/infer",note:"{model, input} \u2192 {output}"},{method:"POST",path:"/graphql",note:"GraphQL endpoint (introspection enabled)"},{method:"GET",path:"/openapi.json",note:"OpenAPI 3.1 document"}];function ye(e){return e.replace(/&/g,"&").replace(//g,">")}function Ze(e){return` + + + + +Interscript API + + + +
+

Interscript API

+

Authority-backed transliteration for every script \u2014 REST v1 + GraphQL on the edge.

+ + + + +${mr.map(n=>``).join(` +`)} + +
MethodEndpointBehavior
${ye(n.method)}${ye(n.path)}${ye(n.note)}
+ +
+

Quick start

+
curl -X POST https://api.interscript.org/v1/transliterate \\
+  -H 'Content-Type: application/json' \\
+  -d '{"system":"alalc-ara-Arab-Latn-1997","input":"\u0627\u0644\u0633\u0644\u0627\u0645 \u0639\u0644\u064A\u0643\u0645"}'
+
+ +
+

Machine-readable

+ +
+
+ + +`}function h(e,t,n){return Response.json({error:{code:t,message:n}},{status:e})}var b=new fr,hr=e=>(e??"").toLowerCase().includes("text/html");b.get("/docs",e=>e.html(Ze("/openapi.json")));b.get("/",e=>hr(e.req.header("accept"))?e.html(Ze("/openapi.json")):e.json({name:"Interscript API",version:"v1",openapi:"/openapi.json",endpoints:["GET /v1/info","GET /v1/maps","GET /v1/maps/{code}","POST /v1/transliterate","POST /v1/detect","GET /v1/models","GET /v1/models/{id}","POST /v1/infer","POST /graphql"]}));b.get("/openapi.json",e=>e.json(fn));b.get("/v1/info",e=>e.json({api_version:"1.0.0",engine_version:fe,engine:"interscript-ts@native-interpreter",maps:_().length,models:be().length,models_index_version:mn,limits:D}));b.get("/v1/maps",e=>e.json({count:_().length,maps:_()}));b.get("/v1/maps/:code",async e=>{let t=e.env?.ASSETS;if(!t)return h(503,"assets_missing","ASSETS binding not configured");let n=e.req.param("code");if(!_().includes(n))return h(404,"map_not_found",`Couldn't locate ${n}`);let r=await t.fetch(`https://assets.internal/${n}.json`);return r.ok?new Response(r.body,{headers:{"content-type":"application/json; charset=utf-8"}}):h(404,"map_not_found",`Couldn't locate ${n}`)});b.post("/v1/transliterate",async e=>{let t=e.env?.ASSETS;if(!t)return h(503,"assets_missing","ASSETS binding not configured");Q(t);let n=await e.req.json().catch(()=>null);if(!n||typeof n!="object")return h(400,"bad_request","body must be JSON {system, input}");let{system:r,input:a}=n;if(typeof r!="string"||typeof a!="string")return h(400,"bad_request","system and input must be strings");try{let s=await he(r,a);return e.json({system:r,input:a,output:s})}catch(s){return s instanceof j?h(413,"input_too_long",s.message):s instanceof $?h(404,"map_not_found",s.message):h(500,"engine_error",String(s))}});b.post("/v1/detect",async e=>{let t=e.env?.ASSETS;if(!t)return h(503,"assets_missing","ASSETS binding not configured");Q(t);let n=await e.req.json().catch(()=>null),{input:r,output:a}=n??{};if(typeof r!="string"||typeof a!="string")return h(400,"bad_request","input and output must be strings");let s=await ge(r,a);return e.json({count:s.length,results:s})});b.get("/v1/models",e=>e.json({count:be().length,models:be()}));b.get("/v1/models/:id",e=>{let t=Xe(e.req.param("id"));return t?e.json(t):h(404,"model_not_found",`Couldn't locate ${e.req.param("id")}`)});b.post("/v1/infer",async e=>{let t=await e.req.json().catch(()=>null),{model:n,input:r}=t??{};if(typeof n!="string"||typeof r!="string")return h(400,"bad_request","body must be JSON {model, input}");if(!Xe(n))return h(404,"model_not_found",`Couldn't locate ${n}`);let{ML_ENDPOINT:a,ML_TOKEN:s}=e.env??{};if(!a||!s)return h(503,"inference_unconfigured","ML_ENDPOINT/ML_TOKEN are not set on this deployment");let o=await fetch(`${a}/infer`,{method:"POST",headers:{"content-type":"application/json","x-api-key":s},body:JSON.stringify({model:n,input:r}),signal:AbortSignal.timeout(ue)}).catch(()=>null);if(!o||!o.ok){let i=o?await o.text().catch(()=>""):"upstream unreachable";return h(502,"inference_upstream",i.slice(0,500))}let c=await o.json();return e.json({model:n,task:c.task,input:r,output:c.output})});var wr=gr({schema:br({typeDefs:Le,resolvers:{Query:{info:()=>pn(),systemCodes:()=>dn(),transliterate:(e,t)=>he(t.systemCode,t.input),detect:(e,t)=>ge(t.input,t.output)}}}),graphqlEndpoint:"*",landingPage:!1,maskedErrors:!1}),J=new yr;J.use("*",Lr({origin:"*",allowMethods:["GET","POST","OPTIONS"]}));J.route("/",b);J.all("*",async e=>{let t=e.env;t?.ASSETS&&Q(t.ASSETS),cn(t?.ML_ENDPOINT,t?.ML_TOKEN);let n;try{n=e.executionCtx}catch{n=void 0}let r=e.req.raw,a=(r.headers.get("content-type")??"").toLowerCase();if(r.method==="POST"&&!a.includes("application/json")){let s=await r.text(),o=!1;try{JSON.parse(s),o=!0}catch{}s.trim()&&!o&&(r=new Request(r.url,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({query:s})}))}return wr.fetch(r,e.env,n)});var Sr=J;export{fe as API_VERSION,D as LIMITS,J as app,Sr as default,Le as typeDefs}; diff --git a/dist/src/rest.js b/dist/src/rest.js index 98c32e6..27ba8a1 100644 --- a/dist/src/rest.js +++ b/dist/src/rest.js @@ -22,26 +22,31 @@ import { INFER_TIMEOUT_MS, LIMITS } from "./limits.js"; import { bundledSystemCodes } from "./engine.js"; import { getModel, listModels, MODELS_INDEX_VERSION } from "./models.js"; import { OPENAPI } from "./openapi.js"; +import { docsPage } from "./docs.js"; function errorResponse(status, code, message) { return Response.json({ error: { code, message } }, { status }); } export const rest = new Hono(); -rest.get("/", (c) => c.json({ - name: "Interscript API", - version: "v1", - openapi: "/openapi.json", - endpoints: [ - "GET /v1/info", - "GET /v1/maps", - "GET /v1/maps/{code}", - "POST /v1/transliterate", - "POST /v1/detect", - "GET /v1/models", - "GET /v1/models/{id}", - "POST /v1/infer", - "POST /graphql", - ], -})); +const wantsHtml = (accept) => (accept ?? "").toLowerCase().includes("text/html"); +rest.get("/docs", (c) => c.html(docsPage("/openapi.json"))); +rest.get("/", (c) => wantsHtml(c.req.header("accept")) + ? c.html(docsPage("/openapi.json")) + : c.json({ + name: "Interscript API", + version: "v1", + openapi: "/openapi.json", + endpoints: [ + "GET /v1/info", + "GET /v1/maps", + "GET /v1/maps/{code}", + "POST /v1/transliterate", + "POST /v1/detect", + "GET /v1/models", + "GET /v1/models/{id}", + "POST /v1/infer", + "POST /graphql", + ], + })); rest.get("/openapi.json", (c) => c.json(OPENAPI)); rest.get("/v1/info", (c) => c.json({ api_version: "1.0.0", diff --git a/dist/test/rest.test.js b/dist/test/rest.test.js index 08d8754..07f9e4d 100644 --- a/dist/test/rest.test.js +++ b/dist/test/rest.test.js @@ -34,6 +34,24 @@ describe("REST index + docs", () => { const body = (await res.json()); expect(body.endpoints).toContain("POST /v1/infer"); }); + it("GET / serves the docs page to browsers, JSON to API clients", async () => { + const html = await get("/", { accept: "text/html,application/xhtml+xml" }); + expect(html.status).toBe(200); + expect(html.headers.get("content-type")).toContain("text/html"); + const page = await html.text(); + expect(page).toContain(""); + expect(page).toMatch(/POST<\/span><\/td>\/v1\/transliterate/); + const json = await get("/"); + expect(json.headers.get("content-type")).toContain("application/json"); + }); + it("GET /docs always serves the docs page", async () => { + const res = await get("/docs"); + expect(res.status).toBe(200); + expect(res.headers.get("content-type")).toContain("text/html"); + const page = await res.text(); + expect(page).toContain("openapi.json"); + expect(page).toContain("/graphql"); + }); it("GET /openapi.json serves a 3.1 document covering all routes", async () => { const res = await get("/openapi.json"); expect(res.status).toBe(200); diff --git a/src/docs.ts b/src/docs.ts new file mode 100644 index 0000000..ff53c98 --- /dev/null +++ b/src/docs.ts @@ -0,0 +1,93 @@ +/** + * The API's own webpage — served from the deployed worker at `/` (to + * browsers, via content negotiation) and at `/docs` (always). Deployed + * content belongs to the api.interscript.org deployment, not the main + * website. Self-contained HTML: no external assets, system font stack. + */ + +const ENDPOINTS: { method: string; path: string; note: string }[] = [ + { method: "GET", path: "/v1/info", note: "version + capability summary" }, + { method: "GET", path: "/v1/maps", note: "every transliteration system code" }, + { method: "GET", path: "/v1/maps/{code}", note: "one system's compiled map (JSON IR)" }, + { method: "POST", path: "/v1/transliterate", note: "{system, input} → {output}" }, + { method: "POST", path: "/v1/detect", note: "{input, output} → ranked systems" }, + { method: "GET", path: "/v1/models", note: "neural model index (IMF v1)" }, + { method: "GET", path: "/v1/models/{id}", note: "one model's metadata" }, + { method: "POST", path: "/v1/infer", note: "{model, input} → {output}" }, + { method: "POST", path: "/graphql", note: "GraphQL endpoint (introspection enabled)" }, + { method: "GET", path: "/openapi.json", note: "OpenAPI 3.1 document" }, +] + +function esc(s: string): string { + return s.replace(/&/g, "&").replace(//g, ">") +} + +export function docsPage(openapiPath: string): string { + const rows = ENDPOINTS.map( + (e) => + `${esc(e.method)}${esc(e.path)}${esc(e.note)}`, + ).join("\n") + return ` + + + + +Interscript API + + + +
+

Interscript API

+

Authority-backed transliteration for every script — REST v1 + GraphQL on the edge.

+ + + + +${rows} + +
MethodEndpointBehavior
+ +
+

Quick start

+
curl -X POST https://api.interscript.org/v1/transliterate \\
+  -H 'Content-Type: application/json' \\
+  -d '{"system":"alalc-ara-Arab-Latn-1997","input":"السلام عليكم"}'
+
+ +
+

Machine-readable

+ +
+
+ + +` +} diff --git a/src/rest.ts b/src/rest.ts index 5d3f308..cfb38be 100644 --- a/src/rest.ts +++ b/src/rest.ts @@ -28,6 +28,7 @@ import { INFER_TIMEOUT_MS, LIMITS } from "./limits.js" import { bundledSystemCodes } from "./engine.js" import { getModel, listModels, MODELS_INDEX_VERSION } from "./models.js" import { OPENAPI } from "./openapi.js" +import { docsPage } from "./docs.js" function errorResponse(status: number, code: string, message: string) { return Response.json({ error: { code, message } }, { status }) @@ -35,23 +36,30 @@ function errorResponse(status: number, code: string, message: string) { export const rest = new Hono<{ Bindings: Env }>() +const wantsHtml = (accept: string | undefined): boolean => + (accept ?? "").toLowerCase().includes("text/html") + +rest.get("/docs", (c) => c.html(docsPage("/openapi.json"))) + rest.get("/", (c) => - c.json({ - name: "Interscript API", - version: "v1", - openapi: "/openapi.json", - endpoints: [ - "GET /v1/info", - "GET /v1/maps", - "GET /v1/maps/{code}", - "POST /v1/transliterate", - "POST /v1/detect", - "GET /v1/models", - "GET /v1/models/{id}", - "POST /v1/infer", - "POST /graphql", - ], - }), + wantsHtml(c.req.header("accept")) + ? c.html(docsPage("/openapi.json")) + : c.json({ + name: "Interscript API", + version: "v1", + openapi: "/openapi.json", + endpoints: [ + "GET /v1/info", + "GET /v1/maps", + "GET /v1/maps/{code}", + "POST /v1/transliterate", + "POST /v1/detect", + "GET /v1/models", + "GET /v1/models/{id}", + "POST /v1/infer", + "POST /graphql", + ], + }), ) rest.get("/openapi.json", (c) => c.json(OPENAPI)) diff --git a/test/rest.test.ts b/test/rest.test.ts index 1f6cc85..041cf7b 100644 --- a/test/rest.test.ts +++ b/test/rest.test.ts @@ -50,6 +50,27 @@ describe("REST index + docs", () => { expect(body.endpoints).toContain("POST /v1/infer") }) + it("GET / serves the docs page to browsers, JSON to API clients", async () => { + const html = await get("/", { accept: "text/html,application/xhtml+xml" }) + expect(html.status).toBe(200) + expect(html.headers.get("content-type")).toContain("text/html") + const page = await html.text() + expect(page).toContain("") + expect(page).toMatch(/POST<\/span><\/td>\/v1\/transliterate/) + + const json = await get("/") + expect(json.headers.get("content-type")).toContain("application/json") + }) + + it("GET /docs always serves the docs page", async () => { + const res = await get("/docs") + expect(res.status).toBe(200) + expect(res.headers.get("content-type")).toContain("text/html") + const page = await res.text() + expect(page).toContain("openapi.json") + expect(page).toContain("/graphql") + }) + it("GET /openapi.json serves a 3.1 document covering all routes", async () => { const res = await get("/openapi.json") expect(res.status).toBe(200)