UNPKG

esearch-ocr

Version:

paddleocr models run on onnx

2 lines (1 loc) 27.3 kB
(function(D,_){typeof exports=="object"&&typeof module<"u"?_(exports):typeof define=="function"&&define.amd?define(["exports"],_):(D=typeof globalThis<"u"?globalThis:D||self,_(D["esearch-ocr"]={}))})(this,function(D){"use strict";var Ln=Object.defineProperty;var Fn=(D,_,F)=>_ in D?Ln(D,_,{enumerable:!0,configurable:!0,writable:!0,value:F}):D[_]=F;var Bt=(D,_,F)=>Fn(D,typeof _!="symbol"?_+"":_,F);let _=(t,e)=>new OffscreenCanvas(t,e);function F(t,e){return _(t,e)}function Qt(t){_=t}function vt(t){return t>0?Math.floor(t):Math.ceil(t)}function U(t,e,s){return Math.max(e,Math.min(t,s))}function mt(t,e,s,o,a="high"){return Zt(t,e,s,o,a).getImageData(0,0,e,s)}function Zt(t,e,s,o,a="high"){const i=H(t),u=F(e,s).getContext("2d");return u.imageSmoothingEnabled=a!==!1,a&&(u.imageSmoothingQuality=a),o==="fill"?u.scale(Math.min(e/t.width,1),Math.min(s/t.height,1)):u.scale(e/t.width,s/t.height),u.drawImage(i,0,0),u}function H(t,e,s){const o=F(e||t.width,s||t.height);return o.getContext("2d").putImageData(t,0,0),o}function gt(t,e,s){const o=t.data,a=[],i=[],r=[];let u=0,m=0;for(let h=0;h<o.length;h+=4)r[m]||(r[m]=[]),i[m]||(i[m]=[]),a[m]||(a[m]=[]),a[m][u]=(o[h]/255-e[0])/s[0],i[m][u]=(o[h+1]/255-e[1])/s[1],r[m][u]=(o[h+2]/255-e[2])/s[2],u++,u===t.width&&(u=0,m++);return[r,i,a]}class Et{constructor(e){Bt(this,"tl",[]);Bt(this,"name");this.name=e}l(e){const s=performance.now();this.tl.push({t:e,n:s});const o=[];for(let i=1;i<this.tl.length;i++){const r=this.tl[i].n-this.tl[i-1].n,u=this.tl[i-1].t,m=o.find(h=>h.n===u);m?(m.c++,m.d+=r):o.push({d:r,n:u,c:1})}const a=[];for(const i of o){const r=i.c>1?`${i.n}x${i.c}`:i.n;a.push(`${r} ${i.d}`)}a.push(this.tl.at(-1).t),console.log(`${this.name} ${o.map(i=>i.d).reduce((i,r)=>i+r,0)}ms: `,a.join(" "))}}async function Jt(t,e,s,o,a,i){const{transposedData:r,image:u}=tn(t,a,i),h=(await nn(r,u,e,s))[0].data,l=h.reduce((y,x)=>Math.max(y,x)),d=h.findIndex(y=>y===l);return o[d]}function tn(t,e,s){const o=mt(t,e,s);return{transposedData:gt(o,[.485,.456,.406],[.229,.224,.225]),image:o}}async function nn(t,e,s,o){const a=t.flat(Number.POSITIVE_INFINITY),i=Float32Array.from(a),r=new s.Tensor("float32",i,[1,3,e.height,e.width]),u={};u[o.inputNames[0]]=r;const m=await o.run(u);return Object.values(m)}function en(t){if(t.length===0)throw new Error("Empty contour");const e=on([...t]);let s=Number.POSITIVE_INFINITY;const o={center:{x:0,y:0},size:{width:0,height:0},angle:0};for(let a=0;a<e.length;a++){const i=e[a],r=e[(a+1)%e.length],u={x:r.x-i.x,y:r.y-i.y},m=Math.hypot(u.x,u.y),[h,l]=[u.x/m,u.y/m];let d=Number.POSITIVE_INFINITY,y=Number.NEGATIVE_INFINITY,x=Number.POSITIVE_INFINITY,b=Number.NEGATIVE_INFINITY;for(const I of e){const k=(I.x-i.x)*h+(I.y-i.y)*l;d=Math.min(d,k),y=Math.max(y,k);const N=-(I.x-i.x)*l+(I.y-i.y)*h;x=Math.min(x,N),b=Math.max(b,N)}const p=(y-d)*(b-x);if(p<s){s=p;const I=(d+y)/2,k=(x+b)/2;o.center={x:i.x+h*I-l*k,y:i.y+l*I+h*k},o.size={width:y-d,height:b-x},o.angle=Math.atan2(l,h)*(180/Math.PI)}}return o.size.width<o.size.height&&([o.size.width,o.size.height]=[o.size.height,o.size.width],o.angle+=90),o.angle=(o.angle%180+180)%180,o}function on(t){t.sort((o,a)=>o.x-a.x||o.y-a.y);const e=[];for(const o of t){for(;e.length>=2&&Pt(e[e.length-2],e[e.length-1],o)<=0;)e.pop();e.push(o)}const s=[];for(let o=t.length-1;o>=0;o--){const a=t[o];for(;s.length>=2&&Pt(s[s.length-2],s[s.length-1],a)<=0;)s.pop();s.push(a)}return e.slice(0,-1).concat(s.slice(0,-1))}function Pt(t,e,s){return(e.x-t.x)*(s.y-t.y)-(e.y-t.y)*(s.x-t.x)}function sn(t,e,s="CHAIN_APPROX_SIMPLE"){const o=t.length,a=o>0?t[0].length:0,i=Array.from({length:o},()=>new Array(a).fill(!1));for(let r=0;r<o;r++)for(let u=0;u<a;u++)if(t[r][u]!==0&&!i[r][u]&&At(t,u,r)){const m=cn(t,i,u,r,s==="CHAIN_APPROX_SIMPLE");e.push(m)}}function At(t,e,s){return t[s][e]!==0&&(s>0&&t[s-1][e]===0||s<t.length-1&&t[s+1][e]===0||e>0&&t[s][e-1]===0||e<t[0].length-1&&t[s][e+1]===0)}function cn(t,e,s,o,a){const i=[];let r={x:s,y:o},u={x:s-1,y:o};const m=new Map,h=new Map;function l(p){return p.x+p.y*t[0].length}function d(p){const I=Math.floor(p/t[0].length);return{x:p%t[0].length,y:I}}function y(p,I){const k=l(p),N=l(I),B=bt(I.x-p.x,I.y-p.y),A=bt(p.x-I.x,p.y-I.y),V=m.get(k)??[],E=m.get(N)??[];m.set(k,[...V,B]),m.set(N,[...E,A])}function x(p){const I=l(r);u=r,r={x:r.x+rt[p].dx,y:r.y+rt[p].dy},y(u,r);const N=(h.get(I)??[]).filter(B=>B!==p);N.length>0?h.set(I,N):h.delete(I)}m.set(l(r),[bt(-1,0)]);let b=0;do{i.push(r),e[r.y][r.x]=!0;const p=rn(t,m,r);if(p.length===0){if(h.size===0)break;const[I,k]=Array.from(h.entries()).at(0),N=k[0];r=d(I),x(N)}if(p.length>=1){const I=l(r);h.set(I,p);const k=p[0];x(k)}b++}while(b<1e9);return a?ln(i):i}const rt=[{dx:1,dy:0},{dx:1,dy:-1},{dx:0,dy:-1},{dx:-1,dy:-1},{dx:-1,dy:0},{dx:-1,dy:1},{dx:0,dy:1},{dx:1,dy:1}];function rn(t,e,s){function o(r){return r.x+r.y*t[0].length}const a=e.get(o(s))??[],i=[];for(const[r,{dx:u,dy:m}]of rt.entries()){if(a.includes(r))continue;const h=s.x+u,l=s.y+m;h>=0&&h<t[0].length&&l>=0&&l<t.length&&At(t,h,l)&&i.push(r)}return i}function bt(t,e){const s=rt.findIndex(({dx:o,dy:a})=>t===o&&e===a);return s===-1?0:s}function ln(t){if(t.length<3)return[...t];const e=[t[0]];for(let s=1;s<t.length-1;s++){const o=e[e.length-1],a=t[s],i=t[s+1];an(o,a,i)||e.push(a)}return e.push(t[t.length-1]),e}function an(t,e,s){return(e.x-t.x)*(s.y-e.y)===(e.y-t.y)*(s.x-e.x)}const q=new Et("t"),Y=new Et("af_det");let j=!1,pt=!1,W=null;function ot(t,e){var o;const s=document.createElement("canvas");s.width=t.width,s.height=t.height,s.getContext("2d").drawImage(t,0,0),e&&(s.id=e);try{(o=document==null?void 0:document.body)==null||o.append(s)}catch{}}let lt=(t,e,s)=>new ImageData(t,e,s);function R(...t){pt&&console.log(...t)}function un(...t){pt&&console.log(t.map(e=>`%c${e}`).join(""),...t.map(e=>`color: ${e}`))}async function fn(t){_t(t);const e={det:"det"in t?t.det:{input:t.detPath,ratio:t.detRatio,on:async o=>{t.onDet&&t.onDet(o),t.onProgress&&t.onProgress("det",1,1)}},rec:"rec"in t?t.rec:{input:t.recPath,decodeDic:t.dic,imgh:t.imgh,on:async(o,a,i)=>{t.onRec&&t.onRec(o,a),t.onProgress&&t.onProgress("rec",i,o+1)}},docCls:"rec"in t?t.docCls:t.docClsPath?{input:t.docClsPath}:void 0,analyzeLayout:"rec"in t?t.analyzeLayout:{columnsTip:t.columnsTip,docDirs:t.docDirs},...t},s=await mn(e);return W=s,s}function _t(t){j=!!t.dev,pt=j||!!t.log,j||(q.l=()=>{},Y.l=()=>{}),t.canvas&&Qt(t.canvas),t.imageData&&(lt=t.imageData)}async function Ot(t){let e;if(typeof window>"u"){const s=t;if(!s.data||!s.width||!s.height)throw new Error("invalid image data");return s}if(typeof t=="string"?(e=new Image,e.src=t,await new Promise(s=>{e.onload=s})):(t instanceof ImageData,e=t),e instanceof HTMLImageElement){const o=F(e.naturalWidth,e.naturalHeight).getContext("2d");if(!o)throw new Error("canvas context is null");o.drawImage(e,0,0),e=o.getImageData(0,0,e.naturalWidth,e.naturalHeight)}if(e instanceof HTMLCanvasElement){const s=e.getContext("2d");if(!s)throw new Error("canvas context is null");e=s.getImageData(0,0,e.width,e.height)}return e}function yt(){try{F(1,1),lt(new Uint8ClampedArray(4),1,1)}catch(t){throw console.log("nodejs need set canvas, please use setOCREnv to set canvas and imageData"),t}}async function hn(t){if(!W)throw new Error("need init");return W.ocr(t)}async function dn(t){if(!W)throw new Error("need init");return W.det(t)}async function xn(t){if(!W)throw new Error("need init");return W.rec(t)}async function mn(t){yt();const e={ort:t.ort,ortOption:t.ortOption},s=t.docCls?await zt({...t.docCls,...e}):void 0,o=await Vt({...t.det,...e}),a=await Rt({...t.rec,...e});return{ocr:async i=>{let r=await Ot(i),u=0;s&&(u=await s.docCls(r),R("dir",u),r=Mt(r,360-u));const m=await o.det(r),h=await a.rec(m),l=Ft(h,t.analyzeLayout);return R(h,l),q.l("end"),{src:h,...l,docDir:u}},det:o.det,rec:a.rec}}function It(t,e,s){return t.InferenceSession.create(e,s)}async function zt(t){const e=await It(t.ort,t.input,t.ortOption);return{docCls:async o=>Jt(o,t.ort,e,[0,90,180,270],224,224)}}async function Vt(t){yt();let e=1;const s=await It(t.ort,t.input,t.ortOption);t.ratio!==void 0&&(e=t.ratio);async function o(a){var x;const i=a;if(j){const b=H(i);ot(b)}q.l("pre_det");const{data:r,width:u,height:m}=pn(i,e),{transposedData:h,image:l}=r;q.l("det");const d=await gn(h,l,s,t.ort);q.l("aft_det");const y=yn({data:d.data,width:d.dims[3],height:d.dims[2]},u,m,i);return(x=t==null?void 0:t.on)==null||x.call(t,y),y}return{det:o}}async function Rt(t){var r;yt();let e=48;const s=await It(t.ort,t.input,t.ortOption),o=t.decodeDic.split(/\r\n|\r|\n/)||[];o.at(-1)===""?o[o.length-1]=" ":o.push(" "),t.imgh&&(e=t.imgh);const a=((r=t.optimize)==null?void 0:r.space)===void 0?!0:t.optimize.space;async function i(u){var l;const m=[];q.l("bf_rec");const h=vn(u,e);for(const[d,y]of h.entries()){const{b:x,imgH:b,imgW:p}=y,I=await bn(x,b,p,s,t.ort),k=En(I,o,{opm:{space:a}})[0];m.push({text:k.text,mean:k.mean,box:u[d].box,style:u[d].style}),(l=t==null?void 0:t.on)==null||l.call(t,d,k,u.length)}return q.l("rec_end"),m.filter(d=>d.mean>=.5)}return{rec:i}}async function gn(t,e,s,o){const a=Float32Array.from(t.flat(3)),i=new o.Tensor("float32",a,[1,3,e.height,e.width]),r={};return r[s.inputNames[0]]=i,(await s.run(r))[s.outputNames[0]]}async function bn(t,e,s,o,a){const i=Float32Array.from(t.flat(3)),r=new a.Tensor("float32",i,[1,3,e,s]),u={};return u[o.inputNames[0]]=r,(await o.run(u))[o.outputNames[0]]}function pn(t,e){const s=Math.max(Math.round(t.height*e/32)*32,32),o=Math.max(Math.round(t.width*e/32)*32,32);if(j){const r=H(t);ot(r)}const a=mt(t,o,s,"fill"),i=gt(a,[.485,.456,.406],[.229,.224,.225]);if(R(a),j){const r=H(a);ot(r)}return{data:{transposedData:i,image:a},width:o,height:s}}function yn(t,e,s,o){Y.l("");const a=Math.min(o.width,e),i=Math.min(o.height,s),{data:r,width:u,height:m}=t,h=new Uint8Array(u*m);for(let x=0;x<r.length;x++){const b=r[x]>.3?255:0;h[x]=b}if(j){const x=new Uint8ClampedArray(u*m*4);for(let I=0;I<r.length;I++){const k=I*4,N=r[I]>.3?255:0;x[k]=x[k+1]=x[k+2]=N,x[k+3]=255,h[I]=N}const b=lt(x,u,m),p=H(b);ot(p,"det_ru")}Y.l("edge");const l=[],d=[];for(let x=0;x<m;x++)d.push(Array.from(h.slice(x*u,x*u+u)));const y=[];if(sn(d,y),j){const x=document.querySelector("#det_ru").getContext("2d");for(const b of y){x.moveTo(b[0].x,b[0].y);for(const p of b)x.lineTo(p.x,p.y);x.strokeStyle="red",x.closePath(),x.stroke()}}for(let x=0;x<y.length;x++){Y.l("get_box");const b=3,p=y[x],{points:I,sside:k}=Cn(p);if(k<b)continue;const N=Mn(I),B=N.points;if(N.sside<b+2)continue;const A=o.width/a,V=o.height/i;for(let z=0;z<B.length;z++)B[z][0]*=A,B[z][1]*=V;Y.l("order");const E=Nn(B);for(const z of E)z[0]=U(Math.round(z[0]),0,o.width),z[1]=U(Math.round(z[1]),0,o.height);const kt=vt(Lt(E[0],E[1])),Ct=vt(Lt(E[0],E[3]));if(kt<=3||Ct<=3)continue;Pn(B,"","red","det_ru"),Y.l("crop");const K=Sn(o,B);Y.l("match best");const{bg:O,text:Q}=Tn(K),ht=Bn(B,K,Q);l.push({box:ht,img:K,style:{bg:O,text:Q}})}return Y.l("e"),R(l),l}function In(t){let e=-1;const s=t.length;let o,a=t[s-1],i=0;for(;++e<s;)o=a,a=t[e],i+=o[1]*a[0]-o[0]*a[1];return i/2}function wn(t){let e=-1;const s=t.length;let o=t[s-1],a,i,r=o[0],u=o[1],m=0;for(;++e<s;)a=r,i=u,o=t[e],r=o[0],u=o[1],a-=r,i-=u,m+=Math.hypot(a,i);return m}function Mn(t){const s=Math.abs(In(t)),o=wn(t),a=s*1.5/o,i=[];for(const[h,l]of t.entries()){const d=t.at((h-1)%4),y=t.at((h+1)%4),x=l[0]-d[0],b=l[1]-d[1],p=Math.sqrt(x**2+b**2),I=x/p*a,k=b/p*a,N=l[0]-y[0],B=l[1]-y[1],A=Math.sqrt(N**2+B**2),V=N/A*a,E=B/A*a;i.push([l[0]+I+V,l[1]+k+E])}const r=[i[0][0]-i[1][0],i[0][1]-i[1][1]],u=[i[2][0]-i[1][0],i[2][1]-i[1][1]],m=r[0]*u[1]-r[1]*u[0];return{points:i,sside:Math.abs(m)}}function kn(t,e,s){const o=e.width,a=e.height,i=s*Math.PI/180,r=Math.cos(i),u=Math.sin(i),m=t.x,h=t.y,l=o*.5,d=a*.5,y=[],x=m-l*r+d*u,b=h-l*u-d*r;y.push([x,b]);const p=m+l*r+d*u,I=h+l*u-d*r;y.push([p,I]);const k=m+l*r-d*u,N=h+l*u+d*r;y.push([k,N]);const B=m-l*r-d*u,A=h-l*u+d*r;return y.push([B,A]),y}function Cn(t){const s=en(t),o=Array.from(kn(s.center,s.size,s.angle)).sort((l,d)=>l[0]-d[0]);let a=0,i=1,r=2,u=3;o[1][1]>o[0][1]?(a=0,u=1):(a=1,u=0),o[3][1]>o[2][1]?(i=2,r=3):(i=3,r=2);const m=[o[a],o[i],o[r],o[u]],h=Math.min(s.size.height,s.size.width);return{points:m,sside:h}}function Lt(t,e){return Math.sqrt((t[0]-e[0])**2+(t[1]-e[1])**2)}function Nn(t){const e=[[0,0],[0,0],[0,0],[0,0]],s=t.map(i=>i[0]+i[1]);e[0]=t[s.indexOf(Math.min(...s))],e[2]=t[s.indexOf(Math.max(...s))];const o=t.filter(i=>i!==e[0]&&i!==e[2]),a=o[1].map((i,r)=>i-o[0][r]);return e[1]=o[a.indexOf(Math.min(...a))],e[3]=o[a.indexOf(Math.max(...a))],e}function Sn(t,e){const[s,o,a,i]=e.map(E=>({x:E[0],y:E[1]})),r=Math.sqrt((o.x-s.x)**2+(o.y-s.y)**2),u=Math.sqrt((i.x-s.x)**2+(i.y-s.y)**2),m=o.x-s.x,h=o.y-s.y,l=i.x-s.x,d=i.y-s.y,y=m*d-l*h;if(y===0)throw new Error("点共线,无法形成矩形");const x=r*d/y,b=-l*r/y,p=-u*h/y,I=m*u/y,k=-x*s.x-b*s.y,N=-p*s.x-I*s.y,B=H(t),A=F(Math.ceil(r),Math.ceil(u)),V=A.getContext("2d");return V.setTransform(x,p,b,I,k,N),V.drawImage(B,0,0),V.resetTransform(),V.getImageData(0,0,A.width,A.height)}function Tn(t){var m,h;const e=new Map,s=t.data;for(let l=0;l<s.length;l+=4){if(l/4%t.width>t.height*4)continue;const y=s[l],x=s[l+1],b=s[l+2],p=[y,x,b].join(",");e.set(p,(e.get(p)||0)+1)}const o=Dn(e,20).map(l=>({el:l.el.split(",").map(Number),count:l.count})),a=((m=o.at(0))==null?void 0:m.el)||[255,255,255],i=((h=o.at(1))==null?void 0:h.el)||[0,0,0];let r=i;const u=100;if(at(i,a)<u){const l=o.slice(1).filter(d=>at(d.el,a)>50);l.length>0&&(r=[0,1,2].map(d=>Math.round(jt(l.map(y=>[y.el[d],y.count]))))),(l.length===0||at(r,a)<u)&&(r=a.map(d=>255-d)),un(`rgb(${r.join(",")})`)}return{bg:a,text:r,textEdge:i}}function at(t,e){const s=t,o=e;return Math.sqrt((s[0]-o[0])**2+(s[1]-o[1])**2+(s[2]-o[2])**2)}function Dn(t,e=1){let s=[];return t.forEach((o,a)=>{s.length===0?s.push({el:a,count:o}):(s.length<e?s.push({el:a,count:o}):s.find(i=>i.count<=o)&&s.push({el:a,count:o}),s.sort((i,r)=>r.count-i.count),s.length>e&&(s=s.slice(0,e)))}),s}function Bn(t,e,s){let o=0,a=e.height,i=0,r=e.width;function u(x){return at(x,s)<200}t:for(let x=o;x<e.height;x++)for(let b=0;b<e.width;b++){const p=ut(e,b,x);if(u(p)){o=x;break t}}t:for(let x=a-1;x>=0;x--)for(let b=0;b<e.width;b++){const p=ut(e,b,x);if(u(p)){a=x;break t}}t:for(let x=i;x<e.width;x++)for(let b=o;b<=a;b++){const p=ut(e,x,b);if(u(p)){i=x;break t}}t:for(let x=r-1;x>=0;x--)for(let b=o;b<=a;b++){const p=ut(e,x,b);if(u(p)){r=x;break t}}const m=U(o-1,0,4),h=U(e.height-a-1,0,4),l=U(i-1,0,4),d=U(e.width-r-1,0,4);return[[t[0][0]+l,t[0][1]+m],[t[1][0]-d,t[1][1]+m],[t[2][0]-d,t[2][1]-h],[t[3][0]+l,t[3][1]-h]]}function ut(t,e,s){const o=(s*t.width+e)*4;return Array.from(t.data.slice(o,o+4))}function vn(t,e){const s=[];function o(a){const i=Math.floor(e*(a.width/a.height)),r=mt(a,i,e,void 0,!1);return j&&ot(H(r,i,e)),{data:r,w:i,h:e}}for(const a of t){let i=a.img;i.width<i.height&&(i=Mt(i,-90));const r=o(i);s.push({b:gt(r.data,[.5,.5,.5],[.5,.5,.5]),imgH:r.h,imgW:r.w})}return R(s),s}function En(t,e,s){const o=t.dims[2],a=[];let i=t.dims[0]-1;function r(m){return e.at(m-1)??""}for(let m=0;m<t.data.length;m+=o*t.dims[1]){const h=[],l=[];for(let d=m;d<m+o*t.dims[1];d+=o){const y=t.data.slice(d,d+o);let x=Number.NEGATIVE_INFINITY,b=-1,p=Number.NEGATIVE_INFINITY,I=-1;for(let k=0;k<y.length;k++){const N=y[k];N>x?(p=x,x=N,b=k):N>p&&N<x&&(p=N,I=k)}s.opm.space&&b===0&&r(I)===" "&&p>.001&&(x=p,b=I),l.push(x),h.push(b)}a[i]=u(h,l),i--}function u(m,h){const l=[],d=[];for(let b=0;b<m.length;b++)m[b]!==0&&(b>0&&m[b-1]===m[b]||(l.push(r(m[b])),d.push(h[b])));let y="",x=0;if(l.length){y=l.join("").trim();let b=0;for(const p of d)b+=p;x=b/d.length}return{text:y,mean:x}}return a}function Ft(t,e){var Ut;R(t);const s=(e==null?void 0:e.docDirs)??[{block:"tb",inline:"lr"},{block:"rl",inline:"tb"}],o={block:"tb",inline:"lr"},a={inline:[1,0],block:[0,1]},i={inline:[1,0],block:[0,1]};if(t.length===0)return{columns:[],parragraphs:[],readingDir:o,angle:{reading:{inline:0,block:90},angle:0}};const r=[{box:[[Number.NEGATIVE_INFINITY,Number.NEGATIVE_INFINITY],[Number.POSITIVE_INFINITY,Number.NEGATIVE_INFINITY],[Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY],[Number.NEGATIVE_INFINITY,Number.POSITIVE_INFINITY]],type:"none"}],u=0;function m(n){const c=l.center(n);for(let f=r.length-1;f>=0;f--){const w=r[f].box;if(c[0]>=w[0][0]&&c[0]<=w[1][0]&&c[1]>=w[0][1]&&c[1]<=w[3][1])return f}return u}const h={center:(n,c)=>[(n[0]+c[0])/2,(n[1]+c[1])/2],disByV:(n,c,f)=>Math.abs(f==="block"?d.dotMup(n,i.block)-d.dotMup(c,i.block):d.dotMup(n,i.inline)-d.dotMup(c,i.inline)),compare:(n,c,f)=>f==="block"?d.dotMup(n,i.block)-d.dotMup(c,i.block):d.dotMup(n,i.inline)-d.dotMup(c,i.inline),toInline:n=>d.dotMup(n,i.inline),toBlock:n=>d.dotMup(n,i.block)},l={inlineStart:n=>h.center(n[0],n[3]),inlineEnd:n=>h.center(n[1],n[2]),blockStart:n=>h.center(n[0],n[1]),blockEnd:n=>h.center(n[2],n[3]),inlineSize:n=>n[1][0]-n[0][0],blockSize:n=>n[3][1]-n[0][1],inlineStartDis:(n,c)=>h.disByV(n[0],c[0],"inline"),inlineEndDis:(n,c)=>h.disByV(n[1],c[1],"inline"),blockGap:(n,c)=>h.disByV(n[0],c[3],"block"),inlineCenter:n=>(n[2][0]+n[0][0])/2,blockCenter:n=>(n[2][1]+n[0][1])/2,inlineStartCenter:n=>l.inlineStart(n),center:n=>h.center(n[0],n[2])},d={fromPonts:(n,c)=>[n[0]-c[0],n[1]-c[1]],dotMup:(n,c)=>n[0]*c[0]+n[1]*c[1],numMup:(n,c)=>[n[0]*c,n[1]*c],add:(n,c)=>[n[0]+c[0],n[1]+c[1]]};function y(n){let c=0,f=0;const g=[];for(const[w,M]of n.entries()){const C=M>180?M-180:M,T=C-180,P=w===0?C:Math.abs(T-c)<Math.abs(C-c)?T:C;g.push(P),c=(c*f+P)/(f+1),f++}return{av:c,l:g}}function x(n,c){return Math.abs(n-c)<45||Math.abs(n-(c-180))<45||Math.abs(n-180-c)<45}function b(n){n.sort((f,g)=>f-g);const c=Math.floor(n.length/2);return n.length%2===0?(n[c-1]+n[c])/2:n[c]}function p(n){return n==="lr"||n==="rl"?"x":"y"}function I(n,c){let f=Number.POSITIVE_INFINITY,g=-1;for(let w=0;w<n.length;w++){const M=c(n[w]);M<f&&(f=M,g=w)}return n[g]}const k={lr:[1,0],rl:[-1,0],tb:[0,1],bt:[0,-1]};function N(n,c){const f=k[n.inline],g=k[n.block],w=k[c.inline],M=k[c.block],C=[d.dotMup(w,f),d.dotMup(w,g)],T=[d.dotMup(M,f),d.dotMup(M,g)];return P=>[d.dotMup(P,C),d.dotMup(P,T)]}function B(n,c){const f=N(n,c);return{b:g=>{for(const w of g){const[M,C]=f(w);w[0]=M,w[1]=C}},p:f}}function A(n){return c=>{const f=[[0,0],[0,0],[0,0],[0,0]];for(let g=0;g<n.length;g++)f[g]=c[n[g]];return f}}function V(n,c){return Math.sqrt((n[0]-c[0])**2+(n[1]-c[1])**2)}function E(n){const c=n.flatMap(v=>v.map(S=>S)),f=Math.min(...c.map(v=>d.dotMup(v,i.inline))),g=Math.max(...c.map(v=>d.dotMup(v,i.inline))),w=Math.min(...c.map(v=>d.dotMup(v,i.block))),M=Math.max(...c.map(v=>d.dotMup(v,i.block))),C=d.add(d.numMup(i.inline,f),d.numMup(i.block,w)),T=d.numMup(i.inline,g-f),P=d.numMup(i.block,M-w);return[C,d.add(C,T),d.add(d.add(C,T),P),d.add(C,P)]}function kt(n){let c=null,f=Number.POSITIVE_INFINITY;for(const P in $){const v=$[P].src.at(-1);if(!v)continue;const S=V(n.box[0],v.box[0]);S<f&&(c=Number(P),f=S)}if(c===null){$.push({src:[n]});return}const g=$[c].src.at(-1),w=l.inlineSize(n.box),M=l.inlineSize(g.box),C=Math.min(w,M),T=l.blockSize(n.box);if(!((l.inlineStartDis(n.box,g.box)<3*T||l.inlineEndDis(n.box,g.box)<3*T||h.disByV(l.center(n.box),l.center(g.box),"inline")<C*.4)&&l.blockGap(n.box,g.box)<T*1.1)){$.push({src:[n]});return}$[c].src.push(n)}function Ct(n){var w,M;const c=new RegExp("\\p{Ideographic}","u"),f=/[。,!?;:“”‘’《》、【】()…—]/,g={box:E(n.map(C=>C.box)),text:"",mean:jt(n.map(C=>[C.mean,C.text.length])),style:n[0].style};for(const C of n){const T=g.text.at(-1);T&&(!T.match(c)&&!T.match(f)||!((w=C.text.at(0))!=null&&w.match(c))&&!((M=C.text.at(0))!=null&&M.match(f)))&&(g.text+=" "),g.text+=C.text}return g}function K(n){n.sort((c,f)=>{const g=c.src.at(0)?l.blockSize(c.src.at(0).box):2;return h.disByV(l.blockStart(c.outerBox),l.blockStart(f.outerBox),"block")<g?h.compare(l.inlineStart(c.outerBox),l.inlineStart(f.outerBox),"inline"):h.compare(l.blockStart(c.outerBox),l.blockStart(f.outerBox),"block")})}if(e!=null&&e.columnsTip)for(const n of e.columnsTip)r.push(structuredClone(n));const O={inline:0,block:90},Q=t.map(n=>{const c=n.box,f=c[1][0]-c[0][0],g=c[3][1]-c[0][1];let w={x:0,y:0};if(f<g){const C=d.fromPonts(h.center(c[2],c[3]),h.center(c[0],c[1]));w={x:C[0],y:C[1]}}else{const C=d.fromPonts(h.center(c[1],c[2]),h.center(c[0],c[3]));w={x:C[0],y:C[1]}}return ft(Math.atan2(w.y,w.x)*(180/Math.PI))}),ht=y(Q),z=Q.filter(n=>x(n,ht.av)),Yt=b(z),An=b(z.map(n=>Math.abs(n-Yt))),Gt=z.filter(n=>Math.abs((n-Yt)/(An*1.4826))<2),G=ft(y(Gt).av);R("dir0",Q,ht,z,Gt,G);const Z=ft(G+90),_n=x(G,0)?"x":"y",On=x(Z,90)?"y":"x",Nt=s.find(n=>_n===p(n.inline)&&On===p(n.block))??s.at(0);Nt&&(o.block=Nt.block,o.inline=Nt.inline);const Ht={lr:0,rl:180,tb:90,bt:270};O.inline=I([G,G-360,G-180,G+180],n=>Math.abs(n-Ht[o.inline])),O.block=I([Z,Z-360,Z-180,Z+180],n=>Math.abs(n-Ht[o.block])),a.inline=[Math.cos(O.inline*(Math.PI/180)),Math.sin(O.inline*(Math.PI/180))],a.block=[Math.cos(O.block*(Math.PI/180)),Math.sin(O.block*(Math.PI/180))],R("dir",o,O,a,G,Z);const qt=[[o.inline[0],o.block[0]],[o.inline[1],o.block[0]],[o.inline[1],o.block[1]],[o.inline[0],o.block[1]]].map(([n,c])=>({lt:0,rt:1,rb:2,lb:3})[n==="l"||n==="r"?n+c:c+n]),dt=B({inline:"lr",block:"tb"},o),Wt=A(qt),zn=t.map(n=>{const c=Wt(n.box);return dt.b(c),{...n,box:c}});for(const n of r)n.box=Wt(n.box),dt.b(n.box);i.inline=dt.p(a.inline),i.block=dt.p(a.block),R("相对坐标系",i);const Vn=zn.sort((n,c)=>h.compare(l.blockStart(n.box),l.blockStart(c.box),"block")),J=[];for(const n of Vn){const c=m(n.box),f=(Ut=J.at(-1))==null?void 0:Ut.line.at(-1);if(!f){J.push({line:[{src:n,colId:c}]});continue}const g=l.center(n.box),w=l.center(f.src.box);if(h.disByV(g,w,"block")<.5*l.blockSize(n.box)){const M=J.at(-1);M?M.line.push({src:n,colId:c}):J.push({line:[{src:n,colId:c}]})}else J.push({line:[{src:n,colId:c}]})}const xt=[];for(const n of J){if(n.line.length===1){xt.push({src:n.line[0].src,colId:n.line[0].colId});continue}const c=wt(n.line.map(g=>l.blockSize(g.src.box)));n.line.sort((g,w)=>h.compare(l.inlineStart(g.src.box),l.inlineStart(w.src.box),"inline"));let f=n.line.at(0);for(const g of n.line.slice(1)){const w=l.inlineEnd(f.src.box),M=l.inlineStart(g.src.box);r[g.colId].type==="table"||g.colId!==f.colId||h.toInline(M)-h.toInline(w)>c?(xt.push({...f}),f=g):(f.src.text+=g.src.text,f.src.mean=(f.src.mean+g.src.mean)/2,f.src.box=E([f.src.box,g.src.box]))}xt.push({...f})}const $=[],St=[],st=[];for(const n of xt)if(n.colId===u)St.push(n);else{const c=st.find(f=>f.colId===n.colId);c?c.src.push(n.src):st.push({src:[n.src],type:r[n.colId].type,colId:n.colId})}St.sort((n,c)=>h.compare(l.blockStart(n.src.box),l.blockStart(c.src.box),"block"));for(const n of St)kt(n.src);const ct=[];for(const[n,c]of $.entries()){const f=c.src,g=E(f.map(T=>T.box)),w=l.blockCenter(g),M=l.inlineSize(g);if(n===0){ct.push({smallCol:[{src:f,outerBox:g,x:w,w:M}]});continue}const C=ct.find(T=>{const P=T.smallCol.at(-1),v=l.blockSize(f.at(0).box);return l.inlineStartDis(P.outerBox,g)<3*v&&l.inlineEndDis(P.outerBox,g)<3*v&&l.blockGap(g,P.outerBox)<v*2.1});C?C.smallCol.push({src:f,outerBox:g,x:w,w:M}):ct.push({smallCol:[{src:f,outerBox:g,x:w,w:M}]})}for(const n of ct)n.smallCol.sort((c,f)=>h.compare(l.blockStart(c.outerBox),l.blockStart(f.outerBox),"block"));for(const n of st)n.src.sort((c,f)=>h.compare(l.blockStart(c.box),l.blockStart(f.box),"block"));const Tt=[];for(const n of ct){const c=E(n.smallCol.map(g=>g.outerBox)),f=n.smallCol.flatMap(g=>g.src);Tt.push({src:f,outerBox:c,type:"none"})}K(Tt);const it=[];for(const n of Tt){const c=it.at(-1);if(!c){it.push(n);continue}if(c.type!=="none"){it.push(n);continue}const f=c.outerBox,g=l.blockSize(n.src[0].box);c.src.length===1&&l.inlineStartDis(f,n.outerBox)<3*g||n.src.length===1&&l.inlineStartDis(f,n.outerBox)<3*g||l.inlineStartDis(f,n.outerBox)<3*g&&l.inlineEndDis(f,n.outerBox)<3*g?(c.src.push(...n.src),c.outerBox=E(c.src.map(w=>w.box))):it.push(n)}let Dt=!1;const X=[];for(const n of it){const c=X.at(-1),f={...n,reCal:!1};if(!c){X.push(f);continue}const g=l.blockSize(f.src.at(0).box);h.compare(l.blockEnd(f.outerBox),l.blockEnd(c.outerBox),"block")<0&&(l.inlineStartDis(c.outerBox,f.outerBox)<3*g||l.inlineEndDis(c.outerBox,f.outerBox)<3*g)?(c.src.push(...f.src),c.reCal=!0,Dt=!0):X.push(f)}for(const n of X)n.reCal&&(n.src.sort((c,f)=>h.compare(l.blockStart(c.box),l.blockStart(f.box),"block")),n.outerBox=E(n.src.map(c=>c.box)));st.length&&(Dt=!0);for(const n of st){const c=E(n.src.map(g=>g.box)),f=n.src;X.push({src:f,outerBox:c,type:n.type,reCal:!1})}Dt&&K(X);const $t=B(o,{inline:"lr",block:"tb"}),Xt=X.map(n=>{const c=n.src,f=[];if(n.type==="auto"||n.type==="none"){const M={};for(let S=1;S<c.length;S++){const L=c[S-1].box,nt=c[S].box,et=h.disByV(l.center(nt),l.center(L),"block");M[et]||(M[et]=0),M[et]++}const C=wt(c.map(S=>l.blockSize(S.box))),T=[[]];for(const S of Object.keys(M).map(L=>Number(L)).sort()){const L=T.at(-1),nt=L.at(-1);nt!==void 0?Math.abs(nt-S)<C*.5?L.push(S):T.push([]):L.push(S)}const P=T.map(S=>wt(S)).sort((S,L)=>S-L).at(0)||0;R("d",M,T,P),f.push([c[0]]);let v=c[0];for(let S=1;S<c.length;S++){const L=d.add(d.add(l.inlineStartCenter(v.box),d.numMup(i.block,P)),d.numMup(i.inline,-l.inlineStartDis(v.box,n.outerBox))),nt=l.inlineStartCenter(c[S].box),et=l.blockSize(c[S].box);if(l.inlineEndDis(v.box,n.outerBox)>2*et||V(L,nt)>et*.5)f.push([c[S]]);else{const Kt=f.at(-1);Kt?Kt.push(c[S]):f.push([c[S]])}v=c[S]}}else(n.type==="table"||n.type==="raw"||n.type==="raw-blank")&&f.push(c);for(const M of c)$t.b(M.box);$t.b(n.outerBox);const g=[];for(const[M,C]of qt.entries())g[C]=M;const w=A(g);for(const M of c)M.box=w(M.box);return n.outerBox=w(n.outerBox),R(f),{src:c,outerBox:n.outerBox,parragraphs:f.map(M=>({src:M,parse:Ct(M)}))}}),Rn=Xt.flatMap(n=>n.parragraphs.map(c=>c.parse));let tt=0;return o.inline==="lr"&&(tt=O.inline),o.inline==="rl"&&(tt=O.inline-180),o.block==="lr"&&(tt=O.block),o.block==="rl"&&(tt=O.block-180),R("angle",tt),{columns:Xt,parragraphs:Rn,readingDir:o,angle:{reading:O,angle:tt}}}function wt(t){return t.reduce((e,s)=>e+s,0)/t.length}function jt(t){const e=t.map(o=>o[1]).reduce((o,a)=>o+a,0);let s=0;for(const o of t)s+=o[0]*o[1]/e;return s}function ft(t){return(t%360+360)%360}function Mt(t,e){const s=ft(e);if(s===0)return t;if(![90,180,270].includes(s))throw new Error("只支持90度的旋转");const o=new Uint8ClampedArray(t.height*t.width*4);for(let r=0;r<t.height;r++)for(let u=0;u<t.width;u++){const m=r*t.width+u,h=s===90?u*t.height+(t.height-r-1):s===180?t.width-u-1+(t.height-r-1)*t.width:(t.width-u-1)*t.height+r;o.set(t.data.slice(m*4,m*4+4),h*4)}const a=s===90||s===270?t.height:t.width,i=s===90||s===270?t.width:t.height;return lt(o,a,i)}function Pn(t,e="",s,o,a){if(!j)return;const r=document.querySelector(`#${o}`).getContext("2d");r.beginPath(),r.strokeStyle=s,r.moveTo(t[0][0],t[0][1]),r.lineTo(t[1][0],t[1][1]),r.lineTo(t[2][0],t[2][1]),r.lineTo(t[3][0],t[3][1]),r.lineTo(t[0][0],t[0][1]),r.stroke(),r.strokeStyle="black",r.strokeText(e,t[0][0],t[0][1])}D.analyzeLayout=Ft,D.det=dn,D.init=fn,D.initDet=Vt,D.initDocDirCls=zt,D.initRec=Rt,D.loadImg=Ot,D.ocr=hn,D.rec=xn,D.rotateImg=Mt,D.setOCREnv=_t,Object.defineProperty(D,Symbol.toStringTag,{value:"Module"})});