1function e(){const e="undefined"!=typeof navigator&&navigator.deviceMemory?navigator.deviceMemory:4,t="undefined"!=typeof navigator&&navigator.hardwareConcurrency?navigator.hardwareConcurrency:4;return e<1?"minimal":e<=2||t<=2?"low":"high"}function t(e,t,a){return e<=a&&t<=a?{width:e,height:t}:e>t?{width:a,height:Math.round(t*(a/e))}:{width:Math.round(e*(a/t)),height:a}}function a(e){const t=e.length/4,a=new Uint32Array(256),n=new Uint8ClampedArray(t);for(let d=0,f=0;d<e.length;d+=4,f++){const t=77*e[d]+151*e[d+1]+28*e[d+2]>>8;n[f]=t,a[t]++}const r=Math.max(1,Math.floor(.01*t));let o=0,i=255,s=0;for(let d=0;d<256;d++)if(s+=a[d],s>r){o=d;break}s=0;for(let d=255;d>=0;d--)if(s+=a[d],s>r){i=d;break}const c=i-o,l=c>10?255/c:1,h=c>10?o:0;for(let d=0,f=0;d<e.length;d+=4,f++){let t=(n[f]-h)*l;t<0?t=0:t>255&&(t=255),e[d]=e[d+1]=e[d+2]=t,e[d+3]=255}return e}async function n(e,{maxDim:n,quality:r,mainThreadFallback:o}){if("undefined"!=typeof Worker&&"undefined"!=typeof OffscreenCanvas&&"function"==typeof createImageBitmap){let o=null;try{o=await createImageBitmap(e);const{width:s,height:c}=t(o.width,o.height,n),l=await function(e,t,n,r){const o=`\n const applyGrayscaleAutoContrast = ${a.toString()};\n self.onmessage = async (e) => {\n try {\n const { bitmap, width, height, quality } = e.data;\n const canvas = new OffscreenCanvas(width, height);\n const ctx = canvas.getContext('2d', { willReadFrequently: true });\n ctx.drawImage(bitmap, 0, 0, width, height);\n bitmap.close();\n // Bypass destructive grayscaling and auto-contrast to preserve optimal color and detail for PaddleOCR.\n const blob = await canvas.convertToBlob({ type: 'image/jpeg', quality });\n self.postMessage({ ok: true, blob });\n } catch (err) {\n self.postMessage({ ok: false, error: (err && err.message) || String(err) });\n }\n };\n `,i=URL.createObjectURL(new Blob([o],{type:"application/javascript"})),s=new Worker(i);return new Promise((a,o)=>{s.onmessage=e=>{e.data.ok?a(e.data.blob):o(new Error(e.data.error))},s.onerror=e=>o(new Error(e.message||"Preprocess worker error")),s.postMessage({bitmap:e,width:t,height:n,quality:r},[e])}).finally(()=>{s.terminate(),URL.revokeObjectURL(i)})}(o,s,c,r);return o=null,await(i=l,new Promise((e,t)=>{const a=new FileReader;a.onload=()=>e(a.result),a.onerror=t,a.readAsDataURL(i)}))}catch(s){console.warn("[OCR] Worker preprocessing failed, falling back to main thread:",s),o&&"function"==typeof o.close&&o.close()}}var i;if("function"==typeof o)return o(e,n,r);throw new Error("No preprocessing path available")}export{a as applyGrayscaleAutoContrast,t as fitDimensions,e as getDeviceCapability,n as preprocessImageOptimized};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.