@bicharts/shape-core 0.4.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2 +1,2 @@
1
1
  /*! @bicharts/shape-core — Apache-2.0. Bundled reference data: GeoNames (https://www.geonames.org/) CC BY 4.0; US Census/TIGER (public domain). Full text: NOTICE in this package. */
2
- import{a as j,b as q}from"./chunk-2LR73DNS.mjs";import{a as Y,b as G,c as x}from"./chunk-NWDPA7DG.mjs";import{a as U}from"./chunk-3MIEXLB3.mjs";import{a as z,b as F,c as k}from"./chunk-WBEROMBG.mjs";import{a as H}from"./chunk-QEH7WTLB.mjs";import X from"papaparse";var Z=12,$=100,J=.3,Q=.9,tt=120,et=1900,nt=2100,it=0,st=20,rt=new Set(["id","ids","uuid","guid","key","zip","zipcode","postal","postalcode","ssn","code","codes","sku","isbn","msisdn","imei"]);function at(p){if(!p)return!1;let e=p.replace(/([a-z0-9])([A-Z])/g,"$1 $2").replace(/[_\-./]+/g," ").toLowerCase().split(/\s+/).filter(o=>o.length>0);return e.length===0?!1:rt.has(e[e.length-1])}var ot=/\b(year|yr|fy|fiscal\s*year|calendar\s*year)\b/i,ut=/^(?:(?:19|20)\d{2}(?:[-/ ]?(?:q[1-4]|w(?:0?[1-9]|[1-4]\d|5[0-3])|(?:0?[1-9]|1[0-2])))?|q[1-4][-/ ](?:19|20)\d{2}|(?:jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)[a-z]*[-/ ]?(?:19|20)?\d{2})$/i;function W(p){if(!Number.isInteger(p)||p<190001||p>210012)return!1;let e=p%100;return e>=1&&e<=12}function P(p){if(!Number.isInteger(p)||p<19000101||p>21001231)return!1;let e=Math.floor(p/100)%100,o=p%100;return e>=1&&e<=12&&o>=1&&o<=31}function lt(p,e){if(!e||!/\b(?:19|20)\d{2}\b/.test(p))return!1;let o=p.replace(/\b(?:19|20)\d{2}\b/g,"").replace(/[-/.,]/g," ").trim();if(!o)return!1;let c=j(o);return c.length>0&&e[c]!==void 0}function ct(p){let{dataType:e,name:o,isMeasure:c,distinctCount:f}=p;if(e==="DateTime")return!0;if(c)return!1;if(e==="Integer"||e==="Decimal"){let n=p.minNum,b=p.maxNum;if(!(n!=null&&b!=null&&Number.isFinite(n)&&Number.isFinite(b)&&Number.isInteger(n)&&Number.isInteger(b)&&b>=n))return!1;let T=n>=1900&&b<=2100;if(T&&f>=2&&ot.test(o)||T&&f>=3&&f===b-n+1)return!0;let M=W(n)&&W(b),D=P(n)&&P(b);if(M||D){if(!p.sampleValues)return!0;let h=0,N=0;for(let l of p.sampleValues){if(l==null||l==="")continue;h++;let t=Number(String(l).trim());if(Number.isFinite(t)&&(M?W(t):P(t))&&N++,h>=60)break}if(h>=2&&N===h)return!0}return!1}if(p.sampleValues){let n=p.locale?q(p.locale):null,b=0,I=0;for(let T of p.sampleValues){if(T==null||T==="")continue;b++;let M=String(T).trim();if((ut.test(M)||lt(M,n))&&I++,b>=60)break}if(b>=2&&I/b>=.8)return!0}return!1}function mt(p){let e=(p||"").trim().toLowerCase();return e.startsWith("sum ")||e.startsWith("total ")?"sum":e.startsWith("average ")||e.startsWith("avg. ")?"avg":e.startsWith("count ")||e.startsWith("distinct count ")||e.startsWith("count (distinct) ")?"count":e.startsWith("min ")||e.startsWith("minimum ")?"min":e.startsWith("max ")||e.startsWith("maximum ")?"max":null}function ft(p){let{rows:e,measureColIdx:o,measureName:c,candidateDims:f,minNum:n,maxNum:b,discourageAgg:I}=p,T=100,M=.01,D="";for(let N of f){if(N.distinct<2||N.distinct>T)continue;let l=f.filter(i=>i.idx!==N.idx).map(i=>i.idx),t=new Map;for(let i of e){let u=i[o];if(typeof u!="number"||!Number.isFinite(u))continue;let d=l.length?l.map(y=>String(i[y])).join(D):"",g=t.get(d);g||(g={sum:0,cset:new Set},t.set(d,g)),g.sum+=u,g.cset.add(String(i[N.idx]))}let r=0,a=0,s=0;for(let i of t.values())i.cset.size<2||(s++,Math.abs(i.sum-100)<=100*M?r++:Math.abs(i.sum-1)<=1*M&&a++);if(s>=2&&(r/s>=.9||a/s>=.9))return{additivity:"part_of_whole",partOfWholeDim:N.name}}if(I)return{additivity:"intensive_rate"};let h=mt(c);return h==="avg"||h==="min"||h==="max"?{additivity:"intensive_rate"}:h==="sum"||h==="count"?{additivity:"additive"}:n!=null&&b!=null&&Number.isFinite(n)&&Number.isFinite(b)&&n>=0&&b<=1.0001&&b>0?{additivity:"intensive_rate"}:{additivity:"unknown"}}function B(p){let{dataType:e,isMeasure:o,name:c,distinct:f,nonblank:n,prec:b,maxval:I,minval:T}=p,M=I-T+1,D=M>0?f/M:1,h=n>0?f/n:0,N=e==="Decimal"||b>0;return at(c)?"Categorical":D>=Q&&(z(c)&&f<=tt||T>=et&&I<=nt||T>=it&&I<=st)?"Ordinal":o||f>Z&&(N||f>=$||h>=J)?"Continuous":"Categorical"}var K=class{_computedStatsForLevel=null;_cols=[];_rows=[];_origIndices=[];_rowHashes=new Set;dedupRows=!0;STR(e){return e==null?"":e.toString()}getPrecision(e){if(!isFinite(e))return 0;let c=e.toString().split(".")[1];return c?c.length:0}getColumns(){return this._cols}hasTimeComponent(e){return!(e instanceof Date)||isNaN(e.getTime())?!1:e.getHours()!==0||e.getMinutes()!==0||e.getSeconds()!==0||e.getMilliseconds()!==0}getColumnsWithStats(e,o){if(this._computedStatsForLevel==e)return this._cols;let c=0,f=parseInt(e),n=[];for(let t of this._cols){let r=new Map,a=[],s=0,i=0,u=0,d=null,g=null,y=null,w=!1,R=!0,A=!0,v=null,S=!1;for(let C of this._rows){let m=C[c],_=this.STR(m);if(_!=""){if(s+=_.length,r.set(_,(r.get(_)||0)+1),i++,t.dataType=="Integer"||t.dataType=="Decimal"||t.dataType=="DateTime")if((d===null||m<d)&&(d=m),(g===null||m>g)&&(g=m),t.dataType=="Integer"||t.dataType=="Decimal"){if(y===null?y=m:y+=m,t.dataType=="Decimal"){let L=this.getPrecision(m);L>u&&(u=L)}a.push(m)}else w=w||this.hasTimeComponent(m);S&&(m<v?R=!1:m>v&&(A=!1)),v=m,S=!0}}if(i>=3&&(R&&!A?t.sortedDirection="asc":A&&!R?t.sortedDirection="desc":t.sortedDirection="none"),i>0&&r.size>0&&!t.isMeasure){let C=0,m=Number.MAX_SAFE_INTEGER;for(let _ of r.values())_>C&&(C=_),_<m&&(m=_);if(t.modalShare=C/i,t.minGroupCount=m===Number.MAX_SAFE_INTEGER?null:m,r.size===2){let _=[...r.keys()].map(V=>Y(V).trim().toLowerCase()).sort(),E=[["false","true"],["no","yes"],["n","y"],["0","1"],["f","t"]].some(V=>_[0]===V[0]&&_[1]===V[1]),O=/^(is|has)[_a-z0-9]|(?:default|churn|fraud|approv|convert|active|cancel|delinquen|flag|paid|win|pass|fail)/i.test(t.name);(E||O)&&(t.isBinaryFlag=!0)}}t.dataType=="DateTime"&&(t.dateWithTime=w),t.isTemporal=ct({dataType:t.dataType,name:t.name,isMeasure:t.isMeasure,distinctCount:r.size,minNum:typeof d=="number"?d:null,maxNum:typeof g=="number"?g:null,sampleValues:r.keys(),locale:o}),this.updateColumnStats10(f,t,i,r,u,g,d),this.updateColumnStats20(f,a,i,y,t,s,w,d,g,u,r,o),!t.isMeasure&&(t.dataType==="Integer"||t.dataType==="Decimal")&&B({dataType:t.dataType,isMeasure:!1,name:t.name,distinct:r.size,nonblank:i,prec:u,maxval:typeof g=="number"?g:0,minval:typeof d=="number"?d:0})==="Continuous"&&(t.isMeasure=!0),n[c]=t.isMeasure||r.size>2e3?null:new Set(r.keys()),c++}let b=[];this._cols.forEach((t,r)=>{t.isMeasure||b.push({idx:r,distinct:t.distinctCount??0,name:t.name})}),this._cols.forEach((t,r)=>{if(!t.isMeasure)return;let a=typeof t.lowValue=="number"?t.lowValue:null,s=typeof t.highValue=="number"?t.highValue:null,i=ft({rows:this._rows,measureColIdx:r,measureName:t.name,candidateDims:b,minNum:a,maxNum:s,discourageAgg:!!t.discourageAggregationAcrossGroups});t.additivity=i.additivity,i.partOfWholeDim&&(t.partOfWholeDim=i.partOfWholeDim)});let I=50,T=b.filter(t=>t.distinct>=2&&t.distinct<=I);this._cols.forEach((t,r)=>{if(!t.isMeasure)return;let a=[];for(let v of this._rows){let S=v[r];if(S==null||S==="")continue;let C=typeof S=="number"?S:parseFloat(S);isNaN(C)||a.push(C)}if(a.length===0)return;let s=[...a].sort((v,S)=>v-S),i=v=>s[Math.min(s.length-1,Math.max(0,Math.floor(v*(s.length-1))))],u=i(.5),d=i(.1),g=i(.9),y=Math.abs(u)>1e-9?Math.abs(u):Math.abs(s[s.length-1])>1e-9?Math.abs(s[s.length-1]):1;t.relativeDispersion=Math.round((g-d)/y*1e3)/1e3;let w=0;for(let v of a)w+=v;w/=a.length;let R=0;for(let v of a)R+=(v-w)*(v-w);if(R<=1e-12)return;let A=[];for(let v of T){let S=new Map;for(let m of this._rows){let _=m[r];if(_==null||_==="")continue;let L=typeof _=="number"?_:parseFloat(_);if(isNaN(L))continue;let E=this.STR(m[v.idx])+"",O=S.get(E);O?(O.s+=L,O.n++):S.set(E,{s:L,n:1})}let C=0;for(let m of S.values()){let _=m.s/m.n;C+=m.n*(_-w)*(_-w)}A.push({otherColumn:v.name,eta2:Math.round(C/R*1e4)/1e4})}A.length>0&&(t.groupDiscrimination=A)});let M=.97,D=5,h=this._cols.map((t,r)=>({c:t,i:r})).filter(t=>t.c.isMeasure);for(let t=0;t<h.length;t++)for(let r=t+1;r<h.length;r++){let a=h[t].i,s=h[r].i,i=0,u=0,d=0,g=0,y=0,w=0;for(let S of this._rows){let C=S[a],m=S[s];if(C==null||C===""||m===null||m===void 0||m==="")continue;let _=typeof C=="number"?C:parseFloat(C),L=typeof m=="number"?m:parseFloat(m);isNaN(_)||isNaN(L)||(i++,u+=_,d+=L,g+=_*_,y+=L*L,w+=_*L)}if(i<D)continue;let R=i*g-u*u,A=i*y-d*d;if(R<=1e-12||A<=1e-12)continue;let v=(i*w-u*d)/Math.sqrt(R*A);if(Math.abs(v)>=M){let S=h[t].c,C=h[r].c;S.collinearWithMeasures||(S.collinearWithMeasures=[]),C.collinearWithMeasures||(C.collinearWithMeasures=[]),S.collinearWithMeasures.push(C.name),C.collinearWithMeasures.push(S.name)}}for(let t=0;t<this._cols.length;t++){let r=n[t];if(!r||r.size===0)continue;let a=[];for(let s=0;s<this._cols.length;s++){if(s===t)continue;let i=n[s];if(!i||i.size===0)continue;let u=0;for(let g of r)i.has(g)&&u++;let d=Math.round(u/r.size*100);d>0&&a.push({otherColumn:this._cols[s].name,percentShared:d})}a.length>0&&(this._cols[t].sharedValueRatioWithOthers=a)}let N=50,l=[];for(let t=0;t<this._cols.length;t++){let r=n[t];r&&r.size>=2&&r.size<=N&&l.push(t)}if(l.length>=2){let t=new Map,r=(s,i)=>s+":"+i;for(let s=0;s<l.length;s++)for(let i=s+1;i<l.length;i++)t.set(r(l[s],l[i]),new Map);for(let s of this._rows)for(let i=0;i<l.length;i++){let u=this.STR(s[l[i]])+"";for(let d=i+1;d<l.length;d++){let g=""+this.STR(s[l[d]]),y=t.get(r(l[i],l[d])),w=u+""+g;y.set(w,(y.get(w)??0)+1)}}let a=new Map;for(let s=0;s<l.length;s++)for(let i=s+1;i<l.length;i++){let u=l[s],d=l[i],g=n[u].size,y=n[d].size,w=t.get(r(u,d)),R=w.size,A=0;for(let m of w.values())(A===0||m<A)&&(A=m);let v=Math.round(R/(g*y)*100),S=R===g,C=R===y;if((this._cols[u].categoricalPairStats||=[]).push({otherColumn:this._cols[d].name,fillPct:v,determinesOther:S,minCellCount:A,distinctCombinations:R}),(this._cols[d].categoricalPairStats||=[]).push({otherColumn:this._cols[u].name,fillPct:v,determinesOther:C,minCellCount:A,distinctCombinations:R}),S&&g>y){let m=a.get(u);(!m||y<m.card)&&a.set(u,{name:this._cols[d].name,card:y,ratio:y/g})}if(C&&y>g){let m=a.get(d);(!m||g<m.card)&&a.set(d,{name:this._cols[u].name,card:g,ratio:g/y})}}for(let[s,i]of a)this._cols[s].primaryParentColumn=i.name,this._cols[s].nestingRatio=Math.round(i.ratio*100)/100}return this._computedStatsForLevel=e,this._cols}updateColumnStats20(e,o,c,f,n,b,I,T,M,D,h,N){if(e>=20){let l=[...o].sort((a,s)=>a-s),t=Math.floor(l.length/2);if(c>0&&f!=null?n.avgValue=n.dataType=="Integer"?Math.round(f/c):f/c:n.avgValue=null,c>0&&(n.avgLength=b/c),this._rows.length>0&&(n.dataType!="DateTime"||I||!T?n.lowValue=T:n.lowValue=new Date(T).toISOString().slice(0,10)+"T00:00:00.000Z",n.dataType!="DateTime"||I||!M?n.highValue=M:n.highValue=new Date(M).toISOString().slice(0,10)+"T00:00:00.000Z",n.medianValue=l.length===0?null:l.length%2===0?n.dataType=="Integer"?Math.round((l[t-1]+l[t])/2):(l[t-1]+l[t])/2:l[t],n.numericPrecision=D),l.length>0){let a=n.avgValue??0,s=l.length,i=0,u=0;for(let g of l){let y=g-a;i+=y*y,u+=y*y*y}let d=i/s;n.skewness=d===0?0:u/s/Math.pow(Math.sqrt(d),3),n.stdDev=Math.sqrt(d)}f!==null&&(n.sum=f);let r=Array.from(h.entries()).sort((a,s)=>s[1]-a[1]);if(n.topCategories=r.slice(0,10).map(a=>a[1]),!n.isMeasure&&r.length>0){if(n.dataType==="String"){let s=r.map(u=>u[0]);n.formatSignature=H(s);let i=/^(UUID|EMAIL_LIKE|URL_LIKE|PHONE_LIKE|NUMERIC_ID|HEX_ID|OPAQUE_ID_ALPHANUMERIC|DATE_STR|BOOLEAN)$/;n.formatSignature&&!i.test(n.formatSignature)&&(n.avgLength===void 0||n.avgLength>=3)&&(n.isFreeText=!0)}else n.topCategoryValues=r.slice(0,5).map(s=>s[0]);if(e>=20){let s=r.map(u=>u[0]),i=k(s,N);if(i!==null)n.ordinalPattern=i.pattern,n.orderedDomain=i.orderedDomain;else if(n.dataType==="String"){let u=F(s);u!==null&&(n.safeDistinctValues=u)}}let a=U(r.map(s=>s[0]),n.name,N);a!==null&&(n.geoKind=a.geoKind,n.geoMatchPct=a.geoMatchPct,a.geoAmbiguous&&(n.geoAmbiguous=!0))}if(l.length>=8&&(n.dataType==="Integer"||n.dataType==="Decimal")){let a=s=>l[Math.floor((l.length-1)*s)];n.quantiles={p05:a(.05),p25:a(.25),p75:a(.75),p95:a(.95)}}}}updateColumnStats10(e,o,c,f,n,b,I){e>=10&&(o.blankCount=this._rows.length-c,o.distinctCount=f.size+(o.blankCount!=0?1:0),o.valueNature="Categorical",c>0&&(o.dataType==="Integer"||o.dataType==="Decimal"?o.valueNature=B({dataType:o.dataType,isMeasure:!!o.isMeasure,name:o.name,distinct:f.size,nonblank:c,prec:n,maxval:b,minval:I}):o.dataType==="DateTime"&&(o.valueNature=o.dateWithTime?"Continuous":"Ordinal")))}getRowCount(){return this._rows.length}getLeafCardinality(){if(this._leafCardinality!==null)return this._leafCardinality;let e=[];if(this._cols.forEach((c,f)=>{c.isMeasure||e.push(f)}),e.length===0)return this._leafCardinality=this._rows.length,this._leafCardinality;let o=new Set;for(let c of this._rows)o.add(JSON.stringify(e.map(f=>c[f])));return this._leafCardinality=o.size,this._leafCardinality}_leafCardinality=null;obfuscateString(e){let o="abcdefghijklmnopqrstuvwxyz",c=()=>o[Math.floor(x()*o.length)],f=()=>c().toUpperCase(),n=()=>Math.floor(x()*10).toString(),b=t=>/[A-Z]/.test(t)?f():/[a-z]/.test(t)?c():/[0-9]/.test(t)?n():t,I=e.includes("@")&&e.includes("."),T=I?e.split("@"):[e],M=I?T[1]:"",D=M.endsWith(".com"),h=D?".com":"",N=D?M.slice(0,-4):M,l=t=>{let r="";for(let a of t)r+=b(a),/[a-zA-Z0-9]/.test(a)&&x()<.2&&(r+=b(a));if(r.length>6){let a=Math.floor(x()*Math.min(3,r.length-6));for(let s=0;s<a;s++){let i=0;for(;i<5;){let u=Math.floor(x()*r.length);if(/[a-zA-Z0-9]/.test(r[u])){r=r.slice(0,u)+r.slice(u+1);break}i++}}}return r};if(I){let t=l(T[0]),r=l(N);return`${t}@${r}${h}`}else return l(e)}toObjectArray(){return this._rows.map(e=>{let o={};return this._cols.forEach((c,f)=>{o[c.name]=e[f]}),o})}async getCSVAsync(e){let o=[],c=e?25:1e7,f=e?4e3:1e7,n=new Map;for(let I of this._rows){let T={};for(let M=0;M<this._cols.length;M++){let D=this._cols[M],h=I[M];if(this.STR(h)!=""){if(e&&D.dataType=="String")if(n.has(h))h=n.get(h);else{let N=this.obfuscateString(h);n.set(h,N),h=N}else D.dataType=="DateTime"&&!D.dateWithTime&&(h=new Date(h).toISOString().slice(0,10)+"T00:00:00.000Z");f-=this.STR(h).length}else h=null;T[M]=h,--f}if(o.push(T),--c,c<=0||f<=0)break}return await X.unparse(o,{header:!1})}getCSVHeaderLine(){return X.unparse([this._cols.map(e=>this.STR(e.name))])}addRow(e,o){if(this.dedupRows){let c="";for(let n of e)c+=this.STR(n)+"~";let f=G(c);if(this._rowHashes.has(f))return!1;this._rowHashes.add(f)}return this._rows.push(e),this._origIndices.push(o??-1),!0}getOriginalRowIndex(e){return e<0||e>=this._origIndices.length?-1:this._origIndices[e]}reset(){this._cols=[],this._rows=[],this._origIndices=[],this._rowHashes=new Set,this._leafCardinality=null}setColumns(e){this._cols=e}};export{at as a,ct as b,mt as c,ft as d,B as e,K as f};
2
+ import{a as j,b as q}from"./chunk-2LR73DNS.mjs";import{a as Y,b as G,c as x}from"./chunk-NWDPA7DG.mjs";import{a as U}from"./chunk-IFOJMDYY.mjs";import{a as z,b as F,c as k}from"./chunk-WBEROMBG.mjs";import{a as H}from"./chunk-QEH7WTLB.mjs";import X from"papaparse";var Z=12,$=100,J=.3,Q=.9,tt=120,et=1900,nt=2100,it=0,st=20,rt=new Set(["id","ids","uuid","guid","key","zip","zipcode","postal","postalcode","ssn","code","codes","sku","isbn","msisdn","imei"]);function at(p){if(!p)return!1;let e=p.replace(/([a-z0-9])([A-Z])/g,"$1 $2").replace(/[_\-./]+/g," ").toLowerCase().split(/\s+/).filter(o=>o.length>0);return e.length===0?!1:rt.has(e[e.length-1])}var ot=/\b(year|yr|fy|fiscal\s*year|calendar\s*year)\b/i,ut=/^(?:(?:19|20)\d{2}(?:[-/ ]?(?:q[1-4]|w(?:0?[1-9]|[1-4]\d|5[0-3])|(?:0?[1-9]|1[0-2])))?|q[1-4][-/ ](?:19|20)\d{2}|(?:jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)[a-z]*[-/ ]?(?:19|20)?\d{2})$/i;function W(p){if(!Number.isInteger(p)||p<190001||p>210012)return!1;let e=p%100;return e>=1&&e<=12}function P(p){if(!Number.isInteger(p)||p<19000101||p>21001231)return!1;let e=Math.floor(p/100)%100,o=p%100;return e>=1&&e<=12&&o>=1&&o<=31}function lt(p,e){if(!e||!/\b(?:19|20)\d{2}\b/.test(p))return!1;let o=p.replace(/\b(?:19|20)\d{2}\b/g,"").replace(/[-/.,]/g," ").trim();if(!o)return!1;let c=j(o);return c.length>0&&e[c]!==void 0}function ct(p){let{dataType:e,name:o,isMeasure:c,distinctCount:f}=p;if(e==="DateTime")return!0;if(c)return!1;if(e==="Integer"||e==="Decimal"){let n=p.minNum,b=p.maxNum;if(!(n!=null&&b!=null&&Number.isFinite(n)&&Number.isFinite(b)&&Number.isInteger(n)&&Number.isInteger(b)&&b>=n))return!1;let T=n>=1900&&b<=2100;if(T&&f>=2&&ot.test(o)||T&&f>=3&&f===b-n+1)return!0;let M=W(n)&&W(b),D=P(n)&&P(b);if(M||D){if(!p.sampleValues)return!0;let h=0,N=0;for(let l of p.sampleValues){if(l==null||l==="")continue;h++;let t=Number(String(l).trim());if(Number.isFinite(t)&&(M?W(t):P(t))&&N++,h>=60)break}if(h>=2&&N===h)return!0}return!1}if(p.sampleValues){let n=p.locale?q(p.locale):null,b=0,I=0;for(let T of p.sampleValues){if(T==null||T==="")continue;b++;let M=String(T).trim();if((ut.test(M)||lt(M,n))&&I++,b>=60)break}if(b>=2&&I/b>=.8)return!0}return!1}function mt(p){let e=(p||"").trim().toLowerCase();return e.startsWith("sum ")||e.startsWith("total ")?"sum":e.startsWith("average ")||e.startsWith("avg. ")?"avg":e.startsWith("count ")||e.startsWith("distinct count ")||e.startsWith("count (distinct) ")?"count":e.startsWith("min ")||e.startsWith("minimum ")?"min":e.startsWith("max ")||e.startsWith("maximum ")?"max":null}function ft(p){let{rows:e,measureColIdx:o,measureName:c,candidateDims:f,minNum:n,maxNum:b,discourageAgg:I}=p,T=100,M=.01,D="";for(let N of f){if(N.distinct<2||N.distinct>T)continue;let l=f.filter(i=>i.idx!==N.idx).map(i=>i.idx),t=new Map;for(let i of e){let u=i[o];if(typeof u!="number"||!Number.isFinite(u))continue;let d=l.length?l.map(y=>String(i[y])).join(D):"",g=t.get(d);g||(g={sum:0,cset:new Set},t.set(d,g)),g.sum+=u,g.cset.add(String(i[N.idx]))}let r=0,a=0,s=0;for(let i of t.values())i.cset.size<2||(s++,Math.abs(i.sum-100)<=100*M?r++:Math.abs(i.sum-1)<=1*M&&a++);if(s>=2&&(r/s>=.9||a/s>=.9))return{additivity:"part_of_whole",partOfWholeDim:N.name}}if(I)return{additivity:"intensive_rate"};let h=mt(c);return h==="avg"||h==="min"||h==="max"?{additivity:"intensive_rate"}:h==="sum"||h==="count"?{additivity:"additive"}:n!=null&&b!=null&&Number.isFinite(n)&&Number.isFinite(b)&&n>=0&&b<=1.0001&&b>0?{additivity:"intensive_rate"}:{additivity:"unknown"}}function B(p){let{dataType:e,isMeasure:o,name:c,distinct:f,nonblank:n,prec:b,maxval:I,minval:T}=p,M=I-T+1,D=M>0?f/M:1,h=n>0?f/n:0,N=e==="Decimal"||b>0;return at(c)?"Categorical":D>=Q&&(z(c)&&f<=tt||T>=et&&I<=nt||T>=it&&I<=st)?"Ordinal":o||f>Z&&(N||f>=$||h>=J)?"Continuous":"Categorical"}var K=class{_computedStatsForLevel=null;_cols=[];_rows=[];_origIndices=[];_rowHashes=new Set;dedupRows=!0;STR(e){return e==null?"":e.toString()}getPrecision(e){if(!isFinite(e))return 0;let c=e.toString().split(".")[1];return c?c.length:0}getColumns(){return this._cols}hasTimeComponent(e){return!(e instanceof Date)||isNaN(e.getTime())?!1:e.getHours()!==0||e.getMinutes()!==0||e.getSeconds()!==0||e.getMilliseconds()!==0}getColumnsWithStats(e,o){if(this._computedStatsForLevel==e)return this._cols;let c=0,f=parseInt(e),n=[];for(let t of this._cols){let r=new Map,a=[],s=0,i=0,u=0,d=null,g=null,y=null,w=!1,R=!0,A=!0,v=null,S=!1;for(let C of this._rows){let m=C[c],_=this.STR(m);if(_!=""){if(s+=_.length,r.set(_,(r.get(_)||0)+1),i++,t.dataType=="Integer"||t.dataType=="Decimal"||t.dataType=="DateTime")if((d===null||m<d)&&(d=m),(g===null||m>g)&&(g=m),t.dataType=="Integer"||t.dataType=="Decimal"){if(y===null?y=m:y+=m,t.dataType=="Decimal"){let L=this.getPrecision(m);L>u&&(u=L)}a.push(m)}else w=w||this.hasTimeComponent(m);S&&(m<v?R=!1:m>v&&(A=!1)),v=m,S=!0}}if(i>=3&&(R&&!A?t.sortedDirection="asc":A&&!R?t.sortedDirection="desc":t.sortedDirection="none"),i>0&&r.size>0&&!t.isMeasure){let C=0,m=Number.MAX_SAFE_INTEGER;for(let _ of r.values())_>C&&(C=_),_<m&&(m=_);if(t.modalShare=C/i,t.minGroupCount=m===Number.MAX_SAFE_INTEGER?null:m,r.size===2){let _=[...r.keys()].map(V=>Y(V).trim().toLowerCase()).sort(),E=[["false","true"],["no","yes"],["n","y"],["0","1"],["f","t"]].some(V=>_[0]===V[0]&&_[1]===V[1]),O=/^(is|has)[_a-z0-9]|(?:default|churn|fraud|approv|convert|active|cancel|delinquen|flag|paid|win|pass|fail)/i.test(t.name);(E||O)&&(t.isBinaryFlag=!0)}}t.dataType=="DateTime"&&(t.dateWithTime=w),t.isTemporal=ct({dataType:t.dataType,name:t.name,isMeasure:t.isMeasure,distinctCount:r.size,minNum:typeof d=="number"?d:null,maxNum:typeof g=="number"?g:null,sampleValues:r.keys(),locale:o}),this.updateColumnStats10(f,t,i,r,u,g,d),this.updateColumnStats20(f,a,i,y,t,s,w,d,g,u,r,o),!t.isMeasure&&(t.dataType==="Integer"||t.dataType==="Decimal")&&B({dataType:t.dataType,isMeasure:!1,name:t.name,distinct:r.size,nonblank:i,prec:u,maxval:typeof g=="number"?g:0,minval:typeof d=="number"?d:0})==="Continuous"&&(t.isMeasure=!0),n[c]=t.isMeasure||r.size>2e3?null:new Set(r.keys()),c++}let b=[];this._cols.forEach((t,r)=>{t.isMeasure||b.push({idx:r,distinct:t.distinctCount??0,name:t.name})}),this._cols.forEach((t,r)=>{if(!t.isMeasure)return;let a=typeof t.lowValue=="number"?t.lowValue:null,s=typeof t.highValue=="number"?t.highValue:null,i=ft({rows:this._rows,measureColIdx:r,measureName:t.name,candidateDims:b,minNum:a,maxNum:s,discourageAgg:!!t.discourageAggregationAcrossGroups});t.additivity=i.additivity,i.partOfWholeDim&&(t.partOfWholeDim=i.partOfWholeDim)});let I=50,T=b.filter(t=>t.distinct>=2&&t.distinct<=I);this._cols.forEach((t,r)=>{if(!t.isMeasure)return;let a=[];for(let v of this._rows){let S=v[r];if(S==null||S==="")continue;let C=typeof S=="number"?S:parseFloat(S);isNaN(C)||a.push(C)}if(a.length===0)return;let s=[...a].sort((v,S)=>v-S),i=v=>s[Math.min(s.length-1,Math.max(0,Math.floor(v*(s.length-1))))],u=i(.5),d=i(.1),g=i(.9),y=Math.abs(u)>1e-9?Math.abs(u):Math.abs(s[s.length-1])>1e-9?Math.abs(s[s.length-1]):1;t.relativeDispersion=Math.round((g-d)/y*1e3)/1e3;let w=0;for(let v of a)w+=v;w/=a.length;let R=0;for(let v of a)R+=(v-w)*(v-w);if(R<=1e-12)return;let A=[];for(let v of T){let S=new Map;for(let m of this._rows){let _=m[r];if(_==null||_==="")continue;let L=typeof _=="number"?_:parseFloat(_);if(isNaN(L))continue;let E=this.STR(m[v.idx])+"",O=S.get(E);O?(O.s+=L,O.n++):S.set(E,{s:L,n:1})}let C=0;for(let m of S.values()){let _=m.s/m.n;C+=m.n*(_-w)*(_-w)}A.push({otherColumn:v.name,eta2:Math.round(C/R*1e4)/1e4})}A.length>0&&(t.groupDiscrimination=A)});let M=.97,D=5,h=this._cols.map((t,r)=>({c:t,i:r})).filter(t=>t.c.isMeasure);for(let t=0;t<h.length;t++)for(let r=t+1;r<h.length;r++){let a=h[t].i,s=h[r].i,i=0,u=0,d=0,g=0,y=0,w=0;for(let S of this._rows){let C=S[a],m=S[s];if(C==null||C===""||m===null||m===void 0||m==="")continue;let _=typeof C=="number"?C:parseFloat(C),L=typeof m=="number"?m:parseFloat(m);isNaN(_)||isNaN(L)||(i++,u+=_,d+=L,g+=_*_,y+=L*L,w+=_*L)}if(i<D)continue;let R=i*g-u*u,A=i*y-d*d;if(R<=1e-12||A<=1e-12)continue;let v=(i*w-u*d)/Math.sqrt(R*A);if(Math.abs(v)>=M){let S=h[t].c,C=h[r].c;S.collinearWithMeasures||(S.collinearWithMeasures=[]),C.collinearWithMeasures||(C.collinearWithMeasures=[]),S.collinearWithMeasures.push(C.name),C.collinearWithMeasures.push(S.name)}}for(let t=0;t<this._cols.length;t++){let r=n[t];if(!r||r.size===0)continue;let a=[];for(let s=0;s<this._cols.length;s++){if(s===t)continue;let i=n[s];if(!i||i.size===0)continue;let u=0;for(let g of r)i.has(g)&&u++;let d=Math.round(u/r.size*100);d>0&&a.push({otherColumn:this._cols[s].name,percentShared:d})}a.length>0&&(this._cols[t].sharedValueRatioWithOthers=a)}let N=50,l=[];for(let t=0;t<this._cols.length;t++){let r=n[t];r&&r.size>=2&&r.size<=N&&l.push(t)}if(l.length>=2){let t=new Map,r=(s,i)=>s+":"+i;for(let s=0;s<l.length;s++)for(let i=s+1;i<l.length;i++)t.set(r(l[s],l[i]),new Map);for(let s of this._rows)for(let i=0;i<l.length;i++){let u=this.STR(s[l[i]])+"";for(let d=i+1;d<l.length;d++){let g=""+this.STR(s[l[d]]),y=t.get(r(l[i],l[d])),w=u+""+g;y.set(w,(y.get(w)??0)+1)}}let a=new Map;for(let s=0;s<l.length;s++)for(let i=s+1;i<l.length;i++){let u=l[s],d=l[i],g=n[u].size,y=n[d].size,w=t.get(r(u,d)),R=w.size,A=0;for(let m of w.values())(A===0||m<A)&&(A=m);let v=Math.round(R/(g*y)*100),S=R===g,C=R===y;if((this._cols[u].categoricalPairStats||=[]).push({otherColumn:this._cols[d].name,fillPct:v,determinesOther:S,minCellCount:A,distinctCombinations:R}),(this._cols[d].categoricalPairStats||=[]).push({otherColumn:this._cols[u].name,fillPct:v,determinesOther:C,minCellCount:A,distinctCombinations:R}),S&&g>y){let m=a.get(u);(!m||y<m.card)&&a.set(u,{name:this._cols[d].name,card:y,ratio:y/g})}if(C&&y>g){let m=a.get(d);(!m||g<m.card)&&a.set(d,{name:this._cols[u].name,card:g,ratio:g/y})}}for(let[s,i]of a)this._cols[s].primaryParentColumn=i.name,this._cols[s].nestingRatio=Math.round(i.ratio*100)/100}return this._computedStatsForLevel=e,this._cols}updateColumnStats20(e,o,c,f,n,b,I,T,M,D,h,N){if(e>=20){let l=[...o].sort((a,s)=>a-s),t=Math.floor(l.length/2);if(c>0&&f!=null?n.avgValue=n.dataType=="Integer"?Math.round(f/c):f/c:n.avgValue=null,c>0&&(n.avgLength=b/c),this._rows.length>0&&(n.dataType!="DateTime"||I||!T?n.lowValue=T:n.lowValue=new Date(T).toISOString().slice(0,10)+"T00:00:00.000Z",n.dataType!="DateTime"||I||!M?n.highValue=M:n.highValue=new Date(M).toISOString().slice(0,10)+"T00:00:00.000Z",n.medianValue=l.length===0?null:l.length%2===0?n.dataType=="Integer"?Math.round((l[t-1]+l[t])/2):(l[t-1]+l[t])/2:l[t],n.numericPrecision=D),l.length>0){let a=n.avgValue??0,s=l.length,i=0,u=0;for(let g of l){let y=g-a;i+=y*y,u+=y*y*y}let d=i/s;n.skewness=d===0?0:u/s/Math.pow(Math.sqrt(d),3),n.stdDev=Math.sqrt(d)}f!==null&&(n.sum=f);let r=Array.from(h.entries()).sort((a,s)=>s[1]-a[1]);if(n.topCategories=r.slice(0,10).map(a=>a[1]),!n.isMeasure&&r.length>0){if(n.dataType==="String"){let s=r.map(u=>u[0]);n.formatSignature=H(s);let i=/^(UUID|EMAIL_LIKE|URL_LIKE|PHONE_LIKE|NUMERIC_ID|HEX_ID|OPAQUE_ID_ALPHANUMERIC|DATE_STR|BOOLEAN)$/;n.formatSignature&&!i.test(n.formatSignature)&&(n.avgLength===void 0||n.avgLength>=3)&&(n.isFreeText=!0)}else n.topCategoryValues=r.slice(0,5).map(s=>s[0]);if(e>=20){let s=r.map(u=>u[0]),i=k(s,N);if(i!==null)n.ordinalPattern=i.pattern,n.orderedDomain=i.orderedDomain;else if(n.dataType==="String"){let u=F(s);u!==null&&(n.safeDistinctValues=u)}}let a=U(r.map(s=>s[0]),n.name,N);a!==null&&(n.geoKind=a.geoKind,n.geoMatchPct=a.geoMatchPct,a.geoAmbiguous&&(n.geoAmbiguous=!0))}if(l.length>=8&&(n.dataType==="Integer"||n.dataType==="Decimal")){let a=s=>l[Math.floor((l.length-1)*s)];n.quantiles={p05:a(.05),p25:a(.25),p75:a(.75),p95:a(.95)}}}}updateColumnStats10(e,o,c,f,n,b,I){e>=10&&(o.blankCount=this._rows.length-c,o.distinctCount=f.size+(o.blankCount!=0?1:0),o.valueNature="Categorical",c>0&&(o.dataType==="Integer"||o.dataType==="Decimal"?o.valueNature=B({dataType:o.dataType,isMeasure:!!o.isMeasure,name:o.name,distinct:f.size,nonblank:c,prec:n,maxval:b,minval:I}):o.dataType==="DateTime"&&(o.valueNature=o.dateWithTime?"Continuous":"Ordinal")))}getRowCount(){return this._rows.length}getLeafCardinality(){if(this._leafCardinality!==null)return this._leafCardinality;let e=[];if(this._cols.forEach((c,f)=>{c.isMeasure||e.push(f)}),e.length===0)return this._leafCardinality=this._rows.length,this._leafCardinality;let o=new Set;for(let c of this._rows)o.add(JSON.stringify(e.map(f=>c[f])));return this._leafCardinality=o.size,this._leafCardinality}_leafCardinality=null;obfuscateString(e){let o="abcdefghijklmnopqrstuvwxyz",c=()=>o[Math.floor(x()*o.length)],f=()=>c().toUpperCase(),n=()=>Math.floor(x()*10).toString(),b=t=>/[A-Z]/.test(t)?f():/[a-z]/.test(t)?c():/[0-9]/.test(t)?n():t,I=e.includes("@")&&e.includes("."),T=I?e.split("@"):[e],M=I?T[1]:"",D=M.endsWith(".com"),h=D?".com":"",N=D?M.slice(0,-4):M,l=t=>{let r="";for(let a of t)r+=b(a),/[a-zA-Z0-9]/.test(a)&&x()<.2&&(r+=b(a));if(r.length>6){let a=Math.floor(x()*Math.min(3,r.length-6));for(let s=0;s<a;s++){let i=0;for(;i<5;){let u=Math.floor(x()*r.length);if(/[a-zA-Z0-9]/.test(r[u])){r=r.slice(0,u)+r.slice(u+1);break}i++}}}return r};if(I){let t=l(T[0]),r=l(N);return`${t}@${r}${h}`}else return l(e)}toObjectArray(){return this._rows.map(e=>{let o={};return this._cols.forEach((c,f)=>{o[c.name]=e[f]}),o})}async getCSVAsync(e){let o=[],c=e?25:1e7,f=e?4e3:1e7,n=new Map;for(let I of this._rows){let T={};for(let M=0;M<this._cols.length;M++){let D=this._cols[M],h=I[M];if(this.STR(h)!=""){if(e&&D.dataType=="String")if(n.has(h))h=n.get(h);else{let N=this.obfuscateString(h);n.set(h,N),h=N}else D.dataType=="DateTime"&&!D.dateWithTime&&(h=new Date(h).toISOString().slice(0,10)+"T00:00:00.000Z");f-=this.STR(h).length}else h=null;T[M]=h,--f}if(o.push(T),--c,c<=0||f<=0)break}return await X.unparse(o,{header:!1})}getCSVHeaderLine(){return X.unparse([this._cols.map(e=>this.STR(e.name))])}addRow(e,o){if(this.dedupRows){let c="";for(let n of e)c+=this.STR(n)+"~";let f=G(c);if(this._rowHashes.has(f))return!1;this._rowHashes.add(f)}return this._rows.push(e),this._origIndices.push(o??-1),!0}getOriginalRowIndex(e){return e<0||e>=this._origIndices.length?-1:this._origIndices[e]}reset(){this._cols=[],this._rows=[],this._origIndices=[],this._rowHashes=new Set,this._leafCardinality=null}setColumns(e){this._cols=e}};export{at as a,ct as b,mt as c,ft as d,B as e,K as f};
@@ -1,2 +1,2 @@
1
1
  /*! @bicharts/shape-core — Apache-2.0. Bundled reference data: GeoNames (https://www.geonames.org/) CC BY 4.0; US Census/TIGER (public domain). Full text: NOTICE in this package. */
2
- import{a,b,c,d}from"./chunk-3MIEXLB3.mjs";import"./chunk-4VVLBWCU.mjs";export{d as buildGeoIsoColumn,a as detectGeo,c as isJoinGeoKind,b as toGeoIso};
2
+ import{a,b,c,d}from"./chunk-IFOJMDYY.mjs";import"./chunk-Y27QIEOE.mjs";export{d as buildGeoIsoColumn,a as detectGeo,c as isJoinGeoKind,b as toGeoIso};
package/dist/geoPoint.mjs CHANGED
@@ -1,2 +1,2 @@
1
1
  /*! @bicharts/shape-core — Apache-2.0. Bundled reference data: GeoNames (https://www.geonames.org/) CC BY 4.0; US Census/TIGER (public domain). Full text: NOTICE in this package. */
2
- import{a,b,c,d,e,f,g,h,i}from"./chunk-4VVLBWCU.mjs";export{g as buildGeoPointColumns,i as cityMatchPct,h as isKnownCity,c as normalizeCountry,a as normalizePlaceName,b as resolveAdmin1,f as resolveGeoPoint,e as zipPrefixCandidates,d as zipToPrefix3};
2
+ import{a,f as b,g as c,h as d,i as e,j as f,k as g,l as h,m as i,n as j}from"./chunk-Y27QIEOE.mjs";export{h as buildGeoPointColumns,j as cityMatchPct,f as isGeoPointAmbiguity,i as isKnownCity,c as normalizeCountry,a as normalizePlaceName,b as resolveAdmin1,g as resolveGeoPoint,e as zipPrefixCandidates,d as zipToPrefix3};
package/dist/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
1
  /*! @bicharts/shape-core — Apache-2.0. Bundled reference data: GeoNames (https://www.geonames.org/) CC BY 4.0; US Census/TIGER (public domain). Full text: NOTICE in this package. */
2
- import{a as ot,b as it}from"./chunk-ZJG5W5TQ.mjs";import{a as U,b as X,c as Y,d as tt,e as nt,f as et}from"./chunk-4BZ64MHR.mjs";import{a as W,b as Z}from"./chunk-2LR73DNS.mjs";import{a as j,b as J,c as Q}from"./chunk-NWDPA7DG.mjs";import{a as q,b as E,c as F,d as K}from"./chunk-3MIEXLB3.mjs";import{a as v,b as f,c as _,d as $,e as h,f as O,g as H,h as R,i as B}from"./chunk-4VVLBWCU.mjs";import{a as G,b as N,c as D}from"./chunk-WBEROMBG.mjs";import{a as V}from"./chunk-QEH7WTLB.mjs";var b=85,S=2,st=100,L=400,T=new Set(["us","usa","u s","u s a","united states","united states of america","america","ca","can","canada","mx","mex","mexico","estados unidos mexicanos"]);function m(i){let n=new Set;for(let e of i){if(e==null)continue;let o=v(String(e));if(o&&!n.has(o)&&(n.add(o),n.size>=L))break}return Array.from(n)}function P(i){let n=m(i);return n.length===0||!n.every(e=>T.has(e))?!1:n.some(e=>!f(e))}function A(i){return T.has(i)&&!!f(i)}function x(i){let n=m(i);if(n.length===0)return 0;let e=0;for(let o of n)f(o)&&e++;return Math.round(e/n.length*1e3)/10}function I(i){let n=new Set;for(let e of i){if(e==null)continue;let o=String(e).trim();if(o&&!n.has(o)&&(n.add(o),n.size>=L))break}return Array.from(n)}function w(i){let n=I(i);if(n.length===0)return 0;let e=0;for(let o of n)h(o).length>0&&e++;return Math.round(e/n.length*1e3)/10}function rt(i){let n=m(i);if(n.length===0)return 0;let e=0;for(let o of n)R(o)&&e++;return Math.round(e/n.length*1e3)/10}function M(i,n){let e=0;for(let o of m(i))n(o)&&e++;return e}function at(i,n){let e=0;for(let o of I(i))n(o)&&e++;return e}function ct(i,n,e){let o=[],p=[],s={},k=new Set(i),d=t=>n.map(r=>r[t]);for(let t of["city","zip","lat","lon","country"]){let r=e?.[t];r&&k.has(r)&&(s[t]=r)}let u=e?.state;if(u&&k.has(u)){let t=d(u),r=m(t);r.length>0&&r.every(A)?p.push(`state=${u} (every value is "CA", which is both Canada and California)`):P(t)?(p.push(`state=${u} (every value is a country, not a state)`),s.country||(s.country=u)):x(t)<b?p.push(`state=${u} (only ${x(t)}% of values are states/provinces)`):s.state=u}let l=new Set(Object.values(s).filter(Boolean)),y=i.filter(t=>!l.has(t)&&!t.startsWith("__"));if(!s.state){let t=null;for(let r of y){let a=d(r);if(P(a))continue;let c=x(a);if(c<b)continue;let C=M(a,g=>!!f(g)),z=M(a,g=>!!f(g)&&!A(g));C<S&&z<1||(!t||c>t.pct)&&(t={name:r,pct:c})}t&&(s.state=t.name,l.add(t.name),o.push(`state=${t.name} (${t.pct}% states/provinces)`))}if(!s.zip)for(let t of y){if(l.has(t))continue;let r=d(t),a=w(r);if(!(a<st)&&!(at(r,c=>h(c).length>0)<S)){s.zip=t,l.add(t),o.push(`zip=${t} (${a}% ZIP codes)`);break}}if(!s.country){for(let t of y)if(!l.has(t)&&P(d(t))){s.country=t,l.add(t),o.push(`country=${t}`);break}}if(!s.city){let t=null;for(let r of y){if(l.has(r))continue;let a=d(r),c=rt(a);c<b||M(a,C=>R(C))<S||(!t||c>t.pct)&&(t={name:r,pct:c})}t&&(s.city=t.name,o.push(`city=${t.name} (${t.pct}% known cities)`))}return{bind:!!(s.city||s.state||s.zip||s.lat&&s.lon)?s:null,backfilled:o,refused:p}}export{Q as GET_RANDOM,et as IndexedText,J as SIMPLE_STRING_HASH,j as STR,x as admin1MatchPct,K as buildGeoIsoColumn,H as buildGeoPointColumns,B as cityMatchPct,tt as classifyAdditivity,nt as classifyNumericValueNature,X as classifyTemporal,V as detectFormatSignature,q as detectGeo,D as detectOrdinalDomain,ot as engineTypeForSqlType,Y as hostAggHint,it as ingest,U as isIdentifierName,F as isJoinGeoKind,G as isOrdinalFriendlyName,P as looksLikeCountryColumn,Z as monthLookupFor,_ as normalizeCountry,W as normalizeMonthKey,v as normalizePlaceName,f as resolveAdmin1,O as resolveGeoPoint,ct as resolvePointRoles,N as safeDistinctValuesToShip,E as toGeoIso,w as zipMatchPct,h as zipPrefixCandidates,$ as zipToPrefix3};
2
+ import{a as st,b as rt}from"./chunk-42L7OPVY.mjs";import{a as Y,b as tt,c as nt,d as et,e as ot,f as it}from"./chunk-ZOJW2P2V.mjs";import{a as j,b as J}from"./chunk-2LR73DNS.mjs";import{a as Q,b as U,c as X}from"./chunk-NWDPA7DG.mjs";import{a as E,b as F,c as V,d as W}from"./chunk-IFOJMDYY.mjs";import{a as b,f as d,g as $,h as O,i as P,j as H,k as K,l as B,m as R,n as q}from"./chunk-Y27QIEOE.mjs";import{a as N,b as D,c as _}from"./chunk-WBEROMBG.mjs";import{a as Z}from"./chunk-QEH7WTLB.mjs";var M=85,S=2,at=100,L=400,T=new Set(["us","usa","u s","u s a","united states","united states of america","america","ca","can","canada","mx","mex","mexico","estados unidos mexicanos"]);function p(o){let e=new Set;for(let n of o){if(n==null)continue;let i=b(String(n));if(i&&!e.has(i)&&(e.add(i),e.size>=L))break}return Array.from(e)}function x(o){let e=p(o);return e.length===0||!e.every(n=>T.has(n))?!1:e.some(n=>!d(n))}function G(o){return T.has(o)&&!!d(o)}function C(o){let e=p(o);if(e.length===0)return 0;let n=0;for(let i of e)d(i)&&n++;return Math.round(n/e.length*1e3)/10}function I(o){let e=new Set;for(let n of o){if(n==null)continue;let i=String(n).trim();if(i&&!e.has(i)&&(e.add(i),e.size>=L))break}return Array.from(e)}function w(o){let e=I(o);if(e.length===0)return 0;let n=0;for(let i of e)P(i).length>0&&n++;return Math.round(n/e.length*1e3)/10}function ct(o,e){let n=p(o);if(n.length===0)return 0;let i=0;for(let l of n)R(l,e)&&i++;return Math.round(i/n.length*1e3)/10}function A(o,e){let n=0;for(let i of p(o))e(i)&&n++;return n}function ut(o,e){let n=0;for(let i of I(o))e(i)&&n++;return n}function lt(o,e,n,i){let l=[],y=[],s={},k=new Set(o),m=t=>e.map(r=>r[t]);for(let t of["city","zip","lat","lon","country"]){let r=n?.[t];r&&k.has(r)&&(s[t]=r)}let u=n?.state;if(u&&k.has(u)){let t=m(u),r=p(t);r.length>0&&r.every(G)?y.push(`state=${u} (every value is "CA", which is both Canada and California)`):x(t)?(y.push(`state=${u} (every value is a country, not a state)`),s.country||(s.country=u)):C(t)<M?y.push(`state=${u} (only ${C(t)}% of values are states/provinces)`):s.state=u}let f=new Set(Object.values(s).filter(Boolean)),g=o.filter(t=>!f.has(t)&&!t.startsWith("__"));if(!s.state){let t=null;for(let r of g){let a=m(r);if(x(a))continue;let c=C(a);if(c<M)continue;let v=A(a,h=>!!d(h)),z=A(a,h=>!!d(h)&&!G(h));v<S&&z<1||(!t||c>t.pct)&&(t={name:r,pct:c})}t&&(s.state=t.name,f.add(t.name),l.push(`state=${t.name} (${t.pct}% states/provinces)`))}if(!s.zip)for(let t of g){if(f.has(t))continue;let r=m(t),a=w(r);if(!(a<at)&&!(ut(r,c=>P(c).length>0)<S)){s.zip=t,f.add(t),l.push(`zip=${t} (${a}% ZIP codes)`);break}}if(!s.country){for(let t of g)if(!f.has(t)&&x(m(t))){s.country=t,f.add(t),l.push(`country=${t}`);break}}if(!s.city){let t=null;for(let r of g){if(f.has(r))continue;let a=m(r),c=ct(a,i);c<M||A(a,v=>R(v,i))<S||(!t||c>t.pct)&&(t={name:r,pct:c})}t&&(s.city=t.name,l.push(`city=${t.name} (${t.pct}% known cities)`))}return{bind:!!(s.city||s.state||s.zip||s.lat&&s.lon)?s:null,backfilled:l,refused:y}}export{X as GET_RANDOM,it as IndexedText,U as SIMPLE_STRING_HASH,Q as STR,C as admin1MatchPct,W as buildGeoIsoColumn,B as buildGeoPointColumns,q as cityMatchPct,et as classifyAdditivity,ot as classifyNumericValueNature,tt as classifyTemporal,Z as detectFormatSignature,E as detectGeo,_ as detectOrdinalDomain,st as engineTypeForSqlType,nt as hostAggHint,rt as ingest,H as isGeoPointAmbiguity,Y as isIdentifierName,V as isJoinGeoKind,N as isOrdinalFriendlyName,x as looksLikeCountryColumn,J as monthLookupFor,$ as normalizeCountry,j as normalizeMonthKey,b as normalizePlaceName,d as resolveAdmin1,K as resolveGeoPoint,lt as resolvePointRoles,D as safeDistinctValuesToShip,F as toGeoIso,w as zipMatchPct,P as zipPrefixCandidates,O as zipToPrefix3};
@@ -1,2 +1,2 @@
1
1
  /*! @bicharts/shape-core — Apache-2.0. Bundled reference data: GeoNames (https://www.geonames.org/) CC BY 4.0; US Census/TIGER (public domain). Full text: NOTICE in this package. */
2
- import{a,b,c,d,e,f}from"./chunk-4BZ64MHR.mjs";import"./chunk-2LR73DNS.mjs";import"./chunk-NWDPA7DG.mjs";import"./chunk-3MIEXLB3.mjs";import"./chunk-4VVLBWCU.mjs";import"./chunk-WBEROMBG.mjs";import"./chunk-QEH7WTLB.mjs";export{f as IndexedText,d as classifyAdditivity,e as classifyNumericValueNature,b as classifyTemporal,c as hostAggHint,a as isIdentifierName};
2
+ import{a,b,c,d,e,f}from"./chunk-ZOJW2P2V.mjs";import"./chunk-2LR73DNS.mjs";import"./chunk-NWDPA7DG.mjs";import"./chunk-IFOJMDYY.mjs";import"./chunk-Y27QIEOE.mjs";import"./chunk-WBEROMBG.mjs";import"./chunk-QEH7WTLB.mjs";export{f as IndexedText,d as classifyAdditivity,e as classifyNumericValueNature,b as classifyTemporal,c as hostAggHint,a as isIdentifierName};
package/dist/ingest.mjs CHANGED
@@ -1,2 +1,2 @@
1
1
  /*! @bicharts/shape-core — Apache-2.0. Bundled reference data: GeoNames (https://www.geonames.org/) CC BY 4.0; US Census/TIGER (public domain). Full text: NOTICE in this package. */
2
- import{a,b}from"./chunk-ZJG5W5TQ.mjs";import"./chunk-4BZ64MHR.mjs";import"./chunk-2LR73DNS.mjs";import"./chunk-NWDPA7DG.mjs";import"./chunk-3MIEXLB3.mjs";import"./chunk-4VVLBWCU.mjs";import"./chunk-WBEROMBG.mjs";import"./chunk-QEH7WTLB.mjs";export{a as engineTypeForSqlType,b as ingest};
2
+ import{a,b}from"./chunk-42L7OPVY.mjs";import"./chunk-ZOJW2P2V.mjs";import"./chunk-2LR73DNS.mjs";import"./chunk-NWDPA7DG.mjs";import"./chunk-IFOJMDYY.mjs";import"./chunk-Y27QIEOE.mjs";import"./chunk-WBEROMBG.mjs";import"./chunk-QEH7WTLB.mjs";export{a as engineTypeForSqlType,b as ingest};
@@ -0,0 +1,21 @@
1
+ export declare function normalizePlaceName(s: string): string;
2
+ export declare const ISO_3166_PAIRS: string;
3
+ export declare const ISO2_TO_ISO3: Map<string, string>;
4
+ export declare const ISO2_SET: Set<string>;
5
+ export declare const ISO3_SET: Set<string>;
6
+ export declare const SUPPORTED_LANGS: string[];
7
+ export declare const COUNTRY_ALIAS_OVERLAY: Record<string, string>;
8
+ export declare function countryNameMap(): Map<string, string>;
9
+ /** ISO-2 -> ISO-3 ("CA" -> "CAN"). Null when the code is not assigned. */
10
+ export declare function iso2ToIso3(a2: string): string | null;
11
+ /**
12
+ * Resolve ANY country identifier to ISO-3: a name in any of the 27 supported
13
+ * languages, an ISO-2 code, an ISO-3 code, or an overlay alias ("USA", "UK",
14
+ * "Holland"). Null when it is not a country.
15
+ *
16
+ * This is the WORLD-wide resolver, and it is deliberately NOT the same thing as
17
+ * geoPoint.normalizeCountry — that one stays narrow (US/CA/MX, 2-letter) because it
18
+ * feeds city-tier narrowing and its published contract is depended on. See the note
19
+ * beside it.
20
+ */
21
+ export declare function countryIso3(value: string | null | undefined): string | null;
@@ -1,12 +1,19 @@
1
- export type GeoPointPrecision = "latlon" | "city" | "zip3" | "state";
1
+ export type GeoPointPrecision = "latlon" | "city" | "zip3" | "state" | "country";
2
2
  export type GeoPointResult = {
3
3
  lat: number;
4
4
  lon: number;
5
5
  precision: GeoPointPrecision;
6
- /** The city name was ambiguous and the largest match was chosen. */
6
+ /** NO LONGER PRODUCED (v2 matching, 2026-08-02): an ambiguous name is refused and
7
+ * reported (see GeoPointAmbiguity), never placed by a tie-break. The field stays so
8
+ * older compiled consumers reading it keep type-checking; it is always absent. */
7
9
  ambiguous?: boolean;
8
10
  };
9
- export declare function normalizePlaceName(s: string): string;
11
+ export { normalizePlaceName } from "./geoCountryNames";
12
+ /** Which point-map's candidate set a lookup runs against. Rows carry kind flags
13
+ * (N = North America map, W = World map; a row may carry both), so ONE table serves
14
+ * every map type with the map deciding its own scope — Joel 2026-08-02: "one row can
15
+ * apply to 1 or more map types", and the matching rules are COMMON logic. */
16
+ export type GeoMapKind = "north-america" | "world";
10
17
  /** Resolve a state/province token ("TX", "Texas", "ON", "Ontario", "Jalisco") to its
11
18
  * canonical admin1 key. Null when unrecognized. */
12
19
  export declare function resolveAdmin1(value: string | null | undefined): string | null;
@@ -37,18 +44,30 @@ export declare function zipPrefixCandidates(value: string | null | undefined): s
37
44
  * Order is deliberate: an explicit coordinate always beats a lookup; a city beats a ZIP
38
45
  * prefix (a city is a point, a ZIP-3 is a region); a ZIP prefix beats a whole state.
39
46
  */
47
+ /** The city tier found MORE THAN ONE place the source row could mean, after every
48
+ * non-blank source attribute was honoured. The row is NOT plotted and the caller
49
+ * reports it as info — since v2 (Joel 2026-08-02) a guess is never made: "if multiple
50
+ * possible matches are found, that should be a call-out … and it should not be
51
+ * plotted." Distinct from `null` (nothing matched at all): coarser tiers must NOT
52
+ * rescue an ambiguity, because the coarser placement would silently pick a side. */
53
+ export type GeoPointAmbiguity = {
54
+ ambiguous: true;
55
+ matches: number;
56
+ };
57
+ export declare function isGeoPointAmbiguity(r: GeoPointResult | GeoPointAmbiguity | null | undefined): r is GeoPointAmbiguity;
40
58
  export declare function resolveGeoPoint(args: {
41
59
  lat?: number | string | null;
42
60
  lon?: number | string | null;
43
61
  city?: string | null;
44
62
  state?: string | null;
45
63
  zip?: string | null;
46
- /** Optional COUNTRY narrowing. When supplied and recognized, a city name is only
47
- * matched against cities in that country, and a state that belongs to a different
48
- * country is not trusted. Absent/unrecognized = the cascade behaves exactly as it
49
- * did before, so this can never make a currently-correct map worse. */
64
+ /** COUNTRY: a matching constraint like state, and since the country tier — also a
65
+ * placement of last resort. Absent = unconstrained. */
50
66
  country?: string | null;
51
- }): GeoPointResult | null;
67
+ /** Which map's candidate rows the CITY tier may use (default "north-america", which
68
+ * is byte-identical to the pre-v2 candidate set). The WORLD map passes "world". */
69
+ mapKind?: GeoMapKind | null;
70
+ }): GeoPointResult | GeoPointAmbiguity | null;
52
71
  export type GeoPointColumns = {
53
72
  /** Per-row coordinates, aligned 1:1 with the input; null where unresolved. */
54
73
  lat: (number | null)[];
@@ -68,8 +87,14 @@ export type GeoPointColumns = {
68
87
  coarseExamples: string[];
69
88
  /** Distinct inputs that resolved to nothing (feeds the off-map annotation). */
70
89
  unmatched: string[];
71
- /** Rows placed by the largest-match tie-break on an ambiguous bare city name. */
90
+ /** Rows whose name matched MORE THAN ONE place after every non-blank source
91
+ * attribute was honoured. NOT PLOTTED (null coordinates), by rule — v2 matching
92
+ * (2026-08-02) refuses instead of guessing; before that this counted rows placed by
93
+ * a largest-city tie-break, which is the behaviour the rule replaced. */
72
94
  ambiguousRows: number;
95
+ /** Distinct inputs behind ambiguousRows — the info call-out a chart shows so the
96
+ * user can add the disambiguating column (a state, a country). Capped. */
97
+ ambiguousExamples: string[];
73
98
  matchedRows: number;
74
99
  totalRows: number;
75
100
  };
@@ -89,13 +114,14 @@ export declare function buildGeoPointColumns(rows: Array<{
89
114
  state?: any;
90
115
  zip?: any;
91
116
  country?: any;
92
- }>): GeoPointColumns;
117
+ }>, mapKind?: GeoMapKind | null): GeoPointColumns;
93
118
  /** Is this an ALREADY-NORMALIZED name (normalizePlaceName applied) of a known city?
94
119
  * geoDetector calls this per distinct value to emit the "city-name" kind — it passes
95
120
  * its own normalized form, so this must NOT re-normalize. */
96
- export declare function isKnownCity(normalizedName: string): boolean;
121
+ export declare function isKnownCity(normalizedName: string, mapKind?: GeoMapKind | null): boolean;
97
122
  /** Share of DISTINCT values that are known city names, 0..100 (one decimal). NOTE:
98
123
  * production offerability does NOT ride on this — detectGeo's "city-name" kind is the
99
124
  * gate (THRESHOLD_PCT 85, ≥2 matches, roster guard). This is the standalone measure
100
- * for harness/MCP callers; keep its notion of "match" aligned with isKnownCity. */
101
- export declare function cityMatchPct(values: Array<string | null | undefined>): number;
125
+ * for harness/MCP callers; keep its notion of "match" aligned with isKnownCity
126
+ * (including the NA-scope default see the note there). */
127
+ export declare function cityMatchPct(values: Array<string | null | undefined>, mapKind?: GeoMapKind | null): number;
@@ -1,3 +1,4 @@
1
+ import { type GeoMapKind } from "./geoPoint";
1
2
  /** The place parts a coordinate can be resolved from. Any subset. */
2
3
  export type PointBind = {
3
4
  city?: string;
@@ -55,4 +56,4 @@ export declare function zipMatchPct(values: Array<unknown>): number;
55
56
  * a refusal drops that ONE role, leaving the rest of the binding intact, because
56
57
  * geocoding from city alone still beats geocoding from nothing.
57
58
  */
58
- export declare function resolvePointRoles(columns: string[], rows: Array<Record<string, any>>, hint: PointBind | null): PointRoleResolution;
59
+ export declare function resolvePointRoles(columns: string[], rows: Array<Record<string, any>>, hint: PointBind | null, mapKind?: GeoMapKind | null): PointRoleResolution;