@borgar/fx 4.8.0 → 4.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/fx.d.ts CHANGED
@@ -101,12 +101,15 @@ export declare function addTokenMeta(tokenlist: Array<Token>, context?: {
101
101
  * @param formula A string (an Excel formula) or a token list that should be adjusted.
102
102
  * @param [options={}] Options
103
103
  * @param [options.addBounds=false] Fill in any undefined bounds of range objects. Top to 0, bottom to 1048575, left to 0, and right to 16383.
104
+ * @param [options.thisRow=false] Enforces using the `[#This Row]` instead of the `@` shorthand when serializing structured ranges.
104
105
  * @param [options.xlsx=false] Switches to the `[1]Sheet1!A1` or `[1]!name` prefix syntax form for external workbooks. See: [Prefixes.md](./Prefixes.md)
105
106
  * @returns A formula string or token list (depending on which was input)
106
107
  */
107
108
  export declare function fixRanges(formula: (string | Array<Token>), options?: {
108
109
  /** Fill in any undefined bounds of range objects. Top to 0, bottom to 1048575, left to 0, and right to 16383. */
109
110
  addBounds?: boolean;
111
+ /** Enforces using the `[#This Row]` instead of the `@` shorthand when serializing structured ranges. */
112
+ thisRow?: boolean;
110
113
  /** Switches to the `[1]Sheet1!A1` or `[1]!name` prefix syntax form for external workbooks. See: [Prefixes.md](./Prefixes.md) */
111
114
  xlsx?: boolean;
112
115
  }): (string | Array<Token>);
@@ -422,10 +425,13 @@ export declare function stringifyR1C1Ref(refObject: ReferenceR1C1, options?: {
422
425
  *
423
426
  * @param refObject A structured reference object
424
427
  * @param [options={}] Options
428
+ * @param [options.thisRow=false] Enforces using the `[#This Row]` instead of the `@` shorthand when serializing structured ranges.
425
429
  * @param [options.xlsx=false] Switches to the `[1]Sheet1!A1` or `[1]!name` prefix syntax form for external workbooks. See: [Prefixes.md](./Prefixes.md)
426
430
  * @returns The structured reference in string format
427
431
  */
428
432
  export declare function stringifyStructRef(refObject: ReferenceStruct, options?: {
433
+ /** Enforces using the `[#This Row]` instead of the `@` shorthand when serializing structured ranges. */
434
+ thisRow?: boolean;
429
435
  /** Switches to the `[1]Sheet1!A1` or `[1]!name` prefix syntax form for external workbooks. See: [Prefixes.md](./Prefixes.md) */
430
436
  xlsx?: boolean;
431
437
  }): string;
@@ -699,6 +705,8 @@ export declare type RangeA1 = {
699
705
  right?: (number | null);
700
706
  /** Top row of the range */
701
707
  top?: (number | null);
708
+ /** Should empty rows and columns at the top/left or bottom/right be discarded when range is read? */
709
+ trim?: ("head" | "tail" | "both");
702
710
  };
703
711
 
704
712
  /** A range in R1C1 style coordinates. */
package/dist/fx.js CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";const e="operator",t="error",n="range_beam",l="range_ternary",r="range_named",o="structured",s="unknown",u="UnaryExpression",i="BinaryExpression",c="ReferenceIdentifier",a="CallExpression",f="LetExpression";function p(e){let t=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=!1,l="";const r=[],o=()=>{l&&r.push(t?l:{value:l,braced:n}),l=""};for(let t=0;t<e.length;t++){const r=e[t];"["===r?(o(),n=!0):"]"===r?(o(),n=!1):l+=r}return o(),r}function h(e){return{context:p(e,!0)}}function g(e){const t={},n=p(e);if(n.length>1)t.workbookName=n[n.length-2].value,t.sheetName=n[n.length-1].value;else if(1===n.length){const e=n[0];e.braced?t.workbookName=e.value:t.sheetName=e.value}return t}const d=e=>e&&":"===e.value&&{},x=e=>e&&"range"===e.type&&{r0:e.value},y=e=>e&&e.type===l&&{r0:e.value},m=e=>e&&"range"===e.type&&{r1:e.value},v=t=>t&&t.type===e&&"!"===t.value&&{},$=e=>e&&e.type===n&&{r0:e.value},E=e=>e&&e.type===o&&{struct:e.value},w=(e,t)=>{const n=t.xlsx?g:h;return e&&"context"===e.type?n(e.value):e&&"context_quote"===e.type?n(e.value.slice(1,-1).replace(/''/g,"'")):void 0},R=e=>e&&e.type===r&&{name:e.value},N=[[y],[x,d,m],[x],[$],[w,v,y],[w,v,x,d,m],[w,v,x],[w,v,$]],b=N.concat([[R],[w,v,R],[E],[R,E],[w,v,R,E]]);function A(e,t){const n={withLocation:!1,mergeRefs:!1,allowTernary:!1,allowNamed:!0,r1c1:!1,xlsx:!1,...t},l=Me(e,Ce,n),r=n.xlsx?{workbookName:"",sheetName:"",r0:"",r1:"",name:""}:{context:[],r0:"",r1:"",name:""};l.length&&"fx_prefix"===l[0].type&&l.shift();const o=n.allowNamed?b:N;for(let e=0;e<o.length;e++){const t={...r};if(o[e].length===l.length){const r=o[e].every(((e,r)=>{const o=e(l[r],n);return Object.assign(t,o),o}));if(r)return t}}return null}const C=/[^0-9A-Za-z._¡¤§¨ª\u00ad¯-\uffff]/;function T(e){let t="",n=0,l=0;const r=e.context||[];for(let e=r.length;e>-1;e--){const o=r[e];if(o){t=(l%2?"["+o+"]":o)+t,n+=C.test(o),l++}}return n&&(t="'"+t.replace(/'/g,"''")+"'"),t?t+"!":t}function L(e){let t="",n=0;const{workbookName:l,sheetName:r}=e;return l&&(t+="["+l+"]",n+=C.test(l)),r&&(t+=r,n+=C.test(r)),n&&(t="'"+t.replace(/'/g,"''")+"'"),t?t+"!":t}const I=(e,t,n)=>Math.min(Math.max(t,e),n),k=(e,t)=>(t?"$":"")+F(e),O=(e,t)=>(t?"$":"")+String(e+1),_=String.fromCharCode;function U(e){const t=e||"",n=t.length;let l=0;if(n>2){const e=t.charCodeAt(n-3);l+=676*(1+e-(e>95?32:0)-65)}if(n>1){const e=t.charCodeAt(n-2);l+=26*(1+e-(e>95?32:0)-65)}if(n){const e=t.charCodeAt(n-1);l+=e-(e>95?32:0)-65}return l}function F(e){return(e>=702?_(((e-702)/676-0)%26+65):"")+(e>=26?_((e/26-1)%26+65):"")+_(e%26+65)}function S(e){let{top:t,left:n,bottom:l,right:r}=e;const{$left:o,$right:s,$top:u,$bottom:i}=e,c=null==n,a=null==r,f=null==t,p=null==l;t=I(0,0|t,1048575),n=I(0,0|n,16383),!c&&!f&&a&&p?(l=t,r=n):(l=I(0,0|l,1048575),r=I(0,0|r,16383));if(0===t&&l>=1048575&&!c&&!a&&(!(o&&!c||s&&!a)||n===r)||f&&p)return k(n,o)+":"+k(r,s);return 0===n&&r>=16383&&!f&&!p&&(!(u&&!f||i&&!p)||t===l)||c&&a?O(t,u)+":"+O(l,i):c||f||a||!p?c||!f||a||p?c||f||!a||p?!c||f||a||p?r!==n||l!==t||s!==o||i!==u?k(n,o)+O(t,u)+":"+k(r,s)+O(l,i):k(n,o)+O(t,u):k(r,s)+O(t,u)+":"+O(l,i):k(n,o)+O(t,u)+":"+O(l,i):k(n,o)+O(l,i)+":"+k(r,s):k(n,o)+O(t,u)+":"+k(r,s)}function M(e){const t=/^(?=.)(\$(?=\D))?([A-Za-z]{0,3})?(\$)?([1-9][0-9]{0,6})?$/.exec(e);return t&&(t[2]||t[4])?[t[4]?(n=t[4],+n-1):null,t[2]?U(t[2]):null,!!t[3],!!t[1]]:null;var n}function D(e){let t=null,n=null,l=null,r=null,o=!1,s=!1,u=!1,i=!1;const[c,a,f]=e.split(":");if(f)return null;const p=M(c),h=a?M(a):null;if(!p||a&&!h)return null;if(null!=p[0]&&null!=p[1]?[t,n,o,s]=p:null==p[0]&&null!=p[1]?[,n,,s]=p:null!=p[0]&&null==p[1]&&([t,,o]=p),a)null!=h[0]&&null!=h[1]?[l,r,u,i]=h:null==h[0]&&null!=h[1]?[,r,,i]=h:null!=h[0]&&null==h[1]&&([l,,u]=h);else{if(null==t||null==n)return null;l=t,r=n,u=o,i=s}return null!=r&&(null==n||null!=n&&r<n)&&([n,r,s,i]=[r,n,i,s]),null!=l&&(null==t||null!=t&&l<t)&&([t,l,o,u]=[l,t,u,o]),{top:t,left:n,bottom:l,right:r,$top:o,$left:s,$bottom:u,$right:i}}function z(e){let{allowNamed:t=!0,allowTernary:n=!1,xlsx:l=!1}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const r=A(e,{allowNamed:t,allowTernary:n,xlsx:l,r1c1:!1});if(r&&(r.r0||r.name)){let e=null;return r.r0&&(e=D(r.r1?r.r0+":"+r.r1:r.r0)),r.name||e?(r.range=e,delete r.r0,delete r.r1,r):null}return null}function j(e){let{xlsx:t=!1}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const n=t?L(e):T(e);return n+(e.name?e.name:S(e.range))}function B(e){return null==e.top&&(e.top=0,e.$top=!1),null==e.bottom&&(e.bottom=1048575,e.$bottom=!1),null==e.left&&(e.left=0,e.$left=!1),null==e.right&&(e.right=16383,e.$right=!1),e}const Z=/^\[('['#@[\]]|[^'#@[\]])+\]/i,q=/^([^#@[\]:]+)/i,P={headers:1,data:2,totals:4,all:8,"this row":16,"@":16},X=function(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return Object.freeze(t)},W={0:X(),1:X("headers"),2:X("data"),4:X("totals"),8:X("all"),16:X("this row"),3:X("headers","data"),6:X("data","totals")},H=function(e){let t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],n=Z.exec(e);if(n){const e=n[0].slice(1,-1).replace(/'(['#@[\]])/g,"$1");return[n[0],e]}return t&&(n=q.exec(e),n)?[n[0],n[0]]:null};function Y(e){const t=[];let n,l,r=0,o=e,s=0;if(!(n=/^(\[\s*)/.exec(o)))return null;if(l=/^\[#([a-z ]+)\]/i.exec(o)){const e=l[1].toLowerCase();if(r+=l[0].length,!P[e])return null;s|=P[e]}else if(l=H(o,!1))r+=l[0].length,t.push(l[1]);else{let l=!0;for(o=o.slice(n[1].length),r+=n[1].length;l&&(n=/^\[#([a-z ]+)\](\s*,\s*)?/i.exec(o));){const e=n[1].toLowerCase();if(!P[e])return null;s|=P[e],o=o.slice(n[0].length),r+=n[0].length,l=!!n[2]}if(l&&(n=/^@/.exec(o))&&(s|=P["@"],o=o.slice(1),r+=1,l="]"!==o[0]),!(s in W))return null;const u=l?H(e.slice(r)):null;if(u){if(r+=u[0].length,t.push(u[1]),o=e.slice(r),":"===o[0]){o=o.slice(1),r++;const e=H(o);if(!e)return null;r+=e[0].length,t.push(e[1])}l=!1}for(;" "===e[r];)r++;if(l||"]"!==e[r])return null;r++}const u=W[s];return{columns:t,sections:u?u.concat():u,length:r,token:e.slice(0,r)}}function G(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{xlsx:!1};const n=A(e,t);if(n&&n.struct){const e=Y(n.struct);if(e&&e.length===n.struct.length)return t.xlsx?{workbookName:n.workbookName,sheetName:n.sheetName,table:n.name,columns:e.columns,sections:e.sections}:{context:n.context,table:n.name,columns:e.columns,sections:e.sections}}return null}function K(e){return e.replace(/([[\]#'@])/g,"'$1")}function V(e){return!/^[a-zA-Z0-9\u00a1-\uffff]+$/.test(e)}function Q(e){return e[0].toUpperCase()+e.slice(1).toLowerCase()}function J(e){let{xlsx:t=!1}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=t?L(e):T(e);e.table&&(n+=e.table);const l=e.columns?.length??0,r=e.sections?.length??0;if(1!==r||l)if(r||1!==l){n+="[";const t=1===r&&"this row"===e.sections[0].toLowerCase();t?n+="@":r&&(n+=e.sections.map((e=>`[#${Q(e)}]`)).join(","),l&&(n+=",")),t&&1===e.columns.length&&!V(e.columns[0])?n+=K(e.columns[0]):l&&(n+=e.columns.slice(0,2).map((e=>`[${K(e)}]`)).join(":")),n+="]"}else n+=`[${K(e.columns[0])}]`;else n+=`[#${Q(e.sections[0])}]`;return n}const ee=/^(?!!)(\[(?:[^\]])+\])?([0-9A-Za-z._¡¤§¨ª\u00ad¯-\uffff]+)?(?=!)/,te=/^'(?:''|[^'])*('|$)(?=!)/,ne="\\$?[A-Z]{1,3}\\$?[1-9][0-9]{0,6}",le="\\$?[A-Z]{1,3}",re="\\$?[1-9][0-9]{0,6}",oe="(?![a-z0-9_\\u00a1-\\uffff])",se=new RegExp(`^${le}:${le}${oe}`,"i"),ue=new RegExp(`^${re}:${re}${oe}`,"i"),ie=new RegExp(`^${ne}${oe}`,"i"),ce=new RegExp(`^((${le}|${re}):${ne}|${ne}:(${le}|${re}))(?![\\w($.])`,"i"),ae="(?:R(?:\\[[+-]?\\d+\\]|[1-9][0-9]{0,6})?)",fe="(?:C(?:\\[[+-]?\\d+\\]|[1-9][0-9]{0,4})?)",pe=new RegExp(`^${fe}(:${fe})?${oe}`,"i"),he=new RegExp(`^${ae}(:${ae})?${oe}`,"i"),ge=new RegExp(`^(?:(?=[RC])${ae}${fe})${oe}`,"i"),de=new RegExp(`^(${ae}${fe}(:${fe}|:${ae})(?![[\\d])|(${ae}|${fe})(:${ae}${fe}))${oe}`,"i"),xe=/^[a-zA-Z\\_\u00a1-\uffff][a-zA-Z0-9\\_.?\u00a1-\uffff]{0,254}/i;function ye(e,t){return n=>{const l=t.exec(n);if(l)return{type:e,value:l[0]}}}function me(e){const t=xe.exec(e);if(t){const e=t[0].toLowerCase();return"\\"===e[0]&&t[0].length<3||("r"===e||"c"===e)?null:{type:r,value:t[0]}}}const ve=/^'(?:[^[\]]+?)?(?:\[(.+?)\])?(?:[^[\]]+?)'$/,$e=/^'\[(.+?)\]'$/;function Ee(e,t){const n=te.exec(e);if(n){const e=n[0];if(t.xlsx&&$e.test(e)||ve.test(e))return{type:"context_quote",value:e}}const l=ee.exec(e);if(l){const[,e,n]=l;if(e&&n||n||e&&!n&&t.xlsx)return{type:"context",value:l[0]}}}function we(e){const t=Y(e);if(t){let n=t.length;for(;" "===e[n];)n++;if("!"!==e[n])return{type:o,value:t.token}}return null}const Re=/([RC])(\[?)(-?\d+)/gi,Ne=/(\d+|[a-zA-Z]+)/gi;function be(e,t){let r,o;if(t.r1c1){if(t.allowTernary&&(r=de.exec(e))?o={type:l,value:r[0]}:(r=ge.exec(e))?o={type:"range",value:r[0]}:((r=he.exec(e))||(r=pe.exec(e)))&&(o={type:n,value:r[0]}),o){for(Re.lastIndex=0;null!==(r=Re.exec(o.value));){const e=("R"===r[1]?1048575:16383)+(r[2]?0:1),t=parseInt(r[3],10);if(t>e||t<-e)return null}return o}}else if(t.allowTernary&&(r=ce.exec(e))?o={type:l,value:r[0]}:(r=se.exec(e))||(r=ue.exec(e))?o={type:n,value:r[0]}:(r=ie.exec(e))&&(o={type:"range",value:r[0]}),o){for(Ne.lastIndex=0;null!==(r=Ne.exec(o.value));)if(/^\d/.test(r[1])){if(parseInt(r[1],10)-1>1048575)return null}else if(U(r[1])>16383)return null;return o}}const Ae=[ye(t,/^#(NAME\?|FIELD!|CALC!|VALUE!|REF!|DIV\/0!|NULL!|NUM!|N\/A|GETTING_DATA\b|SPILL!|UNKNOWN!|FIELD\b|CALC\b|SYNTAX\?|ERROR!|CONNECT!|BLOCKED!|EXTERNAL!)/i),ye(e,/^(<=|>=|<>|[-+/*^%&<>=]|[{},;]|[()]|@|:|!|#)/),ye("func",/^[A-Z_]+[A-Z\d_.]*(?=\()/i),ye("bool",/^(TRUE|FALSE)\b/i),ye("newline",/^\n+/),ye("whitespace",/^[ \f\r\t\v\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]+/),ye("string",/^"(?:""|[^"])*("|$)/),Ee,be,we,ye("number",/^(?:\d+(\.\d+)?(?:[eE][+-]?\d+)?|\d+)/),me],Ce=[function(t,n){return n.r1c1?"!"===t[0]?{type:e,value:t[0]}:null:"!"===t[0]||":"===t[0]?{type:e,value:t[0]}:null},Ee,be,we,me],Te={};function Le(e,t){if(e.length){const n=e[0];t[n]=t[n]||{},Le(e.slice(1),t[n])}else t.$=!0}[["range",":","range"],["range"],[n],[l],["context","!","range",":","range"],["context","!","range"],["context","!",n],["context","!",l],["context_quote","!","range",":","range"],["context_quote","!","range"],["context_quote","!",n],["context_quote","!",l],[r],["context","!",r],["context_quote","!",r],[o],[r,o],["context","!",r,o],["context_quote","!",r,o]].forEach((e=>Le(e.concat().reverse(),Te)));const Ie=function(t,n,l){let r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:0;const o=t[l-r];if(o){const s=o.type===e?o.value:o.type;if(s in n)return Ie(t,n[s],l,r+1)}return n.$?r:0};function ke(e){const t=[];for(let n=e.length-1;n>=0;n--){let l=e[n];const r=Ie(e,Te,n);if(r){const t=e.slice(n-r+1,n+1);l={...l},l.value=t.map((e=>e.value)).join(""),l.loc&&t[0].loc&&(l.loc[0]=t[0].loc[0]),n-=r-1}t.unshift(l)}return t}const Oe=(e,t)=>e&&e.type===t,_e={withLocation:!1,mergeRefs:!0,allowTernary:!1,negativeNumbers:!0,r1c1:!1},Ue=e=>e.type===r||"func"===e.type,Fe=t=>!Oe(t,e)||"%"===t.value||"}"===t.value||")"===t.value||"#"===t.value;function Se(t){let n,l=0,o=0;for(const u of t){if(u.type===e)if("("===u.value){if(o++,"func"===n.type){const e=n.value.toLowerCase();"lambda"!==e&&"let"!==e||(l=o)}}else")"===u.value&&(o--,o<l&&(l=0));else l&&u.type===s&&/^[rc]$/.test(u.value)&&(u.type=r);n=u}return t}function Me(t,n){let l=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const r=Object.assign({},_e,l),{withLocation:o,mergeRefs:u,negativeNumbers:i}=r,c=[];let a=0,f=0,p=0,h=null,g=null,d=null;const x=e=>{const t=e.type===s,n=d&&d.type===s;d&&(t&&n||t&&Ue(d)||n&&Ue(e))?(d.value+=e.value,d.type=s,o&&(d.loc[1]=e.loc[1])):(c.push(e),d=e,"whitespace"!==e.type&&"newline"!==e.type&&(g=h,h=e))};if(/^=/.test(t)){a++,x({type:"fx_prefix",value:"=",...o?{loc:[0,1]}:{}})}for(;a<t.length;){const l=a,u=t.slice(a);let y="",m="";for(let e=0;e<n.length;e++){const t=n[e](u,r);if(t){y=t.type,m=t.value,a+=m.length;break}}y||(y=s,m=t[a],a++);const v={type:y,value:m,...o?{loc:[l,a]}:{}};if(d&&"func"===d.type&&"("===m){const e=d.value.toLowerCase();"lambda"!==e&&"let"!==e||f++}if(y===s){const e=m.toLowerCase();p+="r"===e||"c"===e?1:0}if("string"===y){const e=m.length;if('""'===m);else if('"'===m||'"'!==m[e-1])v.unterminated=!0;else if('""'!==m&&'"'===m[e-2]){let t=e-1;for(;'"'===m[t];)t--;!(t+1)^(e-t+1)%2==0&&(v.unterminated=!0)}}if(i&&"number"===y){const t=d;if(t&&Oe(t,e)&&"-"===t.value&&(!g||Oe(g,"fx_prefix")||!Fe(g))){const e=c.pop();v.value="-"+m,o&&(v.loc[0]=e.loc[0]),h=g,d=c[c.length-1]}}x(v)}return p&&f&&Se(c),u?ke(c):c}function De(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return Me(e,Ae,t)}function ze(e){return!!e&&("range"===e.type||e.type===n||e.type===l)}function je(e){return!!e&&("range"===e.type||e.type===n||e.type===l||e.type===o||e.type===r)}function Be(e){return!!e&&("bool"===e.type||e.type===t||"number"===e.type||"string"===e.type)}function Ze(e){return!!e&&e.type===t}function qe(e){return!!e&&("whitespace"===e.type||"newline"===e.type)}function Pe(e){return!!e&&"func"===e.type}function Xe(e){return!!e&&"fx_prefix"===e.type}function We(t){return!!t&&t.type===e}const He="(END)",Ye=["ANCHORARRAY","CHOOSE","DROP","IF","IFS","INDEX","INDIRECT","LAMBDA","LET","OFFSET","REDUCE","SINGLE","SWITCH","TAKE","XLOOKUP"],Ge=e=>Ye.includes(e.toUpperCase()),Ke=function(e){let t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];const n=(e&&e.value)+"";return!!je(e)||(!(!t||!We(e)||":"!==n&&","!==n&&n.trim())||(!(!Pe(e)||!Ge(n))||!(!Ze(e)||"#REF!"!==n)))},Ve=e=>!!e&&(e.type===c||("ErrorLiteral"===e.type||e.type===t)&&"#REF!"===e.value||e.type===i&&(":"===e.operator||" "===e.operator||","===e.operator)||je(e)||e.type===a&&Ge(e.callee.name)),Qe={};let Je,et,tt,nt=!1,lt=!1;function rt(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;const n=new Error(e);throw n.source=et.map((e=>e.value)).join(""),n.sourceOffset=et.slice(0,t??tt).reduce(((e,t)=>e+t.value.length),0),n}function ot(){let e,t=arguments.length>0&&void 0!==arguments[0]&&arguments[0],n=tt;do{e=et[++n]}while(e&&(qe(e)||We(e)&&"("===e.value));return Ke(e,t)}function st(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;if(e&&e!==Je.id&&rt(`Expected ${e} but got ${Je.id}`),qe(et[tt])){const e=Ve(t),n=e&&ot(!1),l=e&&"("===et[tt+1].value;if(!n&&!l)for(;qe(et[tt]);)tt++}if(tt>=et.length)return void(Je=Qe[He]);const n=et[tt];let l;return tt+=1,n.unterminated&&rt("Encountered an unterminated token"),We(n)?(l=Qe[n.value],l||rt(`Unknown operator ${n.value}`)):qe(n)?l=Qe["(WHITESPACE)"]:Be(n)?l=Qe.Literal:je(n)?l=Qe[c]:Pe(n)?l=Qe["(FUNCTION)"]:rt(`Unexpected ${n.type} token: ${n.value}`),Je=Object.create(l),Je.type=n.type,Je.value=n.value,n.loc&&(Je.loc=[...n.loc]),Je}function ut(e){let t=Je;st(null,t);let n=t.nud();for(;e<Je.lbp;)t=Je,st(null,t),n=t.led(n);return n}const it={nud:()=>rt("Invalid syntax"),led:()=>rt("Missing operator")};function ct(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=Qe[e];return n?t>=n.lbp&&(n.lbp=t):(n={...it},n.id=e,n.value=e,n.lbp=t,Qe[e]=n),n}function at(e,t,n){const l=ct(e,t);return l.led=n||function(e){this.type=i,this.operator=this.value,delete this.value;const n=ut(t);return this.arguments=[e,n],this.loc&&(this.loc=[e.loc[0],n.loc[1]]),this},l}function ft(e,t){const n=ct(e,0);return n.lbp=70,n.led=t||function(e){return this.type=u,this.operator=this.value,delete this.value,this.arguments=[e],this.loc&&(this.loc[0]=e.loc[0]),this},n}function pt(e,t){const n=ct(e);return n.nud=t||function(){this.type=u,this.operator=this.value,delete this.value;const e=ut(70);return this.arguments=[e],this.loc&&(this.loc[1]=e.loc[1]),this},n}function ht(e,t){return at(e,t,(function(n){Ve(n)||rt(`Unexpected ${e} operator`);const l=ut(t);return Ve(l)||rt(`Unexpected ${Je.type} following ${this.id}`),this.type=i,this.operator=this.value.trim()?this.value:" ",delete this.value,this.arguments=[n,l],this.loc&&(this.loc=[n.loc[0],l.loc[1]]),this}))}ct(He),ht(":",80);const gt=ht(",",80);ht("(WHITESPACE)",80);const dt=e=>{const t=gt.lbp>0;return null!=e&&(gt.lbp=e?80:0),t};function xt(e){const t=[],n={};let l,r=!1;const o=dt(!1);if(")"!==Je.id)for(;!r;){qe(Je)&&st();const e=tt,o=ut(0);if(","===Je.id){if(o.type===c&&"name"===o.kind){const e=o.value.toLowerCase();e in n&&rt("Duplicate name: "+o.value),n[e]=1;const l={type:"Identifier",name:o.value};o.loc&&(l.loc=o.loc),t.push(l)}else tt=e,rt("LAMBDA argument is not a name");st(",")}else l=o,r=!0}return dt(o),delete this.value,this.type="LambdaExpression",this.params=t,this.body=l||null,e.loc&&(this.loc=[e.loc[0],Je.loc[1]]),st(")",this),this}function yt(e){const t=[],n=[],l={};let r,o=0;const s=(e,s)=>{if(r&&rt("Unexpected argument following calculation"),s&&o>=2)r=e;else{if(!(o%2))if(e&&e.type===c&&"name"===e.kind){const n=e.value.toLowerCase();n in l&&rt("Duplicate name: "+e.value),l[n]=1,t.push({type:"Identifier",name:e.value,loc:e.loc})}else o>=2?r=e:rt("Argument is not a name");else n.push(e)}o++},u=dt(!1);let i=!1;if(")"!==Je.id){for(;")"!==Je.id;)if(qe(Je)&&st(),","===Je.id)s(null),i=!0,st();else{s(ut(0),","!==Je.id),i=!1,","===Je.id&&(st(","),i=!0)}dt(u)}i&&s(null,!0),void 0===r&&rt("Unexpected end of arguments"),dt(u),delete this.value,this.type=f,this.declarations=[],t.length||rt("Unexpected end of arguments");for(let e=0;e<t.length;e++){const l={type:"LetDeclarator",id:t[e],init:n[e],loc:t[e].loc&&[t[e].loc[0],n[e].loc[1]]};this.declarations.push(l)}return this.body=r,e.loc&&(this.loc=[e.loc[0],Je.loc[1]]),st(")",this),this}function mt(){let e=1;return()=>"fxg"+e++}function vt(e,t){return null==e&&null==t||e===t}function $t(e,t){if(Array.isArray(e)!==Array.isArray(t)||e.length!==t.length)return!1;for(let n=0;n<e.length;n++)if(!vt(e[n],t[n]))return!1;return!0}function Et(e,t){return!e&&!t||String(e).toLowerCase()===String(t).toLowerCase()}function wt(e,t){if((e.name||t.name)&&e.name!==t.name)return!1;if(e.columns||t.columns){if(e.table!==t.table)return!1;if(!$t(e.columns,t.columns))return!1;if(!$t(e.sections,t.sections))return!1}return!!(!e.range&&!t.range||vt(e.range.top,t.range.top)&&vt(e.range.bottom,t.range.bottom)&&vt(e.range.left,t.range.left)&&vt(e.range.right,t.range.right))&&!(!Et(e.workbookName,t.workbookName)||!Et(e.sheetName,t.sheetName))}function Rt(e,t,n){return e.sheetName||(e.sheetName=t),e.workbookName||(e.workbookName=n),e}ft("%"),ft("#",(function(e){return Ve(e)||rt("# expects a reference"),this.type=u,this.operator=this.value,delete this.value,this.arguments=[e],this})),pt("+"),pt("-"),pt("@"),at("^",50),at("*",40),at("/",40),at("+",30),at("-",30),at("&",20),at("=",10),at("<",10),at(">",10),at("<=",10),at(">=",10),at("<>",10),ct("Literal").nud=function(){const{type:e,value:n}=this;if(this.type="Literal",this.raw=n,"number"===e)this.value=+n;else if("bool"===e)this.value="TRUE"===n.toUpperCase();else if(e===t)this.type="ErrorLiteral",this.value=n.toUpperCase();else{if("string"!==e)throw new Error("Unsupported literal type: "+e);this.value=n.slice(1,-1).replace(/""/g,'"')}return this},ct(c).nud=function(){return this.type===r?this.kind="name":this.type===o?this.kind="table":this.type===n?this.kind="beam":this.kind="range",this.type=c,this},ct(")"),pt("(",(function(){const e=dt(!0),t=ut(0);return st(")",t),dt(e),t})),ct("(FUNCTION)").nud=function(){return this},at("(",90,(function(e){let t={type:"Identifier",name:e.value};"(FUNCTION)"!==e.id&&("LambdaExpression"===e.type||e.type===a||e.type===f||e.type===c||e.type===u&&"#"===e.value||"ErrorLiteral"===e.type&&"#REF!"===e.value?t=e:rt("Unexpected call",tt-1));const n=e.value.toLowerCase();if("lambda"===n)return xt.call(this,e);if("let"===n)return yt.call(this,e);const l=[];let r=!1;if(")"!==Je.id){const e=dt(!1);for(;")"!==Je.id;)if(qe(Je)&&st(),","===Je.id)l.push(null),r=!0,st();else{const e=ut(0);l.push(e),r=!1,","===Je.id&&(st(","),r=!0)}dt(e)}r&&l.push(null);const o=Je;return delete this.value,this.type=a,this.callee=t,e.loc&&(this.callee.loc=[...e.loc]),this.arguments=l,e.loc&&(this.loc=[e.loc[0],o.loc[1]]),st(")",this),this})),ct("}"),ct(";"),pt("{",(function(){"}"===Je.id&&rt("Unexpected empty array");let e=[],t=!1;const n=[e],l=dt(!1);for(;!t;){if(qe(Je)&&st(),Be(Je))e.push(Qe.Literal.nud.call(Je)),st();else if(nt&&Ve(Je))e.push(Qe[c].nud.call(Je)),st();else if(lt&&Pe(Je)){const t=ut(0);e.push(t)}else rt(`Unexpected ${Je.type} in array: ${Je.value}`);","===Je.id?st(","):";"===Je.id?(st(";"),e=[],n.push(e)):t=!0}const r=Je;return st("}"),dt(l),this.type="ArrayExpression",this.elements=n,this.loc&&(this.loc[1]=r.loc[1]),delete this.value,this}));const Nt=(e,t,n)=>Math.min(Math.max(t,e),n);function bt(e,t){return t?String(e+1):e?"["+e+"]":""}function At(e){let{r0:t,c0:n,r1:l,c1:r}=e;const{$c0:o,$c1:s,$r0:u,$r1:i}=e,c=null==t,a=null==n;let f=null==l,p=null==r;t=Nt(u?0:-1048575,0|t,1048575),n=Nt(o?0:-16383,0|n,16383),!c&&f&&!a&&p?(l=t,f=!1,r=n,p=!1):(l=Nt(i?0:-1048575,0|l,1048575),r=Nt(s?0:-16383,0|r,16383));if(0===t&&l>=1048575&&!a&&!p||c&&f){const e=bt(n,o),t=bt(r,s);return"C"+(e===t?e:e+":C"+t)}if(0===n&&r>=16383&&!c&&!f||a&&p){const e=bt(t,u),n=bt(l,i);return"R"+(e===n?e:e+":R"+n)}const h=bt(t,u),g=bt(l,i),d=bt(n,o),x=bt(r,s);return c||f||a||p?(c?"":"R"+h)+(a?"":"C"+d)+":"+(f?"":"R"+g)+(p?"":"C"+x):h!==g||d!==x?"R"+h+"C"+d+":R"+g+"C"+x:"R"+h+"C"+d}function Ct(e){let t=null,n=null,l=null,r=null;const o=/^R(?:\[([+-]?\d+)\]|(\d+))?/.exec(e);o&&(o[1]?(t=parseInt(o[1],10),l=!1):o[2]?(t=parseInt(o[2],10)-1,l=!0):(t=0,l=!1),e=e.slice(o[0].length));const s=/^C(?:\[([+-]?\d+)\]|(\d+))?/.exec(e);return s&&(s[1]?(n=parseInt(s[1],10),r=!1):s[2]?(n=parseInt(s[2],10)-1,r=!0):(n=0,r=!1),e=e.slice(s[0].length)),!o&&!s||e.length?null:[t,n,l,r]}function Tt(e){let t=null;const[n,l]=e.split(":",2),r=Ct(n);if(r){const[e,n,o,s]=r;if(!l)return null!=e&&null==n?{r0:e,c0:null,r1:e,c1:null,$r0:o,$c0:!1,$r1:o,$c1:!1}:null==e&&null!=n?{r0:null,c0:n,r1:null,c1:n,$r0:!1,$c0:s,$r1:!1,$c1:s}:{r0:e||0,c0:n||0,r1:e||0,c1:n||0,$r0:o||!1,$c0:s||!1,$r1:o||!1,$c1:s||!1};{const r=Ct(l);if(!r)return null;{t={};const[l,u,i,c]=r;null!=e&&null!=l?(t.r0=o===i?Math.min(e,l):e,t.$r0=o,t.r1=o===i?Math.max(e,l):l,t.$r1=i):null!=e&&null==l?(t.r0=e,t.$r0=o,t.r1=null,t.$r1=o):null==e&&null!=l?(t.r0=l,t.$r0=i,t.r1=null,t.$r1=i):null==e&&null==l&&(t.r0=null,t.$r0=!1,t.r1=null,t.$r1=!1),null!=n&&null!=u?(t.c0=s===c?Math.min(n,u):n,t.$c0=s,t.c1=s===c?Math.max(n,u):u,t.$c1=c):null!=n&&null==u?(t.c0=n,t.$c0=s,t.c1=null,t.$c1=s):null==n&&null!=u?(t.c0=u,t.$c0=c,t.c1=null,t.$c1=c):null==n&&null==u&&(t.c0=null,t.$c0=!1,t.c1=null,t.$c1=!1)}}}return t}function Lt(e){let{allowNamed:t=!0,allowTernary:n=!1,xlsx:l=!1}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const r=A(e,{allowNamed:t,allowTernary:n,xlsx:l,r1c1:!0});if(r&&(r.r0||r.name)){const e=r.r1?Tt(r.r0+":"+r.r1):Tt(r.r0);return r.name||e?(r.range=e,delete r.r0,delete r.r1,r):null}return null}function It(e){let{xlsx:t=!1}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const n=t?L(e):T(e);return n+(e.name?e.name:At(e.range))}const kt=(e,t,n)=>null==t?null:e?t:t-n,Ot={withLocation:!1,mergeRefs:!1,allowTernary:!0,r1c1:!1};function _t(e,t,n,l){let r=!(arguments.length>4&&void 0!==arguments[4])||arguments[4],o=e;if(null!=o&&!t){if(o=n+e,o<0){if(!r)return NaN;o=l+o+1}if(o>l){if(!r)return NaN;o-=l+1}}return o}const Ut={wrapEdges:!0,mergeRefs:!0,allowTernary:!0,xlsx:!1};const Ft=Object.freeze({OPERATOR:e,BOOLEAN:"bool",ERROR:t,NUMBER:"number",FUNCTION:"func",NEWLINE:"newline",WHITESPACE:"whitespace",STRING:"string",CONTEXT:"context",CONTEXT_QUOTE:"context_quote",REF_RANGE:"range",REF_BEAM:n,REF_TERNARY:l,REF_NAMED:r,REF_STRUCT:o,FX_PREFIX:"fx_prefix",UNKNOWN:s}),St=Object.freeze({UNARY:u,BINARY:i,REFERENCE:c,LITERAL:"Literal",ERROR:"ErrorLiteral",CALL:a,ARRAY:"ArrayExpression",IDENTIFIER:"Identifier"});exports.MAX_COLS=16383,exports.MAX_ROWS=1048575,exports.addA1RangeBounds=B,exports.addTokenMeta=function(e){let{sheetName:t="",workbookName:r=""}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const u=[];let i=null;const c=mt(),a=[],f=()=>u.length+(i?1:0);return e.forEach(((e,p)=>{if(e.index=p,e.depth=f(),"("===e.value)u.push(e),e.depth=f();else if(")"===e.value){const t=u.pop();if(t){const n=c();e.groupId=n,e.depth=t.depth,t.groupId=n}else e.error=!0}else if("{"===e.value)i?e.error=!0:(i=e,e.depth=f());else if("}"===e.value){if(i){const t=c();e.groupId=t,e.depth=i.depth,i.groupId=t}else e.error=!0;i=null}else if("range"===e.type||e.type===n||e.type===l||e.type===o){const n=e.type===o?G(e.value,{allowTernary:!0,xlsx:!0}):z(e.value,{allowTernary:!0,xlsx:!0});if(n&&(n.range||n.columns)){n.source=e.value,Rt(n,t,r);const l=a.find((e=>wt(e,n)));l?e.groupId=l.groupId:(n.groupId=c(),e.groupId=n.groupId,a.push(n))}}else e.type===s&&(e.error=!0)})),e},exports.fixRanges=function e(t){let n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{addBounds:!1};if("string"==typeof t)return e(De(t,n),n).map((e=>e.value)).join("");if(!Array.isArray(t))throw new Error("fixRanges expects an array of tokens");const{addBounds:l,r1c1:r,xlsx:s}=n;if(r)throw new Error("fixRanges does not have an R1C1 mode");let u=0;return t.map((e=>{const t={...e};e.loc&&(t.loc=[...e.loc]);let n=0;if(t.type===o){const e=J(G(t.value,{xlsx:s}),{xlsx:s});n=e.length-t.value.length,t.value=e}else if(ze(t)){const e=z(t.value,{xlsx:s,allowTernary:!0}),r=e.range;l&&B(r);const o=j(e,{xlsx:s});n=o.length-t.value.length,t.value=o}return u||n?(t.loc&&(t.loc[0]+=u),u+=n,t.loc&&(t.loc[1]+=u)):u+=n,t}))},exports.fromCol=U,exports.isError=Ze,exports.isFunction=Pe,exports.isFxPrefix=Xe,exports.isLiteral=Be,exports.isOperator=We,exports.isRange=ze,exports.isReference=je,exports.isWhitespace=qe,exports.mergeRefTokens=ke,exports.nodeTypes=St,exports.parse=function(e,t){if("string"==typeof e)et=De(e,{withLocation:!1,...t,mergeRefs:!0});else{if(!Array.isArray(e))throw new Error("Parse requires a string or array of tokens.");et=e}for(nt=t?.permitArrayRanges,lt=t?.permitArrayCalls,tt=0;qe(et[tt])||Xe(et[tt]);)tt++;st(),dt(!0);const n=ut(0);return st(He),n},exports.parseA1Ref=z,exports.parseR1C1Ref=Lt,exports.parseStructRef=G,exports.stringifyA1Ref=j,exports.stringifyR1C1Ref=It,exports.stringifyStructRef=J,exports.toCol=F,exports.tokenTypes=Ft,exports.tokenize=De,exports.translateToA1=function(e,n){let l=arguments.length>2&&void 0!==arguments[2]?arguments[2]:Ut;const r=D(n),o="string"==typeof e,s={...Ut,...l},u=o?De(e,{withLocation:!1,mergeRefs:s.mergeRefs,xlsx:s.xlsx,allowTernary:s.allowTernary,r1c1:!0}):e;let i=0;const c={xlsx:s.xlsx,allowTernary:s.allowTernary};return u.forEach((e=>{if(ze(e)){const n=e.value,l=Lt(n,c),o=l.range,u={},a=_t(o.r0,o.$r0,r.top,1048575,s.wrapEdges),f=_t(o.r1,o.$r1,r.top,1048575,s.wrapEdges);a>f?(u.top=f,u.$top=o.$r1,u.bottom=a,u.$bottom=o.$r0):(u.top=a,u.$top=o.$r0,u.bottom=f,u.$bottom=o.$r1);const p=_t(o.c0,o.$c0,r.left,16383,s.wrapEdges),h=_t(o.c1,o.$c1,r.left,16383,s.wrapEdges);p>h?(u.left=h,u.$left=o.$c1,u.right=p,u.$right=o.$c0):(u.left=p,u.$left=o.$c0,u.right=h,u.$right=o.$c1),isNaN(a)||isNaN(f)||isNaN(p)||isNaN(h)?(e.type=t,e.value="#REF!",delete e.groupId):(l.range=u,e.value=j(l,c)),e.loc&&(e.loc[0]+=i,i+=e.value.length-n.length,e.loc[1]+=i)}else i&&e.loc&&(e.loc[0]+=i,e.loc[1]+=i)})),o?u.map((e=>e.value)).join(""):u},exports.translateToR1C1=function(e,t){let{xlsx:n=!1,allowTernary:l=!0}=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const{top:r,left:o}=D(t),s="string"==typeof e,u=s?De(e,{...Ot,xlsx:n,allowTernary:l}):e;let i=0;const c={xlsx:n,allowTernary:l};return u.forEach((e=>{if(ze(e)){const t=e.value,n=z(t,c),l=n.range,s={};s.r0=kt(l.$top,l.top,r),s.r1=kt(l.$bottom,l.bottom,r),s.c0=kt(l.$left,l.left,o),s.c1=kt(l.$right,l.right,o),s.$r0=l.$top,s.$r1=l.$bottom,s.$c0=l.$left,s.$c1=l.$right,n.range=s,e.value=It(n,c),e.loc&&(e.loc[0]+=i,i+=e.value.length-t.length,e.loc[1]+=i)}else i&&e.loc&&(e.loc[0]+=i,e.loc[1]+=i)})),s?u.map((e=>e.value)).join(""):u};
1
+ "use strict";const e="operator",t="error",n="context",l="range_beam",r="range_ternary",o="range_named",s="structured",u="unknown",a="UnaryExpression",i="BinaryExpression",c="ReferenceIdentifier",f="CallExpression",p="LetExpression";function h(e){let t=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=!1,l="";const r=[],o=()=>{l&&r.push(t?l:{value:l,braced:n}),l=""};for(let t=0;t<e.length;t++){const r=e[t];"["===r?(o(),n=!0):"]"===r?(o(),n=!1):l+=r}return o(),r}function g(e){return{context:h(e,!0)}}function d(e){const t={},n=h(e);if(n.length>1)t.workbookName=n[n.length-2].value,t.sheetName=n[n.length-1].value;else if(1===n.length){const e=n[0];e.braced?t.workbookName=e.value:t.sheetName=e.value}return t}const m=e=>e&&(":"===e.value||".:"===e.value||":."===e.value||".:."===e.value)&&{operator:e.value},x=e=>e&&"range"===e.type&&{r0:e.value},y=e=>e&&e.type===r&&{r0:e.value},v=e=>e&&"range"===e.type&&{r1:e.value},$=t=>t&&t.type===e&&"!"===t.value&&{},w=e=>e&&e.type===l&&{r0:e.value},N=e=>e&&e.type===s&&{struct:e.value},E=(e,t)=>{const l=t.xlsx?d:g;return e&&e.type===n?l(e.value):e&&"context_quote"===e.type?l(e.value.slice(1,-1).replace(/''/g,"'")):void 0},R=e=>e&&e.type===o&&{name:e.value},b=[[y],[x,m,v],[x],[w],[E,$,y],[E,$,x,m,v],[E,$,x],[E,$,w]],A=b.concat([[R],[E,$,R],[N],[R,N],[E,$,R,N]]);function C(e,t){const n={withLocation:!1,mergeRefs:!1,allowTernary:!1,allowNamed:!0,r1c1:!1,xlsx:!1,...t},l=je(e,Le,n),r=n.xlsx?{workbookName:"",sheetName:"",r0:"",r1:"",name:"",operator:""}:{context:[],r0:"",r1:"",name:"",operator:""};l.length&&"fx_prefix"===l[0].type&&l.shift();const o=n.allowNamed?A:b;for(let e=0;e<o.length;e++){const t={...r};if(o[e].length===l.length){const r=o[e].every(((e,r)=>{const o=e(l[r],n);return Object.assign(t,o),o}));if(r)return t}}return null}const T=/[^0-9A-Za-z._¡¤§¨ª\u00ad¯-\uffff]/;function k(e){let t="",n=0,l=0;const r=e.context||[];for(let e=r.length;e>-1;e--){const o=r[e];if(o){t=(l%2?"["+o+"]":o)+t,n+=+T.test(o),l++}}return n&&(t="'"+t.replace(/'/g,"''")+"'"),t?t+"!":t}function L(e){let t="",n=0;const{workbookName:l,sheetName:r}=e;return l&&(t+="["+l+"]",n+=+T.test(l)),r&&(t+=r,n+=+T.test(r)),n&&(t="'"+t.replace(/'/g,"''")+"'"),t?t+"!":t}const I=(e,t,n)=>Math.min(Math.max(t,e),n),_=(e,t)=>(t?"$":"")+S(e),O=(e,t)=>(t?"$":"")+String(e+1),U=String.fromCharCode;function F(e){const t=e||"",n=t.length;let l=0;if(n>2){const e=t.charCodeAt(n-3);l+=676*(1+e-(e>95?32:0)-65)}if(n>1){const e=t.charCodeAt(n-2);l+=26*(1+e-(e>95?32:0)-65)}if(n){const e=t.charCodeAt(n-1);l+=e-(e>95?32:0)-65}return l}function S(e){return(e>=702?U(((e-702)/676-0)%26+65):"")+(e>=26?U((e/26-1)%26+65):"")+U(e%26+65)}function M(e){return"both"===e?".:.":"head"===e?".:":"tail"===e?":.":":"}function D(e,t){return e&&t?"both":e?"head":t?"tail":void 0}function z(e){let{top:t,left:n,bottom:l,right:r,trim:o}=e;const{$left:s,$right:u,$top:a,$bottom:i}=e,c=null==n,f=null==r,p=null==t,h=null==l;t=I(0,0|t,1048575),n=I(0,0|n,16383),!c&&!p&&f&&h?(l=t,r=n):(l=I(0,0|l,1048575),r=I(0,0|r,16383));const g=M(o);if(0===t&&l>=1048575&&!c&&!f&&(!(s&&!c||u&&!f)||n===r)||p&&h)return _(n,s)+g+_(r,u);return 0===n&&r>=16383&&!p&&!h&&(!(a&&!p||i&&!h)||t===l)||c&&f?O(t,a)+g+O(l,i):c||p||f||!h?c||!p||f||h?c||p||!f||h?!c||p||f||h?r!==n||l!==t||u!==s||i!==a?_(n,s)+O(t,a)+g+_(r,u)+O(l,i):_(n,s)+O(t,a):_(r,u)+O(t,a)+g+O(l,i):_(n,s)+O(t,a)+g+O(l,i):_(n,s)+O(l,i)+g+_(r,u):_(n,s)+O(t,a)+g+_(r,u)}function j(e){const t=/^(?=.)(\$(?=\D))?([A-Za-z]{0,3})?(\$)?([1-9][0-9]{0,6})?$/.exec(e);return t&&(t[2]||t[4])?[t[4]?(n=t[4],+n-1):null,t[2]?F(t[2]):null,!!t[3],!!t[1]]:null;var n}function q(e){let t=null,n=null,l=null,r=null,o=!1,s=!1,u=!1,a=!1;const[i,c,f,p,h]=e.split(/(\.?:\.?)/);if(p||h)return null;const g=D(!!c&&"."===c.at(0),!!c&&"."===c.at(-1)),d=j(i),m=f?j(f):null;if(!d||f&&!m)return null;if(null!=d[0]&&null!=d[1]?[t,n,o,s]=d:null==d[0]&&null!=d[1]?[,n,,s]=d:null!=d[0]&&null==d[1]&&([t,,o]=d),f)null!=m[0]&&null!=m[1]?[l,r,u,a]=m:null==m[0]&&null!=m[1]?[,r,,a]=m:null!=m[0]&&null==m[1]&&([l,,u]=m);else{if(null==t||null==n)return null;l=t,r=n,u=o,a=s}null!=r&&(null==n||null!=n&&r<n)&&([n,r,s,a]=[r,n,a,s]),null!=l&&(null==t||null!=t&&l<t)&&([t,l,o,u]=[l,t,u,o]);const x={top:t,left:n,bottom:l,right:r,$top:o,$left:s,$bottom:u,$right:a};return g&&(x.trim=g),x}function B(e){let{allowNamed:t=!0,allowTernary:n=!1,xlsx:l=!1}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const r=C(e,{allowNamed:t,allowTernary:n,xlsx:l,r1c1:!1});if(r&&(r.r0||r.name)){let e=null;return r.r0&&(e=q(r.r1?r.r0+r.operator+r.r1:r.r0)),e?l?{workbookName:r.workbookName,sheetName:r.sheetName,range:e}:{context:r.context,range:e}:r.name?l?{workbookName:r.workbookName,sheetName:r.sheetName,name:r.name}:{context:r.context,name:r.name}:null}return null}function Z(e){let{xlsx:t=!1}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const n=t?L(e):k(e);return n+(e.name?e.name:z(e.range))}function P(e){return null==e.top&&(e.top=0,e.$top=!1),null==e.bottom&&(e.bottom=1048575,e.$bottom=!1),null==e.left&&(e.left=0,e.$left=!1),null==e.right&&(e.right=16383,e.$right=!1),e}const X=/^\[('['#@[\]]|[^'#@[\]])+\]/i,W=/^([^#@[\]:]+)/i,G={headers:1,data:2,totals:4,all:8,"this row":16,"@":16},H=function(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return Object.freeze(t)},Y={0:H(),1:H("headers"),2:H("data"),4:H("totals"),8:H("all"),16:H("this row"),3:H("headers","data"),6:H("data","totals")},K=function(e){let t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],n=X.exec(e);if(n){const e=n[0].slice(1,-1).replace(/'(['#@[\]])/g,"$1");return[n[0],e]}return t&&(n=W.exec(e),n)?[n[0],n[0]]:null};function V(e){const t=[];let n,l,r=0,o=e,s=0;if(!(n=/^(\[\s*)/.exec(o)))return null;if(l=/^\[#([a-z ]+)\]/i.exec(o)){const e=l[1].toLowerCase();if(r+=l[0].length,!G[e])return null;s|=G[e]}else if(l=K(o,!1))r+=l[0].length,t.push(l[1]);else{let l=!0;for(o=o.slice(n[1].length),r+=n[1].length;l&&(n=/^\[#([a-z ]+)\](\s*,\s*)?/i.exec(o));){const e=n[1].toLowerCase();if(!G[e])return null;s|=G[e],o=o.slice(n[0].length),r+=n[0].length,l=!!n[2]}if(l&&(n=/^@/.exec(o))&&(s|=G["@"],o=o.slice(1),r+=1,l="]"!==o[0]),!(s in Y))return null;const u=l?K(e.slice(r)):null;if(u){if(r+=u[0].length,t.push(u[1]),o=e.slice(r),":"===o[0]){o=o.slice(1),r++;const e=K(o);if(!e)return null;r+=e[0].length,t.push(e[1])}l=!1}for(;" "===e[r];)r++;if(l||"]"!==e[r])return null;r++}const u=Y[s];return{columns:t,sections:u?u.concat():u,length:r,token:e.slice(0,r)}}function Q(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{xlsx:!1};const n=C(e,t);if(n&&n.struct){const e=V(n.struct);if(e&&e.length===n.struct.length)return t.xlsx?{workbookName:n.workbookName,sheetName:n.sheetName,table:n.name,columns:e.columns,sections:e.sections}:{context:n.context,table:n.name,columns:e.columns,sections:e.sections}}return null}function J(e){return e.replace(/([[\]#'@])/g,"'$1")}function ee(e){return!/^[a-zA-Z0-9\u00a1-\uffff]+$/.test(e)}function te(e){return e[0].toUpperCase()+e.slice(1).toLowerCase()}function ne(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const{xlsx:n,thisRow:l}=t;let r=n?L(e):k(e);e.table&&(r+=e.table);const o=e.columns?.length??0,s=e.sections?.length??0;if(1!==s||o)if(s||1!==o){r+="[";const t=!l&&1===s&&"this row"===e.sections[0].toLowerCase();t?r+="@":s&&(r+=e.sections.map((e=>`[#${te(e)}]`)).join(","),o&&(r+=",")),t&&1===e.columns.length&&!ee(e.columns[0])?r+=J(e.columns[0]):o&&(r+=e.columns.slice(0,2).map((e=>`[${J(e)}]`)).join(":")),r+="]"}else r+=`[${J(e.columns[0])}]`;else r+=`[#${te(e.sections[0])}]`;return r}const le=/^(?!!)(\[(?:[^\]])+\])?([0-9A-Za-z._¡¤§¨ª\u00ad¯-\uffff]+)?(?=!)/,re=/^'(?:''|[^'])*('|$)(?=!)/,oe="\\$?[A-Z]{1,3}\\$?[1-9][0-9]{0,6}",se="\\$?[A-Z]{1,3}",ue="\\$?[1-9][0-9]{0,6}",ae="(?![a-z0-9_\\u00a1-\\uffff])",ie=new RegExp(`^${se}\\.?:\\.?${se}${ae}`,"i"),ce=new RegExp(`^${ue}\\.?:\\.?${ue}${ae}`,"i"),fe=new RegExp(`^${oe}${ae}`,"i"),pe=new RegExp(`^((${se}|${ue})\\.?:\\.?${oe}|${oe}\\.?:\\.?(${se}|${ue}))(?![\\w($.])`,"i"),he="(?:R(?:\\[[+-]?\\d+\\]|[1-9][0-9]{0,6})?)",ge="(?:C(?:\\[[+-]?\\d+\\]|[1-9][0-9]{0,4})?)",de=new RegExp(`^${ge}(\\.?:\\.?${ge})?${ae}`,"i"),me=new RegExp(`^${he}(\\.?:\\.?${he})?${ae}`,"i"),xe=new RegExp(`^(?:(?=[RC])${he}${ge})${ae}`,"i"),ye=new RegExp(`^(${he}${ge}(\\.?:\\.?${ge}|\\.?:\\.?${he})(?![[\\d])|(${he}|${ge})(\\.?:\\.?${he}${ge}))${ae}`,"i"),ve=/^[a-zA-Z\\_\u00a1-\uffff][a-zA-Z0-9\\_.?\u00a1-\uffff]{0,254}/i;function $e(e,t){return n=>{const l=t.exec(n);if(l)return{type:e,value:l[0]}}}function we(e){const t=ve.exec(e);if(t){const e=t[0].toLowerCase();return"\\"===e[0]&&t[0].length<3||("r"===e||"c"===e)?null:{type:o,value:t[0]}}}const Ne=/^'(?:[^[\]]+?)?(?:\[(.+?)\])?(?:[^[\]]+?)'$/,Ee=/^'\[(.+?)\]'$/;function Re(e,t){const l=re.exec(e);if(l){const e=l[0];if(t.xlsx&&Ee.test(e)||Ne.test(e))return{type:"context_quote",value:e}}const r=le.exec(e);if(r){const[,e,l]=r;if(e&&l||l||e&&!l&&t.xlsx)return{type:n,value:r[0]}}}function be(e){const t=V(e);if(t){let n=t.length;for(;" "===e[n];)n++;if("!"!==e[n])return{type:s,value:t.token}}return null}const Ae=/([RC])(\[?)(-?\d+)/gi,Ce=/(\d+|[a-zA-Z]+)/gi;function Te(e,t){let n,o;if(t.r1c1){if(t.allowTernary&&(n=ye.exec(e))?o={type:r,value:n[0]}:(n=xe.exec(e))?o={type:"range",value:n[0]}:((n=me.exec(e))||(n=de.exec(e)))&&(o={type:l,value:n[0]}),o){for(Ae.lastIndex=0;null!==(n=Ae.exec(o.value));){const e=("R"===n[1]?1048575:16383)+(n[2]?0:1),t=parseInt(n[3],10);if(t>e||t<-e)return null}return o}}else if(t.allowTernary&&(n=pe.exec(e))?o={type:r,value:n[0]}:(n=ie.exec(e))||(n=ce.exec(e))?o={type:l,value:n[0]}:(n=fe.exec(e))&&(o={type:"range",value:n[0]}),o){for(Ce.lastIndex=0;null!==(n=Ce.exec(o.value));)if(/^\d/.test(n[1])){if(parseInt(n[1],10)-1>1048575)return null}else if(F(n[1])>16383)return null;return o}}const ke=[$e(t,/^#(NAME\?|FIELD!|CALC!|VALUE!|REF!|DIV\/0!|NULL!|NUM!|N\/A|GETTING_DATA\b|SPILL!|UNKNOWN!|FIELD\b|CALC\b|SYNTAX\?|ERROR!|CONNECT!|BLOCKED!|EXTERNAL!)/i),$e("operator-trim",/^(\.:\.|\.:|:\.)/),$e(e,/^(<=|>=|<>|[-+/*^%&<>=]|[{},;]|[()]|@|:|!|#)/),$e("func",/^[A-Z_]+[A-Z\d_.]*(?=\()/i),$e("bool",/^(TRUE|FALSE)\b/i),$e("newline",/^\n+/),$e("whitespace",/^[ \f\r\t\v\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]+/),$e("string",/^"(?:""|[^"])*("|$)/),Re,Te,be,$e("number",/^(?:\d+(\.\d+)?(?:[eE][+-]?\d+)?|\d+)/),we],Le=[function(t,n){if(n.r1c1)return"!"===t[0]?{type:e,value:t[0]}:null;const l=/^(!|\.?:\.?)/.exec(t);return l?{type:e,value:l[1]}:null},Re,Te,be,we],Ie={};function _e(e,t){if(e.length){const n=e[0];t[n]=t[n]||{},_e(e.slice(1),t[n])}else t.$=!0}[["range",":","range"],["range",".:","range"],["range",":.","range"],["range",".:.","range"],["range"],[l],[r],[n,"!","range",":","range"],[n,"!","range",".:","range"],[n,"!","range",":.","range"],[n,"!","range",".:.","range"],[n,"!","range"],[n,"!",l],[n,"!",r],["context_quote","!","range",":","range"],["context_quote","!","range",".:","range"],["context_quote","!","range",":.","range"],["context_quote","!","range",".:.","range"],["context_quote","!","range"],["context_quote","!",l],["context_quote","!",r],[o],[n,"!",o],["context_quote","!",o],[s],[o,s],[n,"!",o,s],["context_quote","!",o,s]].forEach((e=>_e(e.concat().reverse(),Ie)));const Oe=function(t,n,l){let r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:0;const o=t[l-r];if(o){const s=o.type===e?o.value:o.type;if(s in n)return Oe(t,n[s],l,r+1)}return n.$?r:0};function Ue(e){const t=[];for(let n=e.length-1;n>=0;n--){let l=e[n];const r=Oe(e,Ie,n);if(r){const t=e.slice(n-r+1,n+1);l={...l},l.value=t.map((e=>e.value)).join(""),l.loc&&t[0].loc&&(l.loc[0]=t[0].loc[0]),n-=r-1}t.unshift(l)}return t}const Fe=(e,t)=>e&&e.type===t,Se={withLocation:!1,mergeRefs:!0,allowTernary:!1,negativeNumbers:!0,r1c1:!1},Me=e=>e.type===o||"func"===e.type,De=t=>!Fe(t,e)||"%"===t.value||"}"===t.value||")"===t.value||"#"===t.value;function ze(t){let n,l=0,r=0;for(const s of t){if(s.type===e)if("("===s.value){if(r++,"func"===n.type){const e=n.value.toLowerCase();"lambda"!==e&&"let"!==e||(l=r)}}else")"===s.value&&(r--,r<l&&(l=0));else l&&s.type===u&&/^[rc]$/.test(s.value)&&(s.type=o);n=s}return t}function je(t,n){let l=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const r=Object.assign({},Se,l),{withLocation:o,mergeRefs:s,negativeNumbers:a}=r,i=[];let c=0,f=0,p=0;const h=[];let g=null,d=null,m=null;const x=e=>{const t=e.type===u,n=m&&m.type===u;m&&(t&&n||t&&Me(m)||n&&Me(e))?(m.value+=e.value,m.type=u,o&&(m.loc[1]=e.loc[1])):("operator-trim"===e.type&&(h.push(i.length),e.type=u),i.push(e),m=e,"whitespace"!==e.type&&"newline"!==e.type&&(d=g,g=e))};if("="===t.at(0)){c++,x({type:"fx_prefix",value:"=",...o?{loc:[0,1]}:{}})}for(;c<t.length;){const l=c,s=t.slice(c);let h="",y="";for(let e=0;e<n.length;e++){const t=n[e](s,r);if(t){h=t.type,y=t.value,c+=y.length;break}}h||(h=u,y=t[c],c++);const v={type:h,value:y,...o?{loc:[l,c]}:{}};if(m&&"func"===m.type&&"("===y){const e=m.value.toLowerCase();"lambda"!==e&&"let"!==e||f++}if(h===u){const e=y.toLowerCase();p+="r"===e||"c"===e?1:0}if("string"===h){const e=y.length;if('""'===y);else if('"'===y||'"'!==y[e-1])v.unterminated=!0;else if('""'!==y&&'"'===y[e-2]){let t=e-1;for(;'"'===y[t];)t--;!(t+1)^(e-t+1)%2==0&&(v.unterminated=!0)}}if(a&&"number"===h){const t=m;if(t&&Fe(t,e)&&"-"===t.value&&(!d||Fe(d,"fx_prefix")||!De(d))){const e=i.pop();v.value="-"+y,o&&(v.loc[0]=e.loc[0]),g=d,m=i[i.length-1]}}x(v)}p&&f&&ze(i);for(const t of h){const n=i[t-1],l=i[t-1];n&&"range"===n.type&&l&&"range"===l.type?i[t].type=e:i[t].type=u}return s?Ue(i):i}function qe(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return je(e,ke,t)}function Be(e){return!!e&&("range"===e.type||e.type===l||e.type===r)}function Ze(e){return!!e&&("range"===e.type||e.type===l||e.type===r||e.type===s||e.type===o)}function Pe(e){return!!e&&("bool"===e.type||e.type===t||"number"===e.type||"string"===e.type)}function Xe(e){return!!e&&e.type===t}function We(e){return!!e&&("whitespace"===e.type||"newline"===e.type)}function Ge(e){return!!e&&"func"===e.type}function He(e){return!!e&&"fx_prefix"===e.type}function Ye(t){return!!t&&t.type===e}const Ke="(END)",Ve=["ANCHORARRAY","CHOOSE","DROP","IF","IFS","INDEX","INDIRECT","LAMBDA","LET","OFFSET","REDUCE","SINGLE","SWITCH","TAKE","TRIMRANGE","XLOOKUP"],Qe=e=>Ve.includes(e.toUpperCase()),Je=function(e){let t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];const n=(e&&e.value)+"";return!!Ze(e)||(!(!t||!Ye(e)||":"!==n&&","!==n&&n.trim())||(!(!Ge(e)||!Qe(n))||!(!Xe(e)||"#REF!"!==n)))},et=e=>!!e&&(e.type===c||("ErrorLiteral"===e.type||e.type===t)&&"#REF!"===e.value||e.type===i&&(":"===e.operator||" "===e.operator||","===e.operator)||Ze(e)||e.type===f&&Qe(e.callee.name)),tt={};let nt,lt,rt,ot=!1,st=!1;function ut(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;const n=new Error(e);throw n.source=lt.map((e=>e.value)).join(""),n.sourceOffset=lt.slice(0,t??rt).reduce(((e,t)=>e+t.value.length),0),n}function at(){let e,t=arguments.length>0&&void 0!==arguments[0]&&arguments[0],n=rt;do{e=lt[++n]}while(e&&(We(e)||Ye(e)&&"("===e.value));return Je(e,t)}function it(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;if(e&&e!==nt.id&&ut(`Expected ${e} but got ${nt.id}`),We(lt[rt])){const e=et(t),n=e&&at(!1),l=e&&"("===lt[rt+1].value;if(!n&&!l)for(;We(lt[rt]);)rt++}if(rt>=lt.length)return void(nt=tt[Ke]);const n=lt[rt];let l;return rt+=1,n.unterminated&&ut("Encountered an unterminated token"),Ye(n)?(l=tt[n.value],l||ut(`Unknown operator ${n.value}`)):We(n)?l=tt["(WHITESPACE)"]:Pe(n)?l=tt.Literal:Ze(n)?l=tt[c]:Ge(n)?l=tt["(FUNCTION)"]:ut(`Unexpected ${n.type} token: ${n.value}`),nt=Object.create(l),nt.type=n.type,nt.value=n.value,n.loc&&(nt.loc=[...n.loc]),nt}function ct(e){let t=nt;it(null,t);let n=t.nud();for(;e<nt.lbp;)t=nt,it(null,t),n=t.led(n);return n}const ft={nud:()=>ut("Invalid syntax"),led:()=>ut("Missing operator")};function pt(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=tt[e];return n?t>=n.lbp&&(n.lbp=t):(n={...ft},n.id=e,n.value=e,n.lbp=t,tt[e]=n),n}function ht(e,t,n){const l=pt(e,t);return l.led=n||function(e){this.type=i,this.operator=this.value,delete this.value;const n=ct(t);return this.arguments=[e,n],this.loc&&(this.loc=[e.loc[0],n.loc[1]]),this},l}function gt(e,t){const n=pt(e,0);return n.lbp=70,n.led=t||function(e){return this.type=a,this.operator=this.value,delete this.value,this.arguments=[e],this.loc&&(this.loc[0]=e.loc[0]),this},n}function dt(e,t){const n=pt(e);return n.nud=t||function(){this.type=a,this.operator=this.value,delete this.value;const e=ct(70);return this.arguments=[e],this.loc&&(this.loc[1]=e.loc[1]),this},n}function mt(e,t){return ht(e,t,(function(n){et(n)||ut(`Unexpected ${e} operator`);const l=ct(t);return et(l)||ut(`Unexpected ${nt.type} following ${this.id}`),this.type=i,this.operator=this.value.trim()?this.value:" ",delete this.value,this.arguments=[n,l],this.loc&&(this.loc=[n.loc[0],l.loc[1]]),this}))}pt(Ke),mt(":",80);const xt=mt(",",80);mt("(WHITESPACE)",80);const yt=e=>{const t=xt.lbp>0;return null!=e&&(xt.lbp=e?80:0),t};function vt(e){const t=[],n={};let l,r=!1;const o=yt(!1);if(")"!==nt.id)for(;!r;){We(nt)&&it();const e=rt,o=ct(0);if(","===nt.id){if(o.type===c&&"name"===o.kind){const e=o.value.toLowerCase();e in n&&ut("Duplicate name: "+o.value),n[e]=1;const l={type:"Identifier",name:o.value};o.loc&&(l.loc=o.loc),t.push(l)}else rt=e,ut("LAMBDA argument is not a name");it(",")}else l=o,r=!0}return yt(o),delete this.value,this.type="LambdaExpression",this.params=t,this.body=l||null,e.loc&&(this.loc=[e.loc[0],nt.loc[1]]),it(")",this),this}function $t(e){const t=[],n=[],l={};let r,o=0;const s=(e,s)=>{if(r&&ut("Unexpected argument following calculation"),s&&o>=2)r=e;else{if(!(o%2))if(e&&e.type===c&&"name"===e.kind){const n=e.value.toLowerCase();n in l&&ut("Duplicate name: "+e.value),l[n]=1,t.push({type:"Identifier",name:e.value,loc:e.loc})}else o>=2?r=e:ut("Argument is not a name");else n.push(e)}o++},u=yt(!1);let a=!1;if(")"!==nt.id){for(;")"!==nt.id;)if(We(nt)&&it(),","===nt.id)s(null),a=!0,it();else{s(ct(0),","!==nt.id),a=!1,","===nt.id&&(it(","),a=!0)}yt(u)}a&&s(null,!0),void 0===r&&ut("Unexpected end of arguments"),yt(u),delete this.value,this.type=p,this.declarations=[],t.length||ut("Unexpected end of arguments");for(let e=0;e<t.length;e++){const l={type:"LetDeclarator",id:t[e],init:n[e],loc:t[e].loc&&[t[e].loc[0],n[e].loc[1]]};this.declarations.push(l)}return this.body=r,e.loc&&(this.loc=[e.loc[0],nt.loc[1]]),it(")",this),this}function wt(){let e=1;return()=>"fxg"+e++}function Nt(e,t){return null==e&&null==t||e===t}function Et(e,t){if(Array.isArray(e)!==Array.isArray(t)||e.length!==t.length)return!1;for(let n=0;n<e.length;n++)if(!Nt(e[n],t[n]))return!1;return!0}function Rt(e,t){return!e&&!t||String(e).toLowerCase()===String(t).toLowerCase()}function bt(e,t){if((e.name||t.name)&&e.name!==t.name)return!1;if(e.columns||t.columns){if(e.table!==t.table)return!1;if(!Et(e.columns,t.columns))return!1;if(!Et(e.sections,t.sections))return!1}return!!(!e.range&&!t.range||Nt(e.range.top,t.range.top)&&Nt(e.range.bottom,t.range.bottom)&&Nt(e.range.left,t.range.left)&&Nt(e.range.right,t.range.right))&&!(!Rt(e.workbookName,t.workbookName)||!Rt(e.sheetName,t.sheetName))}function At(e,t,n){return e.sheetName||(e.sheetName=t),e.workbookName||(e.workbookName=n),e}gt("%"),gt("#",(function(e){return et(e)||ut("# expects a reference"),this.type=a,this.operator=this.value,delete this.value,this.arguments=[e],this})),dt("+"),dt("-"),dt("@"),ht("^",50),ht("*",40),ht("/",40),ht("+",30),ht("-",30),ht("&",20),ht("=",10),ht("<",10),ht(">",10),ht("<=",10),ht(">=",10),ht("<>",10),pt("Literal").nud=function(){const{type:e,value:n}=this;if(this.type="Literal",this.raw=n,"number"===e)this.value=+n;else if("bool"===e)this.value="TRUE"===n.toUpperCase();else if(e===t)this.type="ErrorLiteral",this.value=n.toUpperCase();else{if("string"!==e)throw new Error("Unsupported literal type: "+e);this.value=n.slice(1,-1).replace(/""/g,'"')}return this},pt(c).nud=function(){return this.type===o?this.kind="name":this.type===s?this.kind="table":this.type===l?this.kind="beam":this.kind="range",this.type=c,this},pt(")"),dt("(",(function(){const e=yt(!0),t=ct(0);return it(")",t),yt(e),t})),pt("(FUNCTION)").nud=function(){return this},ht("(",90,(function(e){let t={type:"Identifier",name:e.value};"(FUNCTION)"!==e.id&&("LambdaExpression"===e.type||e.type===f||e.type===p||e.type===c||e.type===a&&"#"===e.value||"ErrorLiteral"===e.type&&"#REF!"===e.value?t=e:ut("Unexpected call",rt-1));const n=e.value.toLowerCase();if("lambda"===n)return vt.call(this,e);if("let"===n)return $t.call(this,e);const l=[];let r=!1;if(")"!==nt.id){const e=yt(!1);for(;")"!==nt.id;)if(We(nt)&&it(),","===nt.id)l.push(null),r=!0,it();else{const e=ct(0);l.push(e),r=!1,","===nt.id&&(it(","),r=!0)}yt(e)}r&&l.push(null);const o=nt;return delete this.value,this.type=f,this.callee=t,e.loc&&(this.callee.loc=[...e.loc]),this.arguments=l,e.loc&&(this.loc=[e.loc[0],o.loc[1]]),it(")",this),this})),pt("}"),pt(";"),dt("{",(function(){"}"===nt.id&&ut("Unexpected empty array");let e=[],t=!1;const n=[e],l=yt(!1);for(;!t;){if(We(nt)&&it(),Pe(nt))e.push(tt.Literal.nud.call(nt)),it();else if(ot&&et(nt))e.push(tt[c].nud.call(nt)),it();else if(st&&Ge(nt)){const t=ct(0);e.push(t)}else ut(`Unexpected ${nt.type} in array: ${nt.value}`);","===nt.id?it(","):";"===nt.id?(it(";"),e=[],n.push(e)):t=!0}const r=nt;return it("}"),yt(l),this.type="ArrayExpression",this.elements=n,this.loc&&(this.loc[1]=r.loc[1]),delete this.value,this}));const Ct=(e,t,n)=>Math.min(Math.max(t,e),n);function Tt(e,t){return t?String(e+1):e?"["+e+"]":""}function kt(e){let{r0:t,c0:n,r1:l,c1:r}=e;const{$c0:o,$c1:s,$r0:u,$r1:a}=e,i=null==t,c=null==n;let f=null==l,p=null==r;const h=M(e.trim),g=!!e.trim;t=Ct(u?0:-1048575,0|t,1048575),n=Ct(o?0:-16383,0|n,16383),!i&&f&&!c&&p?(l=t,f=!1,r=n,p=!1):(l=Ct(a?0:-1048575,0|l,1048575),r=Ct(s?0:-16383,0|r,16383));if(0===t&&l>=1048575&&!c&&!p||i&&f){const e=Tt(n,o),t=Tt(r,s);return"C"+(e!==t||g?e+h+"C"+t:e)}if(0===n&&r>=16383&&!i&&!f||c&&p){const e=Tt(t,u),n=Tt(l,a);return"R"+(e!==n||g?e+h+"R"+n:e)}const d=Tt(t,u),m=Tt(l,a),x=Tt(n,o),y=Tt(r,s);return i||f||c||p?(i?"":"R"+d)+(c?"":"C"+x)+h+(f?"":"R"+m)+(p?"":"C"+y):d!==m||x!==y?"R"+d+"C"+x+h+"R"+m+"C"+y:"R"+d+"C"+x}function Lt(e){let t=null,n=null,l=null,r=null;const o=/^R(?:\[([+-]?\d+)\]|(\d+))?/.exec(e);o&&(o[1]?(t=parseInt(o[1],10),l=!1):o[2]?(t=parseInt(o[2],10)-1,l=!0):(t=0,l=!1),e=e.slice(o[0].length));const s=/^C(?:\[([+-]?\d+)\]|(\d+))?/.exec(e);return s&&(s[1]?(n=parseInt(s[1],10),r=!1):s[2]?(n=parseInt(s[2],10)-1,r=!0):(n=0,r=!1),e=e.slice(s[0].length)),!o&&!s||e.length?null:[t,n,l,r]}function It(e){let t=null;const[n,l,r,o]=e.split(/(\.?:\.?)/);if(o)return null;const s=Lt(n),u=D(!!l&&"."===l.at(0),!!l&&"."===l.at(-1));if(s){const[e,n,l,o]=s;if(r){const s=Lt(r);if(!s)return null;{t={};const[r,u,a,i]=s;null!=e&&null!=r?(t.r0=l===a?Math.min(e,r):e,t.$r0=l,t.r1=l===a?Math.max(e,r):r,t.$r1=a):null!=e&&null==r?(t.r0=e,t.$r0=l,t.r1=null,t.$r1=l):null==e&&null!=r?(t.r0=r,t.$r0=a,t.r1=null,t.$r1=a):null==e&&null==r&&(t.r0=null,t.$r0=!1,t.r1=null,t.$r1=!1),null!=n&&null!=u?(t.c0=o===i?Math.min(n,u):n,t.$c0=o,t.c1=o===i?Math.max(n,u):u,t.$c1=i):null!=n&&null==u?(t.c0=n,t.$c0=o,t.c1=null,t.$c1=o):null==n&&null!=u?(t.c0=u,t.$c0=i,t.c1=null,t.$c1=i):null==n&&null==u&&(t.c0=null,t.$c0=!1,t.c1=null,t.$c1=!1)}}else t=null!=e&&null==n?{r0:e,c0:null,r1:e,c1:null,$r0:l,$c0:!1,$r1:l,$c1:!1}:null==e&&null!=n?{r0:null,c0:n,r1:null,c1:n,$r0:!1,$c0:o,$r1:!1,$c1:o}:{r0:e||0,c0:n||0,r1:e||0,c1:n||0,$r0:l||!1,$c0:o||!1,$r1:l||!1,$c1:o||!1}}return t&&u&&(t.trim=u),t}function _t(e){let{allowNamed:t=!0,allowTernary:n=!1,xlsx:l=!1}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const r=C(e,{allowNamed:t,allowTernary:n,xlsx:l,r1c1:!0});if(r&&(r.r0||r.name)){const e=r.r1?It(r.r0+r.operator+r.r1):It(r.r0);return e?l?{workbookName:r.workbookName,sheetName:r.sheetName,range:e}:{context:r.context,range:e}:r.name?l?{workbookName:r.workbookName,sheetName:r.sheetName,name:r.name}:{context:r.context,name:r.name}:null}return null}function Ot(e){let{xlsx:t=!1}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const n=t?L(e):k(e);return n+(e.name?e.name:kt(e.range))}const Ut=(e,t,n)=>null==t?null:e?t:t-n,Ft={withLocation:!1,mergeRefs:!1,allowTernary:!0,r1c1:!1};function St(e,t,n,l){let r=!(arguments.length>4&&void 0!==arguments[4])||arguments[4],o=e;if(null!=o&&!t){if(o=n+e,o<0){if(!r)return NaN;o=l+o+1}if(o>l){if(!r)return NaN;o-=l+1}}return o}const Mt={wrapEdges:!0,mergeRefs:!0,allowTernary:!0,xlsx:!1};const Dt=Object.freeze({OPERATOR:e,BOOLEAN:"bool",ERROR:t,NUMBER:"number",FUNCTION:"func",NEWLINE:"newline",WHITESPACE:"whitespace",STRING:"string",CONTEXT:n,CONTEXT_QUOTE:"context_quote",REF_RANGE:"range",REF_BEAM:l,REF_TERNARY:r,REF_NAMED:o,REF_STRUCT:s,FX_PREFIX:"fx_prefix",UNKNOWN:u}),zt=Object.freeze({UNARY:a,BINARY:i,REFERENCE:c,LITERAL:"Literal",ERROR:"ErrorLiteral",CALL:f,ARRAY:"ArrayExpression",IDENTIFIER:"Identifier"});exports.MAX_COLS=16383,exports.MAX_ROWS=1048575,exports.addA1RangeBounds=P,exports.addTokenMeta=function(e){let{sheetName:t="",workbookName:n=""}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const o=[];let a=null;const i=wt(),c=[],f=()=>o.length+(a?1:0);return e.forEach(((e,p)=>{if(e.index=p,e.depth=f(),"("===e.value)o.push(e),e.depth=f();else if(")"===e.value){const t=o.pop();if(t){const n=i();e.groupId=n,e.depth=t.depth,t.groupId=n}else e.error=!0}else if("{"===e.value)a?e.error=!0:(a=e,e.depth=f());else if("}"===e.value){if(a){const t=i();e.groupId=t,e.depth=a.depth,a.groupId=t}else e.error=!0;a=null}else if("range"===e.type||e.type===l||e.type===r||e.type===s){const l=e.type===s?Q(e.value,{xlsx:!0}):B(e.value,{allowTernary:!0,xlsx:!0});if(l&&(l.range||l.columns)){l.source=e.value,At(l,t,n);const r=c.find((e=>bt(e,l)));r?e.groupId=r.groupId:(l.groupId=i(),e.groupId=l.groupId,c.push(l))}}else e.type===u&&(e.error=!0)})),e},exports.fixRanges=function e(t){let n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{addBounds:!1};if("string"==typeof t)return e(qe(t,n),n).map((e=>e.value)).join("");if(!Array.isArray(t))throw new Error("fixRanges expects an array of tokens");const{addBounds:l,r1c1:r,xlsx:o,thisRow:u}=n;if(r)throw new Error("fixRanges does not have an R1C1 mode");let a=0;return t.map((e=>{const t={...e};e.loc&&(t.loc=[...e.loc]);let n=0;if(t.type===s){const e=ne(Q(t.value,{xlsx:o}),{xlsx:o,thisRow:u});n=e.length-t.value.length,t.value=e}else if(Be(t)){const e=B(t.value,{xlsx:o,allowTernary:!0}),r=e.range;l&&P(r);const s=Z(e,{xlsx:o});n=s.length-t.value.length,t.value=s}return a||n?(t.loc&&(t.loc[0]+=a),a+=n,t.loc&&(t.loc[1]+=a)):a+=n,t}))},exports.fromCol=F,exports.isError=Xe,exports.isFunction=Ge,exports.isFxPrefix=He,exports.isLiteral=Pe,exports.isOperator=Ye,exports.isRange=Be,exports.isReference=Ze,exports.isWhitespace=We,exports.mergeRefTokens=Ue,exports.nodeTypes=zt,exports.parse=function(e,t){if("string"==typeof e)lt=qe(e,{withLocation:!1,...t,mergeRefs:!0});else{if(!Array.isArray(e))throw new Error("Parse requires a string or array of tokens.");lt=e}for(ot=t?.permitArrayRanges,st=t?.permitArrayCalls,rt=0;We(lt[rt])||He(lt[rt]);)rt++;it(),yt(!0);const n=ct(0);return it(Ke),n},exports.parseA1Ref=B,exports.parseR1C1Ref=_t,exports.parseStructRef=Q,exports.stringifyA1Ref=Z,exports.stringifyR1C1Ref=Ot,exports.stringifyStructRef=ne,exports.toCol=S,exports.tokenTypes=Dt,exports.tokenize=qe,exports.translateToA1=function(e,n){let l=arguments.length>2&&void 0!==arguments[2]?arguments[2]:Mt;const r=q(n),o="string"==typeof e,s={...Mt,...l},u=o?qe(e,{withLocation:!1,mergeRefs:s.mergeRefs,xlsx:s.xlsx,allowTernary:s.allowTernary,r1c1:!0}):e;let a=0;const i={xlsx:s.xlsx,allowTernary:s.allowTernary};return u.forEach((e=>{if(Be(e)){const n=e.value,l=_t(n,i),o=l.range,u={},c=St(o.r0,o.$r0,r.top,1048575,s.wrapEdges),f=St(o.r1,o.$r1,r.top,1048575,s.wrapEdges);c>f?(u.top=f,u.$top=o.$r1,u.bottom=c,u.$bottom=o.$r0):(u.top=c,u.$top=o.$r0,u.bottom=f,u.$bottom=o.$r1);const p=St(o.c0,o.$c0,r.left,16383,s.wrapEdges),h=St(o.c1,o.$c1,r.left,16383,s.wrapEdges);p>h?(u.left=h,u.$left=o.$c1,u.right=p,u.$right=o.$c0):(u.left=p,u.$left=o.$c0,u.right=h,u.$right=o.$c1),o.trim&&(u.trim=o.trim),isNaN(c)||isNaN(f)||isNaN(p)||isNaN(h)?(e.type=t,e.value="#REF!",delete e.groupId):(l.range=u,e.value=Z(l,i)),e.loc&&(e.loc[0]+=a,a+=e.value.length-n.length,e.loc[1]+=a)}else a&&e.loc&&(e.loc[0]+=a,e.loc[1]+=a)})),o?u.map((e=>e.value)).join(""):u},exports.translateToR1C1=function(e,t){let{xlsx:n=!1,allowTernary:l=!0}=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const{top:r,left:o}=q(t),s="string"==typeof e,u=s?qe(e,{...Ft,xlsx:n,allowTernary:l}):e;let a=0;const i={xlsx:n,allowTernary:l};return u.forEach((e=>{if(Be(e)){const t=e.value,n=B(t,i),l=n.range,s={};s.r0=Ut(l.$top,l.top,r),s.r1=Ut(l.$bottom,l.bottom,r),s.c0=Ut(l.$left,l.left,o),s.c1=Ut(l.$right,l.right,o),s.$r0=l.$top,s.$r1=l.$bottom,s.$c0=l.$left,s.$c1=l.$right,l.trim&&(s.trim=l.trim),n.range=s,e.value=Ot(n,i),e.loc&&(e.loc[0]+=a,a+=e.value.length-t.length,e.loc[1]+=a)}else a&&e.loc&&(e.loc[0]+=a,e.loc[1]+=a)})),s?u.map((e=>e.value)).join(""):u};
2
2
  //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZnguanMiLCJzb3VyY2VzIjpbXSwic291cmNlc0NvbnRlbnQiOltdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIn0=
package/docs/API.md CHANGED
@@ -178,6 +178,7 @@ Returns the same formula with the ranges updated. If an array of tokens was supp
178
178
  | formula | `string` \| `Array<Token>` | | A string (an Excel formula) or a token list that should be adjusted. |
179
179
  | [options] | `object` | `{}` | Options |
180
180
  | [options].addBounds | `boolean` | `false` | Fill in any undefined bounds of range objects. Top to 0, bottom to 1048575, left to 0, and right to 16383. |
181
+ | [options].thisRow | `boolean` | `false` | Enforces using the `[#This Row]` instead of the `@` shorthand when serializing structured ranges. |
181
182
  | [options].xlsx | `boolean` | `false` | Switches to the `[1]Sheet1!A1` or `[1]!name` prefix syntax form for external workbooks. See: [Prefixes.md](./Prefixes.md) |
182
183
 
183
184
  ##### Returns
@@ -587,11 +588,12 @@ stringifyStructRef({
587
588
 
588
589
  ##### Parameters
589
590
 
590
- | Name | Type | Default | Description |
591
- | -------------- | ------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------- |
592
- | refObject | [`ReferenceStruct`](#ReferenceStruct) | | A structured reference object |
593
- | [options] | `object` | `{}` | Options |
594
- | [options].xlsx | `boolean` | `false` | Switches to the `[1]Sheet1!A1` or `[1]!name` prefix syntax form for external workbooks. See: [Prefixes.md](./Prefixes.md) |
591
+ | Name | Type | Default | Description |
592
+ | ----------------- | ------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------- |
593
+ | refObject | [`ReferenceStruct`](#ReferenceStruct) | | A structured reference object |
594
+ | [options] | `object` | `{}` | Options |
595
+ | [options].thisRow | `boolean` | `false` | Enforces using the `[#This Row]` instead of the `@` shorthand when serializing structured ranges. |
596
+ | [options].xlsx | `boolean` | `false` | Switches to the `[1]Sheet1!A1` or `[1]!name` prefix syntax form for external workbooks. See: [Prefixes.md](./Prefixes.md) |
595
597
 
596
598
  ##### Returns
597
599
 
@@ -913,16 +915,17 @@ A range in A1 style coordinates.
913
915
 
914
916
  ##### Properties
915
917
 
916
- | Name | Type | Description |
917
- | --------- | ------------------- | ----------------------------------------- |
918
- | [$bottom] | `boolean` \| `null` | Signifies that bottom is a "locked" value |
919
- | [$left] | `boolean` \| `null` | Signifies that left is a "locked" value |
920
- | [$right] | `boolean` \| `null` | Signifies that right is a "locked" value |
921
- | [$top] | `boolean` \| `null` | Signifies that top is a "locked" value |
922
- | [bottom] | `number` \| `null` | Bottom row of the range |
923
- | [left] | `number` \| `null` | Left column of the range |
924
- | [right] | `number` \| `null` | Right column of the range |
925
- | [top] | `number` \| `null` | Top row of the range |
918
+ | Name | Type | Description |
919
+ | --------- | -------------------------------- | ---------------------------------------------------------------------------------------------- |
920
+ | [$bottom] | `boolean` \| `null` | Signifies that bottom is a "locked" value |
921
+ | [$left] | `boolean` \| `null` | Signifies that left is a "locked" value |
922
+ | [$right] | `boolean` \| `null` | Signifies that right is a "locked" value |
923
+ | [$top] | `boolean` \| `null` | Signifies that top is a "locked" value |
924
+ | [bottom] | `number` \| `null` | Bottom row of the range |
925
+ | [left] | `number` \| `null` | Left column of the range |
926
+ | [right] | `number` \| `null` | Right column of the range |
927
+ | [top] | `number` \| `null` | Top row of the range |
928
+ | [trim] | `"head"` \| `"tail"` \| `"both"` | Should empty rows and columns at the top/left or bottom/right be discarded when range is read? |
926
929
 
927
930
  ---
928
931
 
package/lib/a1.js CHANGED
@@ -71,13 +71,41 @@ export function toRow (top) {
71
71
  }
72
72
 
73
73
  export function toRelative (range) {
74
- const { top, left, bottom, right } = range;
75
- return { top, left, bottom, right, $left: false, $right: false, $top: false, $bottom: false };
74
+ return Object.assign({}, range, { $left: false, $right: false, $top: false, $bottom: false });
76
75
  }
77
76
 
78
77
  export function toAbsolute (range) {
79
- const { top, left, bottom, right } = range;
80
- return { top, left, bottom, right, $left: true, $right: true, $top: true, $bottom: true };
78
+ return Object.assign({}, range, { $left: true, $right: true, $top: true, $bottom: true });
79
+ }
80
+
81
+ /**
82
+ * @ignore
83
+ * @param {'head' | 'tail' | 'both' | null | undefined} trim Does the range have trimming?
84
+ * @returns {string} The appropriate range join operator
85
+ */
86
+ export function rangeOperator (trim) {
87
+ if (trim === 'both') {
88
+ return '.:.';
89
+ }
90
+ else if (trim === 'head') {
91
+ return '.:';
92
+ }
93
+ else if (trim === 'tail') {
94
+ return ':.';
95
+ }
96
+ return ':';
97
+ }
98
+
99
+ export function trimDirection (head, tail) {
100
+ if (head && tail) {
101
+ return 'both';
102
+ }
103
+ if (head) {
104
+ return 'head';
105
+ }
106
+ if (tail) {
107
+ return 'tail';
108
+ }
81
109
  }
82
110
 
83
111
  /**
@@ -90,7 +118,8 @@ export function toAbsolute (range) {
90
118
  * @returns {string} An A1-style string represenation of a range
91
119
  */
92
120
  export function toA1 (range) {
93
- let { top, left, bottom, right } = range;
121
+ // eslint-disable-next-line prefer-const
122
+ let { top, left, bottom, right, trim } = range;
94
123
  const { $left, $right, $top, $bottom } = range;
95
124
  const noLeft = left == null;
96
125
  const noRight = right == null;
@@ -107,37 +136,38 @@ export function toA1 (range) {
107
136
  bottom = clamp(0, bottom | 0, MAX_ROWS);
108
137
  right = clamp(0, right | 0, MAX_COLS);
109
138
  }
139
+ const op = rangeOperator(trim);
110
140
  // A:A
111
141
  const allRows = top === 0 && bottom >= MAX_ROWS;
112
142
  const haveAbsCol = ($left && !noLeft) || ($right && !noRight);
113
143
  if ((allRows && !noLeft && !noRight && (!haveAbsCol || left === right)) || (noTop && noBottom)) {
114
- return toColStr(left, $left) + ':' + toColStr(right, $right);
144
+ return toColStr(left, $left) + op + toColStr(right, $right);
115
145
  }
116
146
  // 1:1
117
147
  const allCols = left === 0 && right >= MAX_COLS;
118
148
  const haveAbsRow = ($top && !noTop) || ($bottom && !noBottom);
119
149
  if ((allCols && !noTop && !noBottom && (!haveAbsRow || top === bottom)) || (noLeft && noRight)) {
120
- return toRowStr(top, $top) + ':' + toRowStr(bottom, $bottom);
150
+ return toRowStr(top, $top) + op + toRowStr(bottom, $bottom);
121
151
  }
122
152
  // A1:1
123
153
  if (!noLeft && !noTop && !noRight && noBottom) {
124
- return toColStr(left, $left) + toRowStr(top, $top) + ':' + toColStr(right, $right);
154
+ return toColStr(left, $left) + toRowStr(top, $top) + op + toColStr(right, $right);
125
155
  }
126
156
  // A:A1 => A1:1
127
157
  if (!noLeft && noTop && !noRight && !noBottom) {
128
- return toColStr(left, $left) + toRowStr(bottom, $bottom) + ':' + toColStr(right, $right);
158
+ return toColStr(left, $left) + toRowStr(bottom, $bottom) + op + toColStr(right, $right);
129
159
  }
130
160
  // A1:A
131
161
  if (!noLeft && !noTop && noRight && !noBottom) {
132
- return toColStr(left, $left) + toRowStr(top, $top) + ':' + toRowStr(bottom, $bottom);
162
+ return toColStr(left, $left) + toRowStr(top, $top) + op + toRowStr(bottom, $bottom);
133
163
  }
134
164
  // A:A1 => A1:A
135
165
  if (noLeft && !noTop && !noRight && !noBottom) {
136
- return toColStr(right, $right) + toRowStr(top, $top) + ':' + toRowStr(bottom, $bottom);
166
+ return toColStr(right, $right) + toRowStr(top, $top) + op + toRowStr(bottom, $bottom);
137
167
  }
138
168
  // A1:A1
139
169
  if (right !== left || bottom !== top || $right !== $left || $bottom !== $top) {
140
- return toColStr(left, $left) + toRowStr(top, $top) + ':' +
170
+ return toColStr(left, $left) + toRowStr(top, $top) + op +
141
171
  toColStr(right, $right) + toRowStr(bottom, $bottom);
142
172
  }
143
173
  // A1
@@ -176,10 +206,11 @@ export function fromA1 (rangeString) {
176
206
  let $left = false;
177
207
  let $bottom = false;
178
208
  let $right = false;
179
- const [ part1, part2, part3 ] = rangeString.split(':');
180
- if (part3) {
209
+ const [ part1, op1, part2, op2, part3 ] = rangeString.split(/(\.?:\.?)/);
210
+ if (op2 || part3) {
181
211
  return null;
182
212
  }
213
+ const trim = trimDirection(!!op1 && op1.at(0) === '.', !!op1 && op1.at(-1) === '.');
183
214
  const p1 = splitA1(part1);
184
215
  const p2 = part2 ? splitA1(part2) : null;
185
216
  if (!p1 || (part2 && !p2)) {
@@ -225,7 +256,9 @@ export function fromA1 (rangeString) {
225
256
  if (bottom != null && (top == null || (top != null && bottom < top))) {
226
257
  [ top, bottom, $top, $bottom ] = [ bottom, top, $bottom, $top ];
227
258
  }
228
- return { top, left, bottom, right, $top, $left, $bottom, $right };
259
+ const r = { top, left, bottom, right, $top, $left, $bottom, $right };
260
+ if (trim) { r.trim = trim; }
261
+ return r;
229
262
  }
230
263
 
231
264
  /**
@@ -263,17 +296,19 @@ export function parseA1Ref (refString, { allowNamed = true, allowTernary = false
263
296
  if (d && (d.r0 || d.name)) {
264
297
  let range = null;
265
298
  if (d.r0) {
266
- range = fromA1(d.r1 ? d.r0 + ':' + d.r1 : d.r0);
299
+ range = fromA1(d.r1 ? d.r0 + d.operator + d.r1 : d.r0);
267
300
  }
268
- if (d.name || range) {
269
- d.range = range;
270
- delete d.r0;
271
- delete d.r1;
272
- return d;
301
+ if (range) {
302
+ return xlsx
303
+ ? { workbookName: d.workbookName, sheetName: d.sheetName, range }
304
+ : { context: d.context, range };
273
305
  }
274
- else {
275
- return null;
306
+ if (d.name) {
307
+ return xlsx
308
+ ? { workbookName: d.workbookName, sheetName: d.sheetName, name: d.name }
309
+ : { context: d.context, name: d.name };
276
310
  }
311
+ return null;
277
312
  }
278
313
  return null;
279
314
  }
package/lib/a1.spec.js CHANGED
@@ -16,19 +16,8 @@ import { MAX_COLS, MAX_ROWS } from './constants.js';
16
16
  Test.prototype.isA1Equal = function isA1Equal (expr, expect, opts) {
17
17
  if (expect) {
18
18
  expect = opts?.xlsx
19
- ? {
20
- workbookName: '',
21
- sheetName: '',
22
- name: '',
23
- range: null,
24
- ...expect
25
- }
26
- : {
27
- context: [],
28
- name: '',
29
- range: null,
30
- ...expect
31
- };
19
+ ? { workbookName: '', sheetName: '', ...expect }
20
+ : { context: [], ...expect };
32
21
  Object.assign(expect, expect);
33
22
  if (expect.range && typeof expect.range === 'object') {
34
23
  // mix in some defaults so we don't have to write things out in full
@@ -296,6 +285,56 @@ test('A1 partial ranges', t => {
296
285
  t.end();
297
286
  });
298
287
 
288
+ test('A1 trimmed ranges', t => {
289
+ const locks = { $top: true, $left: true, $bottom: true, $right: true };
290
+ const opts = [ {}, { xlsx: true } ];
291
+ for (const opt of opts) {
292
+ t.isA1Equal('A1:B2', { range: { top: 0, left: 0, bottom: 1, right: 1 } }, opt);
293
+ t.isA1Equal('A1.:B2', { range: { top: 0, left: 0, bottom: 1, right: 1, trim: 'head' } }, opt);
294
+ t.isA1Equal('A1:.B2', { range: { top: 0, left: 0, bottom: 1, right: 1, trim: 'tail' } }, opt);
295
+ t.isA1Equal('A1.:.B2', { range: { top: 0, left: 0, bottom: 1, right: 1, trim: 'both' } }, opt);
296
+
297
+ t.isA1Equal('$A$1:$B$2', { range: { top: 0, left: 0, bottom: 1, right: 1, ...locks } }, opt);
298
+ t.isA1Equal('$A$1.:$B$2', { range: { top: 0, left: 0, bottom: 1, right: 1, trim: 'head', ...locks } }, opt);
299
+ t.isA1Equal('$A$1:.$B$2', { range: { top: 0, left: 0, bottom: 1, right: 1, trim: 'tail', ...locks } }, opt);
300
+ t.isA1Equal('$A$1.:.$B$2', { range: { top: 0, left: 0, bottom: 1, right: 1, trim: 'both', ...locks } }, opt);
301
+
302
+ t.isA1Equal('J:J', { range: { top: null, left: 9, bottom: null, right: 9 } }, opt);
303
+ t.isA1Equal('J.:J', { range: { top: null, left: 9, bottom: null, right: 9, trim: 'head' } }, opt);
304
+ t.isA1Equal('J:.J', { range: { top: null, left: 9, bottom: null, right: 9, trim: 'tail' } }, opt);
305
+ t.isA1Equal('J.:.J', { range: { top: null, left: 9, bottom: null, right: 9, trim: 'both' } }, opt);
306
+
307
+ t.isA1Equal('10:10', { range: { top: 9, left: null, bottom: 9, right: null } }, opt);
308
+ t.isA1Equal('10.:10', { range: { top: 9, left: null, bottom: 9, right: null, trim: 'head' } }, opt);
309
+ t.isA1Equal('10:.10', { range: { top: 9, left: null, bottom: 9, right: null, trim: 'tail' } }, opt);
310
+ t.isA1Equal('10.:.10', { range: { top: 9, left: null, bottom: 9, right: null, trim: 'both' } }, opt);
311
+
312
+ t.isA1Equal('J10:J', null, { ...opt });
313
+ t.isA1Equal('J10:10', null, { ...opt });
314
+ t.isA1Equal('J10.:.J', null, { ...opt });
315
+ t.isA1Equal('J10.:.10', null, { ...opt });
316
+ t.isA1Equal('J10:J', { range: { top: 9, left: 9, bottom: null, right: 9 } }, { allowTernary: true, ...opt });
317
+ t.isA1Equal('J10:10', { range: { top: 9, left: 9, bottom: 9, right: null } }, { allowTernary: true, ...opt });
318
+ t.isA1Equal('J10.:.J', { range: { top: 9, left: 9, bottom: null, right: 9, trim: 'both' } }, { allowTernary: true, ...opt });
319
+ t.isA1Equal('J10.:.10', { range: { top: 9, left: 9, bottom: 9, right: null, trim: 'both' } }, { allowTernary: true, ...opt });
320
+ }
321
+ t.end();
322
+ });
323
+
324
+ test('A1 trimmed ranges vs named ranges', t => {
325
+ // named ranges cannot be trimmed
326
+ t.isA1Equal('name1.:.name1', null);
327
+ t.isA1Equal('name1.:.foo', null);
328
+ t.isA1Equal('foo.:.name1', null);
329
+ // prior to the intruduction of trimed ranges, the following would have
330
+ // been an expression: NAME:`foo.` OP:`:`, COLUMN:`bar`
331
+ t.isA1Equal('foo.:bar', { range: { left: 1395, right: 4460, trim: 'head' } });
332
+ // prior to the intruduction of trimed ranges, the following would have
333
+ // been an expression: NAME:`foo.` OP:`:`, CELL:`B2`
334
+ t.isA1Equal('foo.:B2', { range: { top: 1, left: 1, right: 4460, trim: 'head' } }, { allowTernary: true });
335
+ t.end();
336
+ });
337
+
299
338
  test('A1 serialization', t => {
300
339
  // cell: A1
301
340
  t.is(toA1({ top: 9, bottom: 9, left: 2, right: 2 }), 'C10', 'C10');
@@ -343,6 +382,15 @@ test('A1 serialization', t => {
343
382
  t.is(toA1({ top: 15e5, bottom: 15e5, left: 20000, right: 20000 }), 'XFD1048576', 'XFD1048576');
344
383
  t.is(toA1({ top: 2, bottom: 2, left: 2.5, right: 2.5 }), 'C3', 'C3');
345
384
  t.is(toA1({ top: 1.5, bottom: 2.5, left: 4.5, right: 8.5 }), 'E2:I3', 'E2:I3');
385
+ // triming
386
+ t.is(toA1({ top: 2, bottom: 2, left: 4, right: 4, trim: 'both' }), 'E3', 'E3');
387
+ t.is(toA1({ top: 2, bottom: 3, left: 4, right: 6, trim: 'both' }), 'E3.:.G4', 'E3.:.G4');
388
+ t.is(toA1({ top: 2, bottom: 3, trim: 'both' }), '3.:.4', '3.:.4');
389
+ t.is(toA1({ left: 4, right: 6, trim: 'both' }), 'E.:.G', 'E.:.G');
390
+ t.is(toA1({ top: 9, left: 0, right: 0, trim: 'tail' }), 'A10:.A', 'A10:.A');
391
+ t.is(toA1({ top: 9, left: 0, right: 0, trim: 'head' }), 'A10.:A', 'A10.:A');
392
+ t.is(toA1({ top: 9, left: 0, right: 0, trim: 'both' }), 'A10.:.A', 'A10.:.A');
393
+
346
394
  t.end();
347
395
  });
348
396
 
@@ -403,5 +451,19 @@ test('A1 utilities', t => {
403
451
  };
404
452
  t.deepEqual(toAbsolute(relA1Range), absA1Range, 'toAbsolute');
405
453
  t.deepEqual(toRelative(absA1Range), relA1Range, 'toRelative');
454
+
455
+ const relA1RangeT = {
456
+ top: 0, left: 0, bottom: 0, right: 0,
457
+ $top: false, $left: false, $bottom: false, $right: false,
458
+ trim: 'both'
459
+ };
460
+ const absA1RangeT = {
461
+ top: 0, left: 0, bottom: 0, right: 0,
462
+ $top: true, $left: true, $bottom: true, $right: true,
463
+ trim: 'both'
464
+ };
465
+ t.deepEqual(toAbsolute(relA1RangeT), absA1RangeT, 'toAbsolute');
466
+ t.deepEqual(toRelative(absA1RangeT), relA1RangeT, 'toRelative');
467
+
406
468
  t.end();
407
469
  });
@@ -182,7 +182,7 @@ export function addTokenMeta (tokenlist, { sheetName = '', workbookName = '' } =
182
182
  token.type === REF_STRUCT
183
183
  ) {
184
184
  const ref = (token.type === REF_STRUCT)
185
- ? parseStructRef(token.value, { allowTernary: true, xlsx: true })
185
+ ? parseStructRef(token.value, { xlsx: true })
186
186
  : parseA1Ref(token.value, { allowTernary: true, xlsx: true });
187
187
  if (ref && (ref.range || ref.columns)) {
188
188
  ref.source = token.value;
@@ -137,5 +137,17 @@ test('add extra meta to operators', t => {
137
137
  { index: 7, depth: 0, type: REF_STRUCT, value: 'table[#data]', groupId: 'fxg1' }
138
138
  ], { sheetName: 'Sheet1', workbookName: 'foo' }, { xlsx: true });
139
139
 
140
+ // trimmin should not affect range equivalency
141
+ t.isMetaTokens('=A1:B2*A1.:B2*A1:.B2*A1.:.B2', [
142
+ { type: FX_PREFIX, value: '=', index: 0, depth: 0 },
143
+ { type: REF_RANGE, value: 'A1:B2', index: 1, depth: 0, groupId: 'fxg1' },
144
+ { type: OPERATOR, value: '*', index: 2, depth: 0 },
145
+ { type: REF_RANGE, value: 'A1.:B2', index: 3, depth: 0, groupId: 'fxg1' },
146
+ { type: OPERATOR, value: '*', index: 4, depth: 0 },
147
+ { type: REF_RANGE, value: 'A1:.B2', index: 5, depth: 0, groupId: 'fxg1' },
148
+ { type: OPERATOR, value: '*', index: 6, depth: 0 },
149
+ { type: REF_RANGE, value: 'A1.:.B2', index: 7, depth: 0, groupId: 'fxg1' }
150
+ ], { sheetName: 'Sheet1', workbookName: 'foo' }, { xlsx: true });
151
+
140
152
  t.end();
141
153
  });
package/lib/constants.js CHANGED
@@ -1,4 +1,5 @@
1
1
  export const OPERATOR = 'operator';
2
+ export const OPERATOR_TRIM = 'operator-trim';
2
3
  export const BOOLEAN = 'bool';
3
4
  export const ERROR = 'error';
4
5
  export const NUMBER = 'number';
package/lib/extraTypes.js CHANGED
@@ -38,6 +38,7 @@
38
38
  * @property {boolean | null} [$bottom] Signifies that bottom is a "locked" value
39
39
  * @property {boolean | null} [$left] Signifies that left is a "locked" value
40
40
  * @property {boolean | null} [$right] Signifies that right is a "locked" value
41
+ * @property {"head" | "tail" | "both"} [trim] Should empty rows and columns at the top/left or bottom/right be discarded when range is read?
41
42
  */
42
43
 
43
44
  /**
package/lib/fixRanges.js CHANGED
@@ -44,6 +44,7 @@ import { REF_STRUCT } from './constants.js';
44
44
  * @param {object} [options={}] Options
45
45
  * @param {boolean} [options.addBounds=false] Fill in any undefined bounds of range objects. Top to 0, bottom to 1048575, left to 0, and right to 16383.
46
46
  * @param {boolean} [options.xlsx=false] Switches to the `[1]Sheet1!A1` or `[1]!name` prefix syntax form for external workbooks. See: [Prefixes.md](./Prefixes.md)
47
+ * @param {boolean} [options.thisRow=false] Enforces using the `[#This Row]` instead of the `@` shorthand when serializing structured ranges.
47
48
  * @returns {(string | Array<Token>)} A formula string or token list (depending on which was input)
48
49
  */
49
50
  export function fixRanges (formula, options = { addBounds: false }) {
@@ -55,7 +56,7 @@ export function fixRanges (formula, options = { addBounds: false }) {
55
56
  if (!Array.isArray(formula)) {
56
57
  throw new Error('fixRanges expects an array of tokens');
57
58
  }
58
- const { addBounds, r1c1, xlsx } = options;
59
+ const { addBounds, r1c1, xlsx, thisRow } = options;
59
60
  if (r1c1) {
60
61
  throw new Error('fixRanges does not have an R1C1 mode');
61
62
  }
@@ -68,7 +69,7 @@ export function fixRanges (formula, options = { addBounds: false }) {
68
69
  let offsetDelta = 0;
69
70
  if (token.type === REF_STRUCT) {
70
71
  const sref = parseStructRef(token.value, { xlsx });
71
- const newValue = stringifyStructRef(sref, { xlsx });
72
+ const newValue = stringifyStructRef(sref, { xlsx, thisRow });
72
73
  offsetDelta = newValue.length - token.value.length;
73
74
  token.value = newValue;
74
75
  }
@@ -97,6 +97,7 @@ test('fixRanges A1 addBounds', t => {
97
97
  t.isFixed('=A:A1', '=A:A', opt);
98
98
  t.isFixed('=A:A$1', '=A:A', opt);
99
99
  t.isFixed('=A:$A$1', '=A:$A', opt);
100
+ t.isFixed('=A.:A', '=A.:A', opt);
100
101
  // partials - bottom
101
102
  t.isFixed('=A1:A', '=A:A', opt);
102
103
  t.isFixed('=A1:Z', '=A:Z', opt);
@@ -108,6 +109,7 @@ test('fixRanges A1 addBounds', t => {
108
109
  t.isFixed('=B2:B', '=B2:B1048576', opt);
109
110
  t.isFixed('=A:A2', '=A2:A1048576', opt);
110
111
  t.isFixed('=B:B2', '=B2:B1048576', opt);
112
+ t.isFixed('=B.:.B2', '=B2.:.B1048576', opt);
111
113
  // flipped partials - bottom
112
114
  t.isFixed('=A1:1', '=1:1', opt);
113
115
  t.isFixed('=A1:4', '=1:4', opt);
@@ -119,6 +121,7 @@ test('fixRanges A1 addBounds', t => {
119
121
  t.isFixed('=1:B1', '=B1:XFD1', opt);
120
122
  t.isFixed('=B2:20', '=B2:XFD20', opt);
121
123
  t.isFixed('=2:B20', '=B2:XFD20', opt);
124
+ t.isFixed('=2:.B20', '=B2:.XFD20', opt);
122
125
  t.end();
123
126
  });
124
127