js-xlsx-rails 0.3.6 → 0.5.10

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0d8568130aa77c3bd630f74ba8ec1f88086a07b4
4
- data.tar.gz: d2333492c564432a03d557bf4e9a75350ea968dd
3
+ metadata.gz: 66379200976256434030eaaeb88355646d0de3b7
4
+ data.tar.gz: 08dc7533fb309907a1dbde5da940e2de6576fdc5
5
5
  SHA512:
6
- metadata.gz: 356aecadfd8626fdc8e2ccb994d7d6210575bed152721f84bffe2f5a0c534b008ba6e0612172e5be6d6a3c536996248700f592bb5c0275faf2e23794fd429d95
7
- data.tar.gz: 306fa7fcfdacf276c22f834f60ba6b854b31cfc68d555a503d6a4202cc04743448461e6f4754366217a85b00253751b45f9edda5609c9e6f25efceefe48ec381
6
+ metadata.gz: fb6cefae64cb7a569e8d4b74e92b1bec0a7c26a178a3b9196c37253acad6ad4bd0e87aaccdf9e06cc71075fc77cefb436741a290f600f2ec4bd251b7a896917d
7
+ data.tar.gz: 9b7cde709b414eb1d3db65b34740494d96c2504bd7e54acb5c5ea71a848218f6f328f8150941751339de9d9b822f76cb799a09eaa848ddad654ed49ded8fd4eb
@@ -1,5 +1,5 @@
1
1
  module Jsxlsx
2
2
  module Rails
3
- VERSION = "0.3.6"
3
+ VERSION = "0.5.10"
4
4
  end
5
5
  end
@@ -1,15 +1,15 @@
1
- /* xlsx.js (C) 2013 SheetJS -- http://sheetjs.com */
1
+ /* xlsx.js (C) 2013-2014 SheetJS -- http://sheetjs.com */
2
2
  /* vim: set ts=2: */
3
3
  /*jshint eqnull:true */
4
4
  /* Spreadsheet Format -- jump to XLSX for the XLSX code */
5
- /* ssf.js (C) 2013 SheetJS -- http://sheetjs.com */
5
+ /* ssf.js (C) 2013-2014 SheetJS -- http://sheetjs.com */
6
6
  var SSF = {};
7
7
  var make_ssf = function(SSF){
8
- String.prototype.reverse=function(){return this.split("").reverse().join("");};
9
- var _strrev = function(x) { return String(x).reverse(); };
8
+ var _strrev = function(x) { return String(x).split("").reverse().join("");};
10
9
  function fill(c,l) { return new Array(l+1).join(c); }
11
10
  function pad(v,d,c){var t=String(v);return t.length>=d?t:(fill(c||0,d-t.length)+t);}
12
11
  function rpad(v,d,c){var t=String(v);return t.length>=d?t:(t+fill(c||0,d-t.length));}
12
+ SSF.version = '0.5.8';
13
13
  /* Options */
14
14
  var opts_fmt = {};
15
15
  function fixopts(o){for(var y in opts_fmt) if(o[y]===undefined) o[y]=opts_fmt[y];}
@@ -18,6 +18,7 @@ opts_fmt.date1904 = 0;
18
18
  opts_fmt.output = "";
19
19
  opts_fmt.mode = "";
20
20
  var table_fmt = {
21
+ 0: 'General',
21
22
  1: '0',
22
23
  2: '0.00',
23
24
  3: '#,##0',
@@ -44,7 +45,9 @@ var table_fmt = {
44
45
  46: '[h]:mm:ss',
45
46
  47: 'mmss.0',
46
47
  48: '##0.0E+0',
47
- 49: '@'
48
+ 49: '@',
49
+ 56: '"上午/下午 "hh"時"mm"分"ss"秒 "',
50
+ 65535: 'General'
48
51
  };
49
52
  var days = [
50
53
  ['Sun', 'Sunday'],
@@ -74,12 +77,12 @@ var frac = function frac(x, D, mixed) {
74
77
  var B = x * sgn;
75
78
  var P_2 = 0, P_1 = 1, P = 0;
76
79
  var Q_2 = 1, Q_1 = 0, Q = 0;
77
- var A = B|0;
80
+ var A = Math.floor(B);
78
81
  while(Q_1 < D) {
79
- A = B|0;
82
+ A = Math.floor(B);
80
83
  P = A * P_1 + P_2;
81
84
  Q = A * Q_1 + Q_2;
82
- if((B - A) < 0.0000000001) break;
85
+ if((B - A) < 0.0000000005) break;
83
86
  B = 1 / (B - A);
84
87
  P_2 = P_1; P_1 = P;
85
88
  Q_2 = Q_1; Q_1 = Q;
@@ -87,6 +90,7 @@ var frac = function frac(x, D, mixed) {
87
90
  if(Q > D) { Q = Q_1; P = P_1; }
88
91
  if(Q > D) { Q = Q_2; P = P_2; }
89
92
  if(!mixed) return [0, sgn * P, Q];
93
+ if(Q===0) throw "Unexpected state: "+P+" "+P_1+" "+P_2+" "+Q+" "+Q_1+" "+Q_2;
90
94
  var q = Math.floor(sgn * P/Q);
91
95
  return [q, sgn*P - q*Q, Q];
92
96
  };
@@ -100,25 +104,26 @@ var general_fmt = function(v) {
100
104
  else if(V >= 0.0001 && V < 0.001) o = v.toPrecision(6);
101
105
  else if(V >= Math.pow(10,10) && V < Math.pow(10,11)) o = v.toFixed(10).substr(0,12);
102
106
  else if(V > Math.pow(10,-9) && V < Math.pow(10,11)) {
103
- o = v.toFixed(12).replace(/(\.[0-9]*[1-9])0*$/,"$1").replace(/\.$/,"");
107
+ o = v.toFixed(12).replace(/(\.[0-9]*[1-9])0*$/,"$1").replace(/\.$/,"");
104
108
  if(o.length > 11+(v<0?1:0)) o = v.toPrecision(10);
105
109
  if(o.length > 11+(v<0?1:0)) o = v.toExponential(5);
106
- }
110
+ }
107
111
  else {
108
112
  o = v.toFixed(11).replace(/(\.[0-9]*[1-9])0*$/,"$1");
109
- if(o.length > 11 + (v<0?1:0)) o = v.toPrecision(6);
113
+ if(o.length > 11 + (v<0?1:0)) o = v.toPrecision(6);
110
114
  }
111
115
  o = o.replace(/(\.[0-9]*[1-9])0+e/,"$1e").replace(/\.0*e/,"e");
112
116
  return o.replace("e","E").replace(/\.0*$/,"").replace(/\.([0-9]*[^0])0*$/,".$1").replace(/(E[+-])([0-9])$/,"$1"+"0"+"$2");
113
117
  }
114
118
  if(typeof v === 'string') return v;
115
- throw "unsupported value in General format: " + v;
119
+ throw new Error("unsupported value in General format: " + v);
116
120
  };
117
121
  SSF._general = general_fmt;
118
122
  var parse_date_code = function parse_date_code(v,opts) {
119
- var date = Math.floor(v), time = Math.round(86400 * (v - date)), dow=0;
123
+ var date = Math.floor(v), time = Math.floor(86400 * (v - date)+1e-6), dow=0;
120
124
  var dout=[], out={D:date, T:time, u:86400*(v-date)-time}; fixopts(opts = (opts||{}));
121
125
  if(opts.date1904) date += 1462;
126
+ if(date > 2958465) return null;
122
127
  if(date === 60) {dout = [1900,2,29]; dow=3;}
123
128
  else if(date === 0) {dout = [1900,1,0]; dow=6;}
124
129
  else {
@@ -128,7 +133,7 @@ var parse_date_code = function parse_date_code(v,opts) {
128
133
  d.setDate(d.getDate() + date - 1);
129
134
  dout = [d.getFullYear(), d.getMonth()+1,d.getDate()];
130
135
  dow = d.getDay();
131
- if(opts.mode === 'excel' && date < 60) dow = (dow + 6) % 7;
136
+ if(/* opts.mode === 'excel' && */ date < 60) dow = (dow + 6) % 7;
132
137
  }
133
138
  out.y = dout[0]; out.m = dout[1]; out.d = dout[2];
134
139
  out.S = time % 60; time = Math.floor(time / 60);
@@ -138,61 +143,63 @@ var parse_date_code = function parse_date_code(v,opts) {
138
143
  return out;
139
144
  };
140
145
  SSF.parse_date_code = parse_date_code;
146
+ /*jshint -W086 */
141
147
  var write_date = function(type, fmt, val) {
142
148
  if(val < 0) return "";
149
+ var o;
143
150
  switch(type) {
144
151
  case 'y': switch(fmt) { /* year */
145
152
  case 'y': case 'yy': return pad(val.y % 100,2);
146
- default: return val.y;
147
- } break;
153
+ default: return pad(val.y % 10000,4);
154
+ }
148
155
  case 'm': switch(fmt) { /* month */
149
156
  case 'm': return val.m;
150
157
  case 'mm': return pad(val.m,2);
151
158
  case 'mmm': return months[val.m-1][1];
152
- case 'mmmm': return months[val.m-1][2];
153
159
  case 'mmmmm': return months[val.m-1][0];
154
- default: throw 'bad month format: ' + fmt;
155
- } break;
160
+ default: return months[val.m-1][2];
161
+ }
156
162
  case 'd': switch(fmt) { /* day */
157
163
  case 'd': return val.d;
158
164
  case 'dd': return pad(val.d,2);
159
165
  case 'ddd': return days[val.q][0];
160
- case 'dddd': return days[val.q][1];
161
- default: throw 'bad day format: ' + fmt;
162
- } break;
166
+ default: return days[val.q][1];
167
+ }
163
168
  case 'h': switch(fmt) { /* 12-hour */
164
169
  case 'h': return 1+(val.H+11)%12;
165
170
  case 'hh': return pad(1+(val.H+11)%12, 2);
166
171
  default: throw 'bad hour format: ' + fmt;
167
- } break;
172
+ }
168
173
  case 'H': switch(fmt) { /* 24-hour */
169
174
  case 'h': return val.H;
170
175
  case 'hh': return pad(val.H, 2);
171
176
  default: throw 'bad hour format: ' + fmt;
172
- } break;
177
+ }
173
178
  case 'M': switch(fmt) { /* minutes */
174
179
  case 'm': return val.M;
175
180
  case 'mm': return pad(val.M, 2);
176
181
  default: throw 'bad minute format: ' + fmt;
177
- } break;
182
+ }
178
183
  case 's': switch(fmt) { /* seconds */
179
- case 's': return val.S;
180
- case 'ss': return pad(val.S, 2);
181
- case 'ss.0': return pad(val.S,2) + "." + Math.round(10*val.u);
184
+ case 's': return Math.round(val.S+val.u);
185
+ case 'ss': return pad(Math.round(val.S+val.u), 2);
186
+ case 'ss.0': o = pad(Math.round(10*(val.S+val.u)),3); return o.substr(0,2)+"." + o.substr(2);
187
+ case 'ss.00': o = pad(Math.round(100*(val.S+val.u)),4); return o.substr(0,2)+"." + o.substr(2);
188
+ case 'ss.000': o = pad(Math.round(1000*(val.S+val.u)),5); return o.substr(0,2)+"." + o.substr(2);
182
189
  default: throw 'bad second format: ' + fmt;
183
- } break;
190
+ }
184
191
  case 'Z': switch(fmt) {
185
- case '[h]': return val.D*24+val.H;
192
+ case '[h]': case '[hh]': o = val.D*24+val.H; break;
193
+ case '[m]': case '[mm]': o = (val.D*24+val.H)*60+val.M; break;
194
+ case '[s]': case '[ss]': o = ((val.D*24+val.H)*60+val.M)*60+Math.round(val.S+val.u); break;
186
195
  default: throw 'bad abstime format: ' + fmt;
187
- } break;
196
+ } return fmt.length === 3 ? o : pad(o, 2);
188
197
  /* TODO: handle the ECMA spec format ee -> yy */
189
198
  case 'e': { return val.y; } break;
190
- case 'A': return (val.h>=12 ? 'P' : 'A') + fmt.substr(1);
191
- default: throw 'bad format type ' + type + ' in ' + fmt;
192
199
  }
193
200
  };
194
- String.prototype.reverse = function() { return this.split("").reverse().join(""); };
195
- var commaify = function(s) { return s.reverse().replace(/.../g,"$&,").reverse().replace(/^,/,""); };
201
+ /*jshint +W086 */
202
+ var commaify = function(s) { return _strrev(_strrev(s).replace(/.../g,"$&,")).replace(/^,/,""); };
196
203
  var write_num = function(type, fmt, val) {
197
204
  if(type === '(') {
198
205
  var ffmt = fmt.replace(/\( */,"").replace(/ \)/,"").replace(/\)/,"");
@@ -204,37 +211,60 @@ var write_num = function(type, fmt, val) {
204
211
  if(mul !== 0) return write_num(type, fmt, val * Math.pow(10,2*mul)) + fill("%",mul);
205
212
  if(fmt.indexOf("E") > -1) {
206
213
  var idx = fmt.indexOf("E") - fmt.indexOf(".") - 1;
207
- if(fmt == '##0.0E+0') {
208
- var ee = Number(val.toExponential(0).substr(3))%3;
209
- o = (val/Math.pow(10,ee%3)).toPrecision(idx+1+(ee%3)).replace(/^([+-]?)([0-9]*)\.([0-9]*)[Ee]/,function($$,$1,$2,$3) { return $1 + $2 + $3.substr(0,ee) + "." + $3.substr(ee) + "E"; });
214
+ if(fmt.match(/^#+0.0E\+0$/)) {
215
+ var period = fmt.indexOf("."); if(period === -1) period=fmt.indexOf('E');
216
+ var ee = (Number(val.toExponential(0).substr(2+(val<0))))%period;
217
+ if(ee < 0) ee += period;
218
+ o = (val/Math.pow(10,ee)).toPrecision(idx+1+(period+ee)%period);
219
+ if(!o.match(/[Ee]/)) {
220
+ var fakee = (Number(val.toExponential(0).substr(2+(val<0))));
221
+ if(o.indexOf(".") === -1) o = o[0] + "." + o.substr(1) + "E+" + (fakee - o.length+ee);
222
+ else o += "E+" + (fakee - ee);
223
+ while(o.substr(0,2) === "0.") {
224
+ o = o[0] + o.substr(2,period) + "." + o.substr(2+period);
225
+ o = o.replace(/^0+([1-9])/,"$1").replace(/^0+\./,"0.");
226
+ }
227
+ o = o.replace(/\+-/,"-");
228
+ }
229
+ o = o.replace(/^([+-]?)([0-9]*)\.([0-9]*)[Ee]/,function($$,$1,$2,$3) { return $1 + $2 + $3.substr(0,(period+ee)%period) + "." + $3.substr(ee) + "E"; });
210
230
  } else o = val.toExponential(idx);
211
231
  if(fmt.match(/E\+00$/) && o.match(/e[+-][0-9]$/)) o = o.substr(0,o.length-1) + "0" + o[o.length-1];
212
232
  if(fmt.match(/E\-/) && o.match(/e\+/)) o = o.replace(/e\+/,"e");
213
233
  return o.replace("e","E");
214
234
  }
215
- if(fmt[0] === "$") return "$"+write_num(type,fmt.substr(fmt[1]==' '?2:1),val);
216
- var r, ff, aval = val < 0 ? -val : val, sign = val < 0 ? "-" : "";
217
- if((r = fmt.match(/# (\?+) \/ (\d+)/))) {
218
- var den = Number(r[2]), rnd = Math.round(aval * den), base = Math.floor(rnd/den);
235
+ if(fmt[0] === "$") return "$"+write_num(type,fmt.substr(fmt[1]==' '?2:1),val);
236
+ var r, rr, ff, aval = val < 0 ? -val : val, sign = val < 0 ? "-" : "";
237
+ if((r = fmt.match(/# (\?+)([ ]?)\/([ ]?)(\d+)/))) {
238
+ var den = Number(r[4]), rnd = Math.round(aval * den), base = Math.floor(rnd/den);
219
239
  var myn = (rnd - base*den), myd = den;
220
- return sign + (base?base:"") + " " + (myn === 0 ? fill(" ", r[1].length + 1 + r[2].length) : pad(myn,r[1].length," ") + "/" + pad(myd,r[2].length));
240
+ return sign + (base?base:"") + " " + (myn === 0 ? fill(" ", r[1].length + 1 + r[4].length) : pad(myn,r[1].length," ") + r[2] + "/" + r[3] + pad(myd,r[4].length));
241
+ }
242
+ if(fmt.match(/^#+0+$/)) fmt = fmt.replace(/#/g,"");
243
+ if(fmt.match(/^00+$/)) return (val<0?"-":"")+pad(Math.round(aval),fmt.length);
244
+ if(fmt.match(/^[#?]+$/)) return String(Math.round(val)).replace(/^0$/,"");
245
+ if((r = fmt.match(/^#*0+\.(0+)/))) {
246
+ o = Math.round(val * Math.pow(10,r[1].length));
247
+ return String(o/Math.pow(10,r[1].length)).replace(/^([^\.]+)$/,"$1."+r[1]).replace(/\.$/,"."+r[1]).replace(/\.([0-9]*)$/,function($$, $1) { return "." + $1 + fill("0", r[1].length-$1.length); });
248
+ }
249
+ if((r = fmt.match(/^(0*)\.(#*)$/))) {
250
+ o = Math.round(val*Math.pow(10,r[2].length));
251
+ return String(o * Math.pow(10,-r[2].length)).replace(/\.(\d*[1-9])0*$/,".$1").replace(/^([-]?\d*)$/,"$1.").replace(/^0\./,r[1].length?"0.":".");
252
+ }
253
+ if((r = fmt.match(/^#,##0([.]?)$/))) return sign + commaify(String(Math.round(aval)));
254
+ if((r = fmt.match(/^#,##0\.([#0]*0)$/))) {
255
+ rr = Math.round((val-Math.floor(val))*Math.pow(10,r[1].length));
256
+ return val < 0 ? "-" + write_num(type, fmt, -val) : commaify(String(Math.floor(val))) + "." + pad(rr,r[1].length,0);
257
+ }
258
+ if((r = fmt.match(/^# ([?]+)([ ]?)\/([ ]?)([?]+)/))) {
259
+ rr = Math.min(Math.max(r[1].length, r[4].length),7);
260
+ ff = frac(aval, Math.pow(10,rr)-1, true);
261
+ return sign + (ff[0]||(ff[1] ? "" : "0")) + " " + (ff[1] ? pad(ff[1],rr," ") + r[2] + "/" + r[3] + rpad(ff[2],rr," "): fill(" ", 2*rr+1 + r[2].length + r[3].length));
221
262
  }
222
- if(fmt.match(/^00*$/)) return (val<0?"-":"")+pad(Math.round(Math.abs(val)), fmt.length);
223
- if(fmt.match(/^####*$/)) return "dafuq";
224
263
  switch(fmt) {
225
- case "0": return Math.round(val);
226
- case "0.0": o = Math.round(val*10);
227
- return String(o/10).replace(/^([^\.]+)$/,"$1.0").replace(/\.$/,".0");
228
- case "0.00": o = Math.round(val*100);
229
- return String(o/100).replace(/^([^\.]+)$/,"$1.00").replace(/\.$/,".00").replace(/\.([0-9])$/,".$1"+"0");
230
- case "0.000": o = Math.round(val*1000);
231
- return String(o/1000).replace(/^([^\.]+)$/,"$1.000").replace(/\.$/,".000").replace(/\.([0-9])$/,".$1"+"00").replace(/\.([0-9][0-9])$/,".$1"+"0");
232
- case "#,##0": return sign + commaify(String(Math.round(aval)));
233
- case "#,##0.0": r = Math.round((val-Math.floor(val))*10); return val < 0 ? "-" + write_num(type, fmt, -val) : commaify(String(Math.floor(val))) + "." + r;
234
- case "#,##0.00": r = Math.round((val-Math.floor(val))*100); return val < 0 ? "-" + write_num(type, fmt, -val) : commaify(String(Math.floor(val))) + "." + (r < 10 ? "0"+r:r);
235
- case "# ? / ?": ff = frac(aval, 9, true); return sign + (ff[0]||"") + " " + (ff[1] === 0 ? " " : ff[1] + "/" + ff[2]);
236
- case "# ?? / ??": ff = frac(aval, 99, true); return sign + (ff[0]||"") + " " + (ff[1] ? pad(ff[1],2," ") + "/" + rpad(ff[2],2," ") : " ");
237
- case "# ??? / ???": ff = frac(aval, 999, true); return sign + (ff[0]||"") + " " + (ff[1] ? pad(ff[1],3," ") + "/" + rpad(ff[2],3," ") : " ");
264
+ case "0": case "#0": return Math.round(val);
265
+ case "#.##": o = Math.round(val*100);
266
+ return String(o/100).replace(/^([^\.]+)$/,"$1.").replace(/^0\.$/,".");
267
+ case "#,###": var x = commaify(String(Math.round(aval))); return x !== "0" ? sign + x : "";
238
268
  default:
239
269
  }
240
270
  throw new Error("unsupported format |" + fmt + "|");
@@ -251,7 +281,7 @@ function split_fmt(fmt) {
251
281
  j = i+1;
252
282
  }
253
283
  out.push(fmt.slice(j));
254
- if(in_str !=-1) throw "Format |" + fmt + "| unterminated string at " + in_str;
284
+ if(in_str !=-1) throw new Error("Format |" + fmt + "| unterminated string at " + in_str);
255
285
  return out;
256
286
  }
257
287
  SSF._split = split_fmt;
@@ -262,6 +292,10 @@ function eval_fmt(fmt, v, opts, flen) {
262
292
  /* Tokenize */
263
293
  while(i < fmt.length) {
264
294
  switch((c = fmt[i])) {
295
+ case 'G': /* General */
296
+ if(fmt.substr(i, i+6).toLowerCase() !== "general")
297
+ throw new Error('unrecognized character ' + fmt[i] + ' in ' +fmt);
298
+ out.push({t:'G',v:'General'}); i+=7; break;
265
299
  case '"': /* Literal text */
266
300
  for(o="";fmt[++i] !== '"' && i < fmt.length;) o += fmt[i];
267
301
  out.push({t:'t', v:o}); ++i; break;
@@ -271,28 +305,39 @@ function eval_fmt(fmt, v, opts, flen) {
271
305
  case '@': /* Text Placeholder */
272
306
  out.push({t:'T', v:v}); ++i; break;
273
307
  /* Dates */
308
+ case 'M': case 'D': case 'Y': case 'H': case 'S': case 'E':
309
+ c = c.toLowerCase();
310
+ /* falls through */
274
311
  case 'm': case 'd': case 'y': case 'h': case 's': case 'e':
275
312
  if(v < 0) return "";
276
313
  if(!dt) dt = parse_date_code(v, opts);
277
- o = fmt[i]; while(fmt[++i] === c) o+=c;
314
+ if(!dt) return "";
315
+ o = fmt[i]; while((fmt[++i]||"").toLowerCase() === c) o+=c;
278
316
  if(c === 's' && fmt[i] === '.' && fmt[i+1] === '0') { o+='.'; while(fmt[++i] === '0') o+= '0'; }
279
317
  if(c === 'm' && lst.toLowerCase() === 'h') c = 'M'; /* m = minute */
280
318
  if(c === 'h') c = hr;
319
+ o = o.toLowerCase();
281
320
  q={t:c, v:o}; out.push(q); lst = c; break;
282
321
  case 'A':
283
322
  if(!dt) dt = parse_date_code(v, opts);
323
+ if(!dt) return "";
284
324
  q={t:c,v:"A"};
285
325
  if(fmt.substr(i, 3) === "A/P") {q.v = dt.H >= 12 ? "P" : "A"; q.t = 'T'; hr='h';i+=3;}
286
326
  else if(fmt.substr(i,5) === "AM/PM") { q.v = dt.H >= 12 ? "PM" : "AM"; q.t = 'T'; i+=5; hr='h'; }
287
- else q.t = "t";
327
+ else { q.t = "t"; i++; }
288
328
  out.push(q); lst = c; break;
289
329
  case '[': /* TODO: Fix this -- ignore all conditionals and formatting */
290
330
  o = c;
291
- while(fmt[i++] !== ']') o += fmt[i];
292
- if(o == "[h]") out.push({t:'Z', v:o});
331
+ while(fmt[i++] !== ']' && i < fmt.length) o += fmt[i];
332
+ if(o.substr(-1) !== ']') throw 'unterminated "[" block: |' + o + '|';
333
+ if(o.match(/\[[HhMmSs]*\]/)) {
334
+ if(!dt) dt = parse_date_code(v, opts);
335
+ if(!dt) return "";
336
+ out.push({t:'Z', v:o.toLowerCase()});
337
+ } else { o=""; }
293
338
  break;
294
339
  /* Numbers */
295
- case '0': case '#':
340
+ case '0': case '#': case '.':
296
341
  o = c; while("0#?.,E+-%".indexOf(c=fmt[++i]) > -1) o += c;
297
342
  out.push({t:'n', v:o}); break;
298
343
  case '?':
@@ -305,7 +350,7 @@ function eval_fmt(fmt, v, opts, flen) {
305
350
  out.push({t:'D', v:o}); break;
306
351
  case ' ': out.push({t:c,v:c}); ++i; break;
307
352
  default:
308
- if("$-+/():!^&'~{}<>=".indexOf(c) === -1)
353
+ if(",$-+/():!^&'~{}<>=€".indexOf(c) === -1)
309
354
  throw 'unrecognized character ' + fmt[i] + ' in ' + fmt;
310
355
  out.push({t:'t', v:c}); ++i; break;
311
356
  }
@@ -323,45 +368,48 @@ function eval_fmt(fmt, v, opts, flen) {
323
368
  /* replace fields */
324
369
  for(i=0; i < out.length; ++i) {
325
370
  switch(out[i].t) {
326
- case 't': case 'T': case ' ': break;
327
- case 'd': case 'm': case 'y': case 'h': case 'H': case 'M': case 's': case 'A': case 'e': case 'Z':
371
+ case 't': case 'T': case ' ': case 'D': break;
372
+ case 'd': case 'm': case 'y': case 'h': case 'H': case 'M': case 's': case 'e': case 'Z':
328
373
  out[i].v = write_date(out[i].t, out[i].v, dt);
329
374
  out[i].t = 't'; break;
330
- case 'n': case '(':
375
+ case 'n': case '(': case '?':
331
376
  var jj = i+1;
332
- while(out[jj] && ("? D".indexOf(out[jj].t) > -1 || out[i].t == '(' && (out[jj].t == ')' || out[jj].t == 'n') || out[jj].t == 't' && (out[jj].v == '/' || out[jj].v == '$' || (out[jj].v == ' ' && (out[jj+1]||{}).t == '?')))) {
333
- if(out[jj].v!==' ') out[i].v += ' ' + out[jj].v;
377
+ while(out[jj] && ("?D".indexOf(out[jj].t) > -1 || (" t".indexOf(out[jj].t) > -1 && "?t".indexOf((out[jj+1]||{}).t)>-1 && (out[jj+1].t == '?' || out[jj+1].v == '/')) || out[i].t == '(' && (out[jj].t == ')' || out[jj].t == 'n') || out[jj].t == 't' && (out[jj].v == '/' || '$€'.indexOf(out[jj].v) > -1 || (out[jj].v == ' ' && (out[jj+1]||{}).t == '?')))) {
378
+ out[i].v += out[jj].v;
334
379
  delete out[jj]; ++jj;
335
380
  }
336
- out[i].v = write_num(out[i].t, out[i].v, v);
381
+ out[i].v = write_num(out[i].t, out[i].v, (flen >1 && v < 0 && i>0 && out[i-1].v == "-" ? -v:v));
337
382
  out[i].t = 't';
338
- i = jj; break;
339
- default: throw "unrecognized type " + out[i].t;
383
+ i = jj-1; break;
384
+ case 'G': out[i].t = 't'; out[i].v = general_fmt(v,opts); break;
340
385
  }
341
386
  }
342
-
343
387
  return out.map(function(x){return x.v;}).join("");
344
388
  }
345
389
  SSF._eval = eval_fmt;
346
390
  function choose_fmt(fmt, v, o) {
347
- if(typeof fmt === 'number') fmt = table_fmt[fmt];
391
+ if(typeof fmt === 'number') fmt = ((o&&o.table) ? o.table : table_fmt)[fmt];
348
392
  if(typeof fmt === "string") fmt = split_fmt(fmt);
349
393
  var l = fmt.length;
394
+ if(l<4 && fmt[l-1].indexOf("@")>-1) --l;
350
395
  switch(fmt.length) {
351
- case 1: fmt = [fmt[0], fmt[0], fmt[0], "@"]; break;
352
- case 2: fmt = [fmt[0], fmt[fmt[1] === "@"?0:1], fmt[0], "@"]; break;
396
+ case 1: fmt = fmt[0].indexOf("@")>-1 ? ["General", "General", "General", fmt[0]] : [fmt[0], fmt[0], fmt[0], "@"]; break;
397
+ case 2: fmt = fmt[1].indexOf("@")>-1 ? [fmt[0], fmt[0], fmt[0], fmt[1]] : [fmt[0], fmt[1], fmt[0], "@"]; break;
398
+ case 3: fmt = fmt[2].indexOf("@")>-1 ? [fmt[0], fmt[1], fmt[0], fmt[2]] : [fmt[0], fmt[1], fmt[2], "@"]; break;
353
399
  case 4: break;
354
400
  default: throw "cannot find right format for |" + fmt + "|";
355
401
  }
356
402
  if(typeof v !== "number") return [fmt.length, fmt[3]];
357
403
  return [l, v > 0 ? fmt[0] : v < 0 ? fmt[1] : fmt[2]];
358
404
  }
359
-
360
405
  var format = function format(fmt,v,o) {
361
406
  fixopts(o = (o||{}));
362
- if(fmt === 0) return general_fmt(v, o);
363
- if(typeof fmt === 'number') fmt = table_fmt[fmt];
407
+ if(typeof fmt === "string" && fmt.toLowerCase() === "general") return general_fmt(v, o);
408
+ if(typeof fmt === 'number') fmt = (o.table || table_fmt)[fmt];
364
409
  var f = choose_fmt(fmt, v, o);
410
+ if(f[1].toLowerCase() === "general") return general_fmt(v,o);
411
+ if(v === true) v = "TRUE"; if(v === false) v = "FALSE";
412
+ if(v === "" || typeof v === "undefined") return "";
365
413
  return eval_fmt(f[1], v, o, f[0]);
366
414
  };
367
415
 
@@ -369,19 +417,75 @@ SSF._choose = choose_fmt;
369
417
  SSF._table = table_fmt;
370
418
  SSF.load = function(fmt, idx) { table_fmt[idx] = fmt; };
371
419
  SSF.format = format;
420
+ SSF.get_table = function() { return table_fmt; };
421
+ SSF.load_table = function(tbl) { for(var i=0; i!=0x0188; ++i) if(tbl[i]) SSF.load(tbl[i], i); };
372
422
  };
373
423
  make_ssf(SSF);
374
424
  var XLSX = {};
375
425
  (function(XLSX){
426
+ XLSX.version = '0.5.10-b';
427
+ var current_codepage, current_cptable, cptable;
428
+ if(typeof module !== "undefined" && typeof require !== 'undefined') {
429
+ if(typeof cptable === 'undefined') cptable = require('codepage');
430
+ current_codepage = 1252; current_cptable = cptable[1252];
431
+ }
432
+ function reset_cp() {
433
+ current_codepage = 1252; if(typeof cptable !== 'undefined') current_cptable = cptable[1252];
434
+ }
435
+ function _getchar(x) { return String.fromCharCode(x); }
436
+
437
+ function getdata(data) {
438
+ if(!data) return null;
439
+ if(data.data) return data.name.substr(-4) !== ".bin" ? data.data : data.data.split("").map(function(x) { return x.charCodeAt(0); });
440
+ if(data.asNodeBuffer && typeof Buffer !== 'undefined' && data.name.substr(-4)===".bin") return data.asNodeBuffer();
441
+ if(data.asBinary && data.name.substr(-4) !== ".bin") return data.asBinary();
442
+ if(data._data && data._data.getContent) {
443
+ /* TODO: something far more intelligent */
444
+ if(data.name.substr(-4) === ".bin") return Array.prototype.slice.call(data._data.getContent());
445
+ return Array.prototype.slice.call(data._data.getContent(),0).map(function(x) { return String.fromCharCode(x); }).join("");
446
+ }
447
+ return null;
448
+ }
449
+
450
+ function getzipfile(zip, file) {
451
+ var f = file; if(zip.files[f]) return zip.files[f];
452
+ f = file.toLowerCase(); if(zip.files[f]) return zip.files[f];
453
+ f = f.replace(/\//g,'\\'); if(zip.files[f]) return zip.files[f];
454
+ throw new Error("Cannot find file " + file + " in zip");
455
+ }
456
+
457
+ function getzipdata(zip, file, safe) {
458
+ if(!safe) return getdata(getzipfile(zip, file));
459
+ if(!file) return null;
460
+ try { return getzipdata(zip, file); } catch(e) { return null; }
461
+ }
462
+
463
+ var _fs, jszip;
464
+ if(typeof JSZip !== 'undefined') jszip = JSZip;
465
+ if (typeof exports !== 'undefined') {
466
+ if (typeof module !== 'undefined' && module.exports) {
467
+ if(typeof Buffer !== 'undefined' && typeof jszip === 'undefined') jszip = require('jszip');
468
+ if(typeof jszip === 'undefined') jszip = require('./jszip').JSZip;
469
+ _fs = require('fs');
470
+ }
471
+ }
472
+ var attregexg=/(\w+)=((?:")([^"]*)(?:")|(?:')([^']*)(?:'))/g;
473
+ var attregex=/(\w+)=((?:")(?:[^"]*)(?:")|(?:')(?:[^']*)(?:'))/;
376
474
  function parsexmltag(tag) {
377
475
  var words = tag.split(/\s+/);
378
476
  var z = {'0': words[0]};
379
477
  if(words.length === 1) return z;
380
- (tag.match(/(\w+)="([^"]*)"/g) || []).map(
381
- function(x){var y=x.match(/(\w+)="([^"]*)"/); z[y[1]] = y[2]; });
478
+ (tag.match(attregexg) || []).map(
479
+ function(x){var y=x.match(attregex); z[y[1].replace(/^[a-zA-Z]*:/,"")] = y[2].substr(1,y[2].length-2); });
382
480
  return z;
383
481
  }
384
482
 
483
+ function evert(obj) {
484
+ var o = {};
485
+ Object.keys(obj).forEach(function(k) { if(obj.hasOwnProperty(k)) o[obj[k]] = k; });
486
+ return o;
487
+ }
488
+
385
489
  var encodings = {
386
490
  '&quot;': '"',
387
491
  '&apos;': "'",
@@ -389,6 +493,8 @@ var encodings = {
389
493
  '&lt;': '<',
390
494
  '&amp;': '&'
391
495
  };
496
+ var rencoding = evert(encodings);
497
+ var rencstr = "&<>'\"".split("");
392
498
 
393
499
  // TODO: CP remap (need to read file version to determine OS)
394
500
  function unescapexml(text){
@@ -396,6 +502,12 @@ function unescapexml(text){
396
502
  for(var y in encodings) s = s.replace(new RegExp(y,'g'), encodings[y]);
397
503
  return s.replace(/_x([0-9a-fA-F]*)_/g,function(m,c) {return _chr(parseInt(c,16));});
398
504
  }
505
+ function escapexml(text){
506
+ var s = text + '';
507
+ rencstr.forEach(function(y){s=s.replace(new RegExp(y,'g'), rencoding[y]);});
508
+ return s;
509
+ }
510
+
399
511
 
400
512
  function parsexmlbool(value, tag) {
401
513
  switch(value) {
@@ -406,20 +518,20 @@ function parsexmlbool(value, tag) {
406
518
  }
407
519
 
408
520
  var utf8read = function(orig) {
409
- var out = "", i = 0, c = 0, c1 = 0, c2 = 0, c3 = 0;
521
+ var out = [], i = 0, c = 0, c1 = 0, c2 = 0, c3 = 0;
410
522
  while (i < orig.length) {
411
523
  c = orig.charCodeAt(i++);
412
- if (c < 128) out += _chr(c);
524
+ if (c < 128) out.push(_chr(c));
413
525
  else {
414
526
  c2 = orig.charCodeAt(i++);
415
- if (c>191 && c<224) out += _chr((c & 31) << 6 | c2 & 63);
527
+ if (c>191 && c<224) out.push(_chr((c & 31) << 6 | c2 & 63));
416
528
  else {
417
529
  c3 = orig.charCodeAt(i++);
418
- out += _chr((c & 15) << 12 | (c2 & 63) << 6 | c3 & 63);
530
+ out.push(_chr((c & 15) << 12 | (c2 & 63) << 6 | c3 & 63));
419
531
  }
420
532
  }
421
533
  }
422
- return out;
534
+ return out.join("");
423
535
  };
424
536
 
425
537
  // matches <foo>...</foo> extracts content
@@ -439,327 +551,524 @@ function parseVector(data) {
439
551
  }
440
552
 
441
553
  function isval(x) { return typeof x !== "undefined" && x !== null; }
442
- /* 18.4 Shared String Table */
443
- var parse_sst = (function(){
444
- var tregex = matchtag("t"), rpregex = matchtag("rPr");
445
- /* Parse a list of <r> tags */
446
- var parse_rs = (function() {
447
- /* 18.4.7 rPr CT_RPrElt */
448
- var parse_rpr = function(rpr, intro, outro) {
449
- var font = {};
450
- (rpr.match(/<[^>]*>/g)||[]).forEach(function(x) {
451
- var y = parsexmltag(x);
452
- switch(y[0]) {
453
- /* 18.8.12 condense CT_BooleanProperty */
454
- /* ** not required . */
455
- case '<condense': break;
456
- /* 18.8.17 extend CT_BooleanProperty */
457
- /* ** not required . */
458
- case '<extend': break;
459
- /* 18.8.36 shadow CT_BooleanProperty */
460
- /* ** not required . */
461
- case '<shadow': break;
462
-
463
- /* 18.4.1 charset CT_IntProperty TODO */
464
- case '<charset': break;
465
-
466
- /* 18.4.2 outline CT_BooleanProperty TODO */
467
- case '<outline': break;
468
-
469
- /* 18.4.5 rFont CT_FontName */
470
- case '<rFont': font.name = y.val; break;
471
-
472
- /* 18.4.11 sz CT_FontSize */
473
- case '<sz': font.sz = y.val; break;
474
-
475
- /* 18.4.10 strike CT_BooleanProperty */
476
- case '<strike':
477
- if(!y.val) break;
478
- /* falls through */
479
- case '<strike/>': font.strike = 1; break;
480
- case '</strike>': break;
481
-
482
- /* 18.4.13 u CT_UnderlineProperty */
483
- case '<u':
484
- if(!y.val) break;
485
- /* falls through */
486
- case '<u/>': font.u = 1; break;
487
- case '</u>': break;
488
-
489
- /* 18.8.2 b */
490
- case '<b':
491
- if(!y.val) break;
492
- /* falls through */
493
- case '<b/>': font.b = 1; break;
494
- case '</b>': break;
495
-
496
- /* 18.8.26 i */
497
- case '<i':
498
- if(!y.val) break;
499
- /* falls through */
500
- case '<i/>': font.i = 1; break;
501
- case '</i>': break;
502
-
503
- /* 18.3.1.15 color CT_Color TODO: tint, theme, auto, indexed */
504
- case '<color':
505
- if(y.rgb) font.color = y.rgb.substr(2,6);
506
- break;
554
+ function readIEEE754(buf, idx, isLE, nl, ml) {
555
+ if(isLE === undefined) isLE = true;
556
+ if(!nl) nl = 8;
557
+ if(!ml && nl === 8) ml = 52;
558
+ var e, m, el = nl * 8 - ml - 1, eMax = (1 << el) - 1, eBias = eMax >> 1;
559
+ var bits = -7, d = isLE ? -1 : 1, i = isLE ? (nl - 1) : 0, s = buf[idx + i];
560
+
561
+ i += d;
562
+ e = s & ((1 << (-bits)) - 1); s >>>= (-bits); bits += el;
563
+ for (; bits > 0; e = e * 256 + buf[idx + i], i += d, bits -= 8);
564
+ m = e & ((1 << (-bits)) - 1); e >>>= (-bits); bits += ml;
565
+ for (; bits > 0; m = m * 256 + buf[idx + i], i += d, bits -= 8);
566
+ if (e === eMax) return m ? NaN : ((s ? -1 : 1) * Infinity);
567
+ else if (e === 0) e = 1 - eBias;
568
+ else { m = m + Math.pow(2, ml); e = e - eBias; }
569
+ return (s ? -1 : 1) * m * Math.pow(2, e - ml);
570
+ }
507
571
 
508
- /* 18.8.18 family ST_FontFamily */
509
- case '<family': font.family = y.val; break;
572
+ var __toBuffer;
573
+ if(typeof Buffer !== "undefined") {
574
+ Buffer.prototype.hexlify= function() { return this.toString('hex'); };
575
+ __toBuffer = function(bufs) { return Buffer.concat(bufs[0]); };
576
+ } else {
577
+ __toBuffer = function(bufs) {
578
+ var x = [];
579
+ for(var i = 0; i != bufs[0].length; ++i) { x = x.concat(bufs[0][i]); }
580
+ return x;
581
+ };
582
+ }
510
583
 
511
- /* 18.4.14 vertAlign CT_VerticalAlignFontProperty TODO */
512
- case '<vertAlign': break;
584
+ var __readUInt8 = function(b, idx) { return b.readUInt8 ? b.readUInt8(idx) : b[idx]; };
585
+ var __readUInt16LE = function(b, idx) { return b.readUInt16LE ? b.readUInt16LE(idx) : b[idx+1]*(1<<8)+b[idx]; };
586
+ var __readInt16LE = function(b, idx) { var u = __readUInt16LE(b,idx); if(!(u & 0x8000)) return u; return (0xffff - u + 1) * -1; };
587
+ var __readUInt32LE = function(b, idx) { return b.readUInt32LE ? b.readUInt32LE(idx) : b[idx+3]*(1<<24)+b[idx+2]*(1<<16)+b[idx+1]*(1<<8)+b[idx]; };
588
+ var __readInt32LE = function(b, idx) { if(b.readInt32LE) return b.readInt32LE(idx); var u = __readUInt32LE(b,idx); if(!(u & 0x80000000)) return u; return (0xffffffff - u + 1) * -1; };
589
+ var __readDoubleLE = function(b, idx) { return b.readDoubleLE ? b.readDoubleLE(idx) : readIEEE754(b, idx||0);};
590
+
591
+
592
+ function ReadShift(size, t) {
593
+ var o = "", oo = [], w, vv, i, loc; t = t || 'u';
594
+ if(size === 'ieee754') { size = 8; t = 'f'; }
595
+ switch(size) {
596
+ case 1: o = __readUInt8(this, this.l); break;
597
+ case 2: o=(t==='u' ? __readUInt16LE : __readInt16LE)(this, this.l); break;
598
+ case 4: o = __readUInt32LE(this, this.l); break;
599
+ case 8: if(t === 'f') { o = __readDoubleLE(this, this.l); break; }
600
+ /* falls through */
601
+ case 16: o = this.toString('hex', this.l,this.l+size); break;
602
+
603
+ /* sbcs and dbcs support continue records in the SST way TODO codepages */
604
+ /* TODO: DBCS http://msdn.microsoft.com/en-us/library/cc194788.aspx */
605
+ case 'dbcs': size = 2*t; loc = this.l;
606
+ for(i = 0; i != t; ++i) {
607
+ oo.push(_getchar(__readUInt16LE(this, loc)));
608
+ loc+=2;
609
+ } o = oo.join(""); break;
610
+
611
+ case 'sbcs': size = t; o = ""; loc = this.l;
612
+ for(i = 0; i != t; ++i) {
613
+ o += _getchar(__readUInt8(this, loc));
614
+ loc+=1;
615
+ } break;
616
+ }
617
+ this.l+=size; return o;
618
+ }
513
619
 
514
- /* 18.8.35 scheme CT_FontScheme TODO */
515
- case '<scheme': break;
620
+ function prep_blob(blob, pos) {
621
+ blob.read_shift = ReadShift.bind(blob);
622
+ blob.l = pos || 0;
623
+ var read = ReadShift.bind(blob);
624
+ return [read];
625
+ }
516
626
 
517
- default:
518
- if(y[0][2] !== '/') throw 'Unrecognized rich format ' + y[0];
519
- }
520
- });
521
- /* TODO: These should be generated styles, not inline */
522
- var style = [];
523
- if(font.b) style.push("font-weight: bold;");
524
- if(font.i) style.push("font-style: italic;");
525
- intro.push('<span style="' + style.join("") + '">');
526
- outro.push("</span>");
527
- };
528
-
529
- /* 18.4.4 r CT_RElt */
530
- function parse_r(r) {
531
- var terms = [[],"",[]];
532
- /* 18.4.12 t ST_Xstring */
533
- var t = r.match(tregex);
534
- if(!isval(t)) return "";
535
- terms[1] = t[1];
536
-
537
- var rpr = r.match(rpregex);
538
- if(isval(rpr)) parse_rpr(rpr[1], terms[0], terms[2]);
539
- return terms[0].join("") + terms[1].replace(/\r\n/g,'<br/>') + terms[2].join("");
540
- }
541
- return function(rs) {
542
- return rs.replace(/<r>/g,"").split(/<\/r>/).map(parse_r).join("");
543
- };
544
- })();
545
-
546
- /* 18.4.8 si CT_Rst */
547
- var parse_si = function(x) {
548
- var z = {};
549
- if(!x) return z;
550
- var y;
551
- /* 18.4.12 t ST_Xstring (Plaintext String) */
552
- if(x[1] === 't') {
553
- z.t = utf8read(unescapexml(x.replace(/<[^>]*>/g,"")));
554
- z.raw = x;
555
- z.r = z.t;
556
- }
557
- /* 18.4.4 r CT_RElt (Rich Text Run) */
558
- else if((y = x.match(/<r>/))) {
559
- z.raw = x;
560
- /* TODO: properly parse (note: no other valid child can have body text) */
561
- z.t = utf8read(unescapexml(x.replace(/<[^>]*>/gm,"")));
562
- z.r = parse_rs(x);
563
- }
564
- /* 18.4.3 phoneticPr CT_PhoneticPr (TODO: needed for Asian support) */
565
- /* 18.4.6 rPh CT_PhoneticRun (TODO: needed for Asian support) */
566
- return z;
567
- };
627
+ function parsenoop(blob, length) { blob.l += length; }
628
+ /* [MS-XLSB] 2.1.4 Record */
629
+ var recordhopper = function(data, cb, opts) {
630
+ var tmpbyte, cntbyte, length;
631
+ prep_blob(data, data.l || 0);
632
+ while(data.l < data.length) {
633
+ var RT = data.read_shift(1);
634
+ if(RT & 0x80) RT = (RT & 0x7F) + ((data.read_shift(1) & 0x7F)<<7);
635
+ var R = RecordEnum[RT] || RecordEnum[0xFFFF];
636
+ tmpbyte = data.read_shift(1);
637
+ length = tmpbyte & 0x7F;
638
+ for(cntbyte = 1; cntbyte <4 && (tmpbyte & 0x80); ++cntbyte) length += ((tmpbyte = data.read_shift(1)) & 0x7F)<<(7*cntbyte);
639
+ var d = R.f(data, length, opts);
640
+ if(cb(d, R, RT)) return;
641
+ }
642
+ };
568
643
 
644
+ /* [MS-XLSB] 2.5.143 */
645
+ var parse_StrRun = function(data, length) {
646
+ return { ich: data.read_shift(2), ifnt: data.read_shift(2) };
647
+ };
569
648
 
570
- return function(data) {
571
- var s = [];
572
- /* 18.4.9 sst CT_Sst */
573
- var sst = data.match(new RegExp("<sst([^>]*)>([\\s\\S]*)<\/sst>","m"));
574
- if(isval(sst)) {
575
- s = sst[2].replace(/<si>/g,"").split(/<\/si>/).map(parse_si);
576
- sst = parsexmltag(sst[1]); s.Count = sst.count; s.Unique = sst.uniqueCount;
577
- }
578
- return s;
649
+ /* [MS-XLSB] 2.1.7.121 */
650
+ var parse_RichStr = function(data, length) {
651
+ var start = data.l;
652
+ var flags = data.read_shift(1);
653
+ var fRichStr = flags & 1, fExtStr = flags & 2;
654
+ var str = parse_XLWideString(data);
655
+ var rgsStrRun = [];
656
+ var z = {
657
+ t: str,
658
+ r:"<t>" + escapexml(str) + "</t>",
659
+ h: str
579
660
  };
580
- })();
661
+ if(fRichStr) {
662
+ /* TODO: formatted string */
663
+ var dwSizeStrRun = data.read_shift(4);
664
+ for(var i = 0; i != dwSizeStrRun; ++i) rgsStrRun.push(parse_StrRun(data));
665
+ }
666
+ if(fExtStr) {
667
+ /* TODO: phonetic string */
668
+ }
669
+ data.l = start + length;
670
+ return z;
671
+ };
581
672
 
582
- var ct2type = {
583
- "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml": "workbooks",
584
- "application/vnd.openxmlformats-package.core-properties+xml": "coreprops",
585
- "application/vnd.openxmlformats-officedocument.extended-properties+xml": "extprops",
586
- "application/vnd.openxmlformats-officedocument.spreadsheetml.calcChain+xml": "calcchains",
587
- "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml":"sheets",
588
- "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml": "strs",
589
- "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml":"styles",
590
- "application/vnd.openxmlformats-officedocument.theme+xml":"themes",
591
- "foo": "bar"
673
+ /* [MS-XLSB] 2.5.9 */
674
+ function parse_Cell(data) {
675
+ var col = data.read_shift(4);
676
+ var iStyleRef = data.read_shift(2);
677
+ iStyleRef += data.read_shift(1) <<16;
678
+ var fPhShow = data.read_shift(1);
679
+ return { c:col, iStyleRef: iStyleRef };
680
+ }
681
+
682
+ /* [MS-XLSB] 2.5.21 */
683
+ var parse_CodeName = function(data, length) { return parse_XLWideString(data, length); };
684
+
685
+ /* [MS-XLSB] 2.5.114 */
686
+ var parse_RelID = function(data, length) { return parse_XLNullableWideString(data, length); };
687
+
688
+ /* [MS-XLSB] 2.5.122 */
689
+ function parse_RkNumber(data) {
690
+ var b = data.slice(data.l, data.l+4);
691
+ var fX100 = b[0] & 1, fInt = b[0] & 2;
692
+ data.l+=4;
693
+ b[0] &= ~3;
694
+ var RK = fInt === 0 ? __readDoubleLE([0,0,0,0,b[0],b[1],b[2],b[3]],0) : __readInt32LE(b,0)>>2;
695
+ return fX100 ? RK/100 : RK;
696
+ }
697
+
698
+ /* [MS-XLSB] 2.5.153 */
699
+ var parse_UncheckedRfX = function(data) {
700
+ var cell = {s: {}, e: {}};
701
+ cell.s.r = data.read_shift(4);
702
+ cell.e.r = data.read_shift(4);
703
+ cell.s.c = data.read_shift(4);
704
+ cell.e.c = data.read_shift(4);
705
+ return cell;
592
706
  };
593
707
 
594
- /* 18.2.28 (CT_WorkbookProtection) Defaults */
595
- var WBPropsDef = {
596
- allowRefreshQuery: '0',
597
- autoCompressPictures: '1',
598
- backupFile: '0',
599
- checkCompatibility: '0',
600
- codeName: '',
601
- date1904: '0',
602
- dateCompatibility: '1',
603
- //defaultThemeVersion: '0',
604
- filterPrivacy: '0',
605
- hidePivotFieldList: '0',
606
- promptedSolutions: '0',
607
- publishItems: '0',
608
- refreshAllConnections: false,
609
- saveExternalLinkValues: '1',
610
- showBorderUnselectedTables: '1',
611
- showInkAnnotation: '1',
612
- showObjects: 'all',
613
- showPivotChartFilter: '0'
614
- //updateLinks: 'userSet'
708
+ /* [MS-XLSB] 2.5.166 */
709
+ var parse_XLNullableWideString = function(data) {
710
+ var cchCharacters = data.read_shift(4);
711
+ return cchCharacters === 0 || cchCharacters === 0xFFFFFFFF ? "" : data.read_shift('dbcs', cchCharacters);
615
712
  };
616
713
 
617
- /* 18.2.30 (CT_BookView) Defaults */
618
- var WBViewDef = {
619
- activeTab: '0',
620
- autoFilterDateGrouping: '1',
621
- firstSheet: '0',
622
- minimized: '0',
623
- showHorizontalScroll: '1',
624
- showSheetTabs: '1',
625
- showVerticalScroll: '1',
626
- tabRatio: '600',
627
- visibility: 'visible'
628
- //window{Height,Width}, {x,y}Window
714
+ /* [MS-XLSB] 2.5.168 */
715
+ var parse_XLWideString = function(data) {
716
+ var cchCharacters = data.read_shift(4);
717
+ return cchCharacters === 0 ? "" : data.read_shift('dbcs', cchCharacters);
629
718
  };
630
719
 
631
- /* 18.2.19 (CT_Sheet) Defaults */
632
- var SheetDef = {
633
- state: 'visible'
720
+ /* [MS-XLSB] 2.5.171 */
721
+ function parse_Xnum(data, length) { return data.read_shift('ieee754'); }
722
+
723
+ /* [MS-XLSB] 2.5.198.2 */
724
+ var BErr = {
725
+ 0x00: "#NULL!",
726
+ 0x07: "#DIV/0!",
727
+ 0x0F: "#VALUE!",
728
+ 0x17: "#REF!",
729
+ 0x1D: "#NAME?",
730
+ 0x24: "#NUM!",
731
+ 0x2A: "#N/A",
732
+ 0x2B: "#GETTING_DATA",
733
+ 0xFF: "#WTF?"
634
734
  };
735
+ var RBErr = evert(BErr);
635
736
 
636
- /* 18.2.2 (CT_CalcPr) Defaults */
637
- var CalcPrDef = {
638
- calcCompleted: 'true',
639
- calcMode: 'auto',
640
- calcOnSave: 'true',
641
- concurrentCalc: 'true',
642
- fullCalcOnLoad: 'false',
643
- fullPrecision: 'true',
644
- iterate: 'false',
645
- iterateCount: '100',
646
- iterateDelta: '0.001',
647
- refMode: 'A1'
737
+ /* Parse a list of <r> tags */
738
+ var parse_rs = (function() {
739
+ var tregex = matchtag("t"), rpregex = matchtag("rPr");
740
+ /* 18.4.7 rPr CT_RPrElt */
741
+ var parse_rpr = function(rpr, intro, outro) {
742
+ var font = {};
743
+ (rpr.match(/<[^>]*>/g)||[]).forEach(function(x) {
744
+ var y = parsexmltag(x);
745
+ switch(y[0]) {
746
+ /* 18.8.12 condense CT_BooleanProperty */
747
+ /* ** not required . */
748
+ case '<condense': break;
749
+ /* 18.8.17 extend CT_BooleanProperty */
750
+ /* ** not required . */
751
+ case '<extend': break;
752
+ /* 18.8.36 shadow CT_BooleanProperty */
753
+ /* ** not required . */
754
+ case '<shadow':
755
+ /* falls through */
756
+ case '<shadow/>': break;
757
+
758
+ /* 18.4.1 charset CT_IntProperty TODO */
759
+ case '<charset': break;
760
+
761
+ /* 18.4.2 outline CT_BooleanProperty TODO */
762
+ case '<outline':
763
+ /* falls through */
764
+ case '<outline/>': break;
765
+
766
+ /* 18.4.5 rFont CT_FontName */
767
+ case '<rFont': font.name = y.val; break;
768
+
769
+ /* 18.4.11 sz CT_FontSize */
770
+ case '<sz': font.sz = y.val; break;
771
+
772
+ /* 18.4.10 strike CT_BooleanProperty */
773
+ case '<strike':
774
+ if(!y.val) break;
775
+ /* falls through */
776
+ case '<strike/>': font.strike = 1; break;
777
+ case '</strike>': break;
778
+
779
+ /* 18.4.13 u CT_UnderlineProperty */
780
+ case '<u':
781
+ if(!y.val) break;
782
+ /* falls through */
783
+ case '<u/>': font.u = 1; break;
784
+ case '</u>': break;
785
+
786
+ /* 18.8.2 b */
787
+ case '<b':
788
+ if(!y.val) break;
789
+ /* falls through */
790
+ case '<b/>': font.b = 1; break;
791
+ case '</b>': break;
792
+
793
+ /* 18.8.26 i */
794
+ case '<i':
795
+ if(!y.val) break;
796
+ /* falls through */
797
+ case '<i/>': font.i = 1; break;
798
+ case '</i>': break;
799
+
800
+ /* 18.3.1.15 color CT_Color TODO: tint, theme, auto, indexed */
801
+ case '<color':
802
+ if(y.rgb) font.color = y.rgb.substr(2,6);
803
+ break;
804
+
805
+ /* 18.8.18 family ST_FontFamily */
806
+ case '<family': font.family = y.val; break;
807
+
808
+ /* 18.4.14 vertAlign CT_VerticalAlignFontProperty TODO */
809
+ case '<vertAlign': break;
810
+
811
+ /* 18.8.35 scheme CT_FontScheme TODO */
812
+ case '<scheme': break;
813
+
814
+ default:
815
+ if(y[0][2] !== '/') throw 'Unrecognized rich format ' + y[0];
816
+ }
817
+ });
818
+ /* TODO: These should be generated styles, not inline */
819
+ var style = [];
820
+ if(font.b) style.push("font-weight: bold;");
821
+ if(font.i) style.push("font-style: italic;");
822
+ intro.push('<span style="' + style.join("") + '">');
823
+ outro.push("</span>");
824
+ };
825
+
826
+ /* 18.4.4 r CT_RElt */
827
+ function parse_r(r) {
828
+ var terms = [[],"",[]];
829
+ /* 18.4.12 t ST_Xstring */
830
+ var t = r.match(tregex);
831
+ if(!isval(t)) return "";
832
+ terms[1] = t[1];
833
+
834
+ var rpr = r.match(rpregex);
835
+ if(isval(rpr)) parse_rpr(rpr[1], terms[0], terms[2]);
836
+ return terms[0].join("") + terms[1].replace(/\r\n/g,'<br/>') + terms[2].join("");
837
+ }
838
+ return function(rs) {
839
+ return rs.replace(/<r>/g,"").split(/<\/r>/).map(parse_r).join("");
840
+ };
841
+ })();
842
+
843
+ /* 18.4.8 si CT_Rst */
844
+ var parse_si = function(x, opts) {
845
+ var html = opts ? opts.cellHTML : true;
846
+ var z = {};
847
+ if(!x) return null;
848
+ var y;
849
+ /* 18.4.12 t ST_Xstring (Plaintext String) */
850
+ if(x[1] === 't') {
851
+ z.t = utf8read(unescapexml(x.substr(x.indexOf(">")+1).split(/<\/t>/)[0]));
852
+ z.r = x;
853
+ if(html) z.h = z.t;
854
+ }
855
+ /* 18.4.4 r CT_RElt (Rich Text Run) */
856
+ else if((y = x.match(/<r>/))) {
857
+ z.r = x;
858
+ /* TODO: properly parse (note: no other valid child can have body text) */
859
+ z.t = utf8read(unescapexml(x.replace(/<[^>]*>/gm,"")));
860
+ if(html) z.h = parse_rs(x);
861
+ }
862
+ /* 18.4.3 phoneticPr CT_PhoneticPr (TODO: needed for Asian support) */
863
+ /* 18.4.6 rPh CT_PhoneticRun (TODO: needed for Asian support) */
864
+ return z;
648
865
  };
649
866
 
650
- /* 18.2.3 (CT_CustomWorkbookView) Defaults */
651
- var CustomWBViewDef = {
652
- autoUpdate: 'false',
653
- changesSavedWin: 'false',
654
- includeHiddenRowCol: 'true',
655
- includePrintSettings: 'true',
656
- maximized: 'false',
657
- minimized: 'false',
658
- onlySync: 'false',
659
- personalView: 'false',
660
- showComments: 'commIndicator',
661
- showFormulaBar: 'true',
662
- showHorizontalScroll: 'true',
663
- showObjects: 'all',
664
- showSheetTabs: 'true',
665
- showStatusbar: 'true',
666
- showVerticalScroll: 'true',
667
- tabRatio: '600',
668
- xWindow: '0',
669
- yWindow: '0'
867
+ /* 18.4 Shared String Table */
868
+ var parse_sst_xml = function(data, opts) {
869
+ var s = [];
870
+ /* 18.4.9 sst CT_Sst */
871
+ var sst = data.match(new RegExp("<sst([^>]*)>([\\s\\S]*)<\/sst>","m"));
872
+ if(isval(sst)) {
873
+ s = sst[2].replace(/<(?:si|sstItem)>/g,"").split(/<\/(?:si|sstItem)>/).map(function(x) { return parse_si(x, opts); }).filter(function(x) { return x; });
874
+ sst = parsexmltag(sst[1]); s.Count = sst.count; s.Unique = sst.uniqueCount;
875
+ }
876
+ return s;
670
877
  };
671
878
 
672
- var XMLNS_CT = 'http://schemas.openxmlformats.org/package/2006/content-types';
673
- var XMLNS_WB = 'http://schemas.openxmlformats.org/spreadsheetml/2006/main';
879
+ /* [MS-XLSB] 2.4.219 BrtBeginSst */
880
+ var parse_BrtBeginSst = function(data, length) {
881
+ return [data.read_shift(4), data.read_shift(4)];
882
+ };
674
883
 
675
- var strs = {}; // shared strings
884
+ /* [MS-XLSB] 2.1.7.45 Shared Strings */
885
+ var parse_sst_bin = function(data) {
886
+ var s = [];
887
+ recordhopper(data, function(val, R) {
888
+ switch(R.n) {
889
+ case 'BrtBeginSst': s.Count = val[0]; s.Unique = val[1]; break;
890
+ case 'BrtSSTItem': s.push(val); break;
891
+ case 'BrtEndSst': return true;
892
+ default: throw new Error("Unexpected record " + R.n);
893
+ }
894
+ });
895
+ return s;
896
+ };
676
897
  var styles = {}; // shared styles
677
- var _ssfopts = {}; // spreadsheet formatting options
678
898
 
679
- /* 18.3 Worksheets */
680
- function parseSheet(data) {
681
- if(!data) return data;
682
- /* 18.3.1.99 worksheet CT_Worksheet */
683
- var s = {};
684
-
685
- /* 18.3.1.35 dimension CT_SheetDimension ? */
686
- var ref = data.match(/<dimension ref="([^"]*)"\s*\/>/);
687
- if(ref && ref.length == 2 && ref[1].indexOf(":") !== -1) s["!ref"] = ref[1];
899
+ /* 18.8.31 numFmts CT_NumFmts */
900
+ function parseNumFmts(t) {
901
+ styles.NumberFmt = [];
902
+ for(var y in SSF._table) styles.NumberFmt[y] = SSF._table[y];
903
+ t[0].match(/<[^>]*>/g).forEach(function(x) {
904
+ var y = parsexmltag(x);
905
+ switch(y[0]) {
906
+ case '<numFmts': case '</numFmts>': case '<numFmts/>': break;
907
+ case '<numFmt': {
908
+ var f=unescapexml(y.formatCode), i=parseInt(y.numFmtId,10);
909
+ styles.NumberFmt[i] = f; if(i>0) SSF.load(f,i);
910
+ } break;
911
+ default: throw 'unrecognized ' + y[0] + ' in numFmts';
912
+ }
913
+ });
914
+ }
688
915
 
689
- var refguess = {s: {r:1000000, c:1000000}, e: {r:0, c:0} };
690
- var q = ["v","f"];
691
- var sidx = 0;
692
- /* 18.3.1.80 sheetData CT_SheetData ? */
693
- if(!data.match(/<sheetData *\/>/))
694
- data.match(/<sheetData>([^\u2603]*)<\/sheetData>/m)[1].split("</row>").forEach(function(x) {
695
- if(x === "" || x.trim() === "") return;
916
+ /* 18.8.10 cellXfs CT_CellXfs */
917
+ function parseCXfs(t) {
918
+ styles.CellXf = [];
919
+ t[0].match(/<[^>]*>/g).forEach(function(x) {
920
+ var y = parsexmltag(x);
921
+ switch(y[0]) {
922
+ case '<cellXfs': case '<cellXfs/>': case '</cellXfs>': break;
696
923
 
697
- /* 18.3.1.73 row CT_Row */
698
- var row = parsexmltag(x.match(/<row[^>]*>/)[0]);
699
- if(refguess.s.r > row.r - 1) refguess.s.r = row.r - 1;
700
- if(refguess.e.r < row.r - 1) refguess.e.r = row.r - 1;
924
+ /* 18.8.45 xf CT_Xf */
925
+ case '<xf': delete y[0];
926
+ if(y.numFmtId) y.numFmtId = parseInt(y.numFmtId, 10);
927
+ styles.CellXf.push(y); break;
928
+ case '</xf>': break;
701
929
 
702
- /* 18.3.1.4 c CT_Cell */
703
- var cells = x.substr(x.indexOf('>')+1).split(/<c/);
704
- cells.forEach(function(c, idx) { if(c === "" || c.trim() === "") return;
705
- var cref = c.match(/r="([^"]*)"/);
706
- c = "<c" + c;
707
- if(cref && cref.length == 2) {
708
- var cref_cell = decode_cell(cref[1]);
709
- idx = cref_cell.c;
710
- }
711
- if(refguess.s.c > idx) refguess.s.c = idx;
712
- if(refguess.e.c < idx) refguess.e.c = idx;
713
- var cell = parsexmltag((c.match(/<c[^>]*>/)||[c])[0]); delete cell[0];
714
- var d = c.substr(c.indexOf('>')+1);
715
- var p = {};
716
- q.forEach(function(f){var x=d.match(matchtag(f));if(x)p[f]=unescapexml(x[1]);});
930
+ /* 18.8.1 alignment CT_CellAlignment */
931
+ case '<alignment': break;
717
932
 
718
- /* SCHEMA IS ACTUALLY INCORRECT HERE. IF A CELL HAS NO T, EMIT "" */
719
- if(cell.t === undefined && p.v === undefined) { p.t = "str"; p.v = undefined; }
720
- else p.t = (cell.t ? cell.t : "n"); // default is "n" in schema
721
- switch(p.t) {
722
- case 'n': p.v = parseFloat(p.v); break;
723
- case 's': {
724
- sidx = parseInt(p.v, 10);
725
- p.v = strs[sidx].t;
726
- p.r = strs[sidx].r;
727
- } break;
728
- case 'str': if(p.v) p.v = utf8read(p.v); break; // normal string
729
- case 'inlineStr':
730
- p.t = 'str'; p.v = unescapexml((d.match(matchtag('t'))||["",""])[1]);
731
- break; // inline string
732
- case 'b':
733
- switch(p.v) {
734
- case '0': case 'FALSE': case "false": case false: p.v=false; break;
735
- case '1': case 'TRUE': case "true": case true: p.v=true; break;
736
- default: throw "Unrecognized boolean: " + p.v;
737
- } break;
738
- /* in case of error, stick value in .raw */
739
- case 'e': p.raw = p.v; p.v = undefined; break;
740
- default: throw "Unrecognized cell type: " + p.t;
741
- }
933
+ /* 18.8.33 protection CT_CellProtection */
934
+ case '<protection': case '</protection>': case '<protection/>': break;
742
935
 
743
- /* formatting */
744
- if(cell.s && styles.CellXf) { /* TODO: second check is a hacked guard */
745
- var cf = styles.CellXf[cell.s];
746
- if(cf && cf.numFmtId && cf.numFmtId !== 0) {
747
- p.raw = p.v;
748
- p.rawt = p.t;
749
- try {
750
- p.v = SSF.format(cf.numFmtId,p.v,_ssfopts);
751
- p.t = 'str';
752
- } catch(e) { p.v = p.raw; }
753
- }
754
- }
936
+ case '<extLst': case '</extLst>': break;
937
+ case '<ext': break;
938
+ default: throw 'unrecognized ' + y[0] + ' in cellXfs';
939
+ }
940
+ });
941
+ }
755
942
 
756
- s[cell.r] = p;
757
- });
943
+ /* 18.8 Styles CT_Stylesheet*/
944
+ function parse_sty_xml(data) {
945
+ /* 18.8.39 styleSheet CT_Stylesheet */
946
+ var t;
947
+
948
+ /* numFmts CT_NumFmts ? */
949
+ if((t=data.match(/<numFmts([^>]*)>.*<\/numFmts>/))) parseNumFmts(t);
950
+
951
+ /* fonts CT_Fonts ? */
952
+ /* fills CT_Fills ? */
953
+ /* borders CT_Borders ? */
954
+ /* cellStyleXfs CT_CellStyleXfs ? */
955
+
956
+ /* cellXfs CT_CellXfs ? */
957
+ if((t=data.match(/<cellXfs([^>]*)>.*<\/cellXfs>/))) parseCXfs(t);
958
+
959
+ /* dxfs CT_Dxfs ? */
960
+ /* tableStyles CT_TableStyles ? */
961
+ /* colors CT_Colors ? */
962
+ /* extLst CT_ExtensionList ? */
963
+
964
+ return styles;
965
+ }
966
+ function parse_BrtFmt(data, length) {
967
+ var ifmt = data.read_shift(2);
968
+ var stFmtCode = parse_XLWideString(data,length-2);
969
+ return [ifmt, stFmtCode];
970
+ }
971
+
972
+ function parse_BrtXF(data, length) {
973
+ var ixfeParent = data.read_shift(2);
974
+ var ifmt = data.read_shift(2);
975
+ parsenoop(data, length-4);
976
+ return {ixfe:ixfeParent, ifmt:ifmt };
977
+ }
978
+
979
+ function parse_sty_bin(data) {
980
+ styles.NumberFmt = [];
981
+ for(var y in SSF._table) styles.NumberFmt[y] = SSF._table[y];
982
+
983
+ styles.CellXf = [];
984
+ var state = ""; /* TODO: this should be a stack */
985
+ var pass = false;
986
+ recordhopper(data, function(val, R, RT) {
987
+ switch(R.n) {
988
+ case 'BrtFmt':
989
+ styles.NumberFmt[val[0]] = val[1]; SSF.load(val[1], val[0]);
990
+ break;
991
+ case 'BrtFont': break; /* TODO */
992
+ case 'BrtKnownFonts': break; /* TODO */
993
+ case 'BrtFill': break; /* TODO */
994
+ case 'BrtBorder': break; /* TODO */
995
+ case 'BrtXF':
996
+ if(state === "CELLXFS") {
997
+ styles.CellXf.push(val);
998
+ }
999
+ break; /* TODO */
1000
+ case 'BrtStyle': break; /* TODO */
1001
+ case 'BrtRowHdr': break; /* TODO */
1002
+ case 'BrtCellMeta': break; /* ?? */
1003
+ case 'BrtDXF': break; /* TODO */
1004
+ case 'BrtMRUColor': break; /* TODO */
1005
+ case 'BrtIndexedColor': break; /* TODO */
1006
+ case 'BrtBeginStyleSheet': break;
1007
+ case 'BrtEndStyleSheet': break;
1008
+ case 'BrtBeginTableStyle': break;
1009
+ case 'BrtTableStyleElement': break;
1010
+ case 'BrtEndTableStyle': break;
1011
+ case 'BrtBeginFmts': state = "FMTS"; break;
1012
+ case 'BrtEndFmts': state = ""; break;
1013
+ case 'BrtBeginFonts': state = "FONTS"; break;
1014
+ case 'BrtEndFonts': state = ""; break;
1015
+ case 'BrtACBegin': state = "ACFONTS"; break;
1016
+ case 'BrtACEnd': state = ""; break;
1017
+ case 'BrtBeginFills': state = "FILLS"; break;
1018
+ case 'BrtEndFills': state = ""; break;
1019
+ case 'BrtBeginBorders': state = "BORDERS"; break;
1020
+ case 'BrtEndBorders': state = ""; break;
1021
+ case 'BrtBeginCellStyleXFs': state = "CELLSTYLEXFS"; break;
1022
+ case 'BrtEndCellStyleXFs': state = ""; break;
1023
+ case 'BrtBeginCellXFs': state = "CELLXFS"; break;
1024
+ case 'BrtEndCellXFs': state = ""; break;
1025
+ case 'BrtBeginStyles': state = "STYLES"; break;
1026
+ case 'BrtEndStyles': state = ""; break;
1027
+ case 'BrtBeginDXFs': state = "DXFS"; break;
1028
+ case 'BrtEndDXFs': state = ""; break;
1029
+ case 'BrtBeginTableStyles': state = "TABLESTYLES"; break;
1030
+ case 'BrtEndTableStyles': state = ""; break;
1031
+ case 'BrtBeginColorPalette': state = "COLORPALETTE"; break;
1032
+ case 'BrtBeginIndexedColors': state = "INDEXEDCOLORS"; break;
1033
+ case 'BrtEndIndexedColors': state = ""; break;
1034
+ case 'BrtBeginMRUColors': state = "MRUCOLORS"; break;
1035
+ case 'BrtEndMRUColors': state = ""; break;
1036
+ case 'BrtEndColorPalette': state = ""; break;
1037
+ case 'BrtFRTBegin': pass = true; break;
1038
+ case 'BrtFRTEnd': pass = false; break;
1039
+ //default: if(!pass) throw new Error("Unexpected record " + RT + " " + R.n);
1040
+ }
758
1041
  });
759
- if(!s["!ref"]) s["!ref"] = encode_range(refguess);
760
- return s;
1042
+ return styles;
761
1043
  }
762
1044
 
1045
+ var ct2type = {
1046
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml": "workbooks", /*XLSX*/
1047
+ "application/vnd.ms-excel.sheet.macroEnabled.main+xml":"workbooks", /*XLSM*/
1048
+ "application/vnd.ms-excel.sheet.binary.macroEnabled.main":"workbooks", /*XLSB*/
1049
+
1050
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml":"sheets", /*XLS[XM]*/
1051
+ "application/vnd.ms-excel.worksheet":"sheets", /*XLSB*/
1052
+
1053
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml":"styles", /*XLS[XM]*/
1054
+ "application/vnd.ms-excel.styles":"styles", /*XLSB*/
1055
+
1056
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml": "strs", /*XLS[XM]*/
1057
+ "application/vnd.ms-excel.sharedStrings": "strs", /*XLSB*/
1058
+
1059
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.calcChain+xml": "calcchains", /*XLS[XM]*/
1060
+ //"application/vnd.ms-excel.calcChain": "calcchains", /*XLSB*/
1061
+
1062
+ "application/vnd.openxmlformats-package.core-properties+xml": "coreprops",
1063
+ "application/vnd.openxmlformats-officedocument.extended-properties+xml": "extprops",
1064
+ "application/vnd.openxmlformats-officedocument.custom-properties+xml": "custprops",
1065
+ "application/vnd.openxmlformats-officedocument.theme+xml":"themes",
1066
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml": "comments",
1067
+ "foo": "bar"
1068
+ };
1069
+
1070
+ var XMLNS_CT = 'http://schemas.openxmlformats.org/package/2006/content-types';
1071
+
763
1072
  function parseProps(data) {
764
1073
  var p = { Company:'' }, q = {};
765
1074
  var strings = ["Application", "DocSecurity", "Company", "AppVersion"];
@@ -785,11 +1094,11 @@ function parseProps(data) {
785
1094
  var j = 0, widx = 0;
786
1095
  for(var i = 0; i !== v.length; ++i) {
787
1096
  switch(v[i].v) {
788
- case "Worksheets": widx = j; p.Worksheets = +v[++i]; break;
1097
+ case "Worksheets": widx = j; p.Worksheets = +(v[++i].v); break;
789
1098
  case "Named Ranges": ++i; break; // TODO: Handle Named Ranges
790
1099
  }
791
1100
  }
792
- var parts = parseVector(q.TitlesOfParts).map(utf8read);
1101
+ var parts = parseVector(q.TitlesOfParts).map(function(x) { return utf8read(x.v); });
793
1102
  p.SheetNames = parts.slice(widx, widx + p.Worksheets);
794
1103
  }
795
1104
  p.Creator = q["dc:creator"];
@@ -799,6 +1108,46 @@ function parseProps(data) {
799
1108
  return p;
800
1109
  }
801
1110
 
1111
+ /* 15.2.12.2 Custom File Properties Part */
1112
+ function parseCustomProps(data) {
1113
+ var p = {}, name;
1114
+ data.match(/<[^>]+>([^<]*)/g).forEach(function(x) {
1115
+ var y = parsexmltag(x);
1116
+ switch(y[0]) {
1117
+ case '<property': name = y.name; break;
1118
+ case '</property>': name = null; break;
1119
+ default: if (x.indexOf('<vt:') === 0) {
1120
+ var toks = x.split('>');
1121
+ var type = toks[0].substring(4), text = toks[1];
1122
+ /* 22.4.2.32 (CT_Variant). Omit the binary types from 22.4 (Variant Types) */
1123
+ switch(type) {
1124
+ case 'lpstr': case 'lpwstr': case 'bstr': case 'lpwstr':
1125
+ p[name] = unescapexml(text);
1126
+ break;
1127
+ case 'bool':
1128
+ p[name] = parsexmlbool(text, '<vt:bool>');
1129
+ break;
1130
+ case 'i1': case 'i2': case 'i4': case 'i8': case 'int': case 'uint':
1131
+ p[name] = parseInt(text, 10);
1132
+ break;
1133
+ case 'r4': case 'r8': case 'decimal':
1134
+ p[name] = parseFloat(text);
1135
+ break;
1136
+ case 'filetime': case 'date':
1137
+ p[name] = text; // should we make this into a date?
1138
+ break;
1139
+ case 'cy': case 'error':
1140
+ p[name] = unescapexml(text);
1141
+ break;
1142
+ default:
1143
+ console.warn('Unexpected', x, type, toks);
1144
+ }
1145
+ }
1146
+ }
1147
+ });
1148
+ return p;
1149
+ }
1150
+
802
1151
  /* 18.6 Calculation Chain */
803
1152
  function parseDeps(data) {
804
1153
  var d = [];
@@ -817,11 +1166,10 @@ function parseDeps(data) {
817
1166
  }
818
1167
 
819
1168
  var ctext = {};
820
-
821
1169
  function parseCT(data) {
822
1170
  if(!data || !data.match) return data;
823
1171
  var ct = { workbooks: [], sheets: [], calcchains: [], themes: [], styles: [],
824
- coreprops: [], extprops: [], strs:[], xmlns: "" };
1172
+ coreprops: [], extprops: [], custprops: [], strs:[], comments: [], xmlns: "" };
825
1173
  (data.match(/<[^>]*>/g)||[]).forEach(function(x) {
826
1174
  var y = parsexmltag(x);
827
1175
  switch(y[0]) {
@@ -842,8 +1190,519 @@ function parseCT(data) {
842
1190
  }
843
1191
 
844
1192
 
1193
+
1194
+ /* 9.3.2 OPC Relationships Markup */
1195
+ function parseRels(data, currentFilePath) {
1196
+ if (!data) return data;
1197
+ if (currentFilePath.charAt(0) !== '/') {
1198
+ currentFilePath = '/'+currentFilePath;
1199
+ }
1200
+ var rels = {};
1201
+
1202
+ var resolveRelativePathIntoAbsolute = function (to) {
1203
+ var toksFrom = currentFilePath.split('/');
1204
+ toksFrom.pop(); // folder path
1205
+ var toksTo = to.split('/');
1206
+ var reversed = [];
1207
+ while (toksTo.length !== 0) {
1208
+ var tokTo = toksTo.shift();
1209
+ if (tokTo === '..') {
1210
+ toksFrom.pop();
1211
+ } else if (tokTo !== '.') {
1212
+ toksFrom.push(tokTo);
1213
+ }
1214
+ }
1215
+ return toksFrom.join('/');
1216
+ };
1217
+
1218
+ data.match(/<[^>]*>/g).forEach(function(x) {
1219
+ var y = parsexmltag(x);
1220
+ /* 9.3.2.2 OPC_Relationships */
1221
+ if (y[0] === '<Relationship') {
1222
+ var rel = {}; rel.Type = y.Type; rel.Target = y.Target; rel.Id = y.Id; rel.TargetMode = y.TargetMode;
1223
+ var canonictarget = resolveRelativePathIntoAbsolute(y.Target);
1224
+ rels[canonictarget] = rel;
1225
+ }
1226
+ });
1227
+
1228
+ return rels;
1229
+ }
1230
+
1231
+
1232
+ /* 18.7.3 CT_Comment */
1233
+ function parse_comments_xml(data, opts) {
1234
+ if(data.match(/<comments *\/>/)) return [];
1235
+ var authors = [];
1236
+ var commentList = [];
1237
+ data.match(/<authors>([^\u2603]*)<\/authors>/m)[1].split('</author>').forEach(function(x) {
1238
+ if(x === "" || x.trim() === "") return;
1239
+ authors.push(x.match(/<author[^>]*>(.*)/)[1]);
1240
+ });
1241
+ data.match(/<commentList>([^\u2603]*)<\/commentList>/m)[1].split('</comment>').forEach(function(x, index) {
1242
+ if(x === "" || x.trim() === "") return;
1243
+ var y = parsexmltag(x.match(/<comment[^>]*>/)[0]);
1244
+ var comment = { author: y.authorId && authors[y.authorId] ? authors[y.authorId] : undefined, ref: y.ref, guid: y.guid };
1245
+ var cell = decode_cell(y.ref);
1246
+ if(opts.sheetRows && opts.sheetRows <= cell.r) return;
1247
+ var textMatch = x.match(/<text>([^\u2603]*)<\/text>/m);
1248
+ if (!textMatch || !textMatch[1]) return; // a comment may contain an empty text tag.
1249
+ var rt = parse_si(textMatch[1]);
1250
+ comment.r = rt.r;
1251
+ comment.t = rt.t;
1252
+ if(opts.cellHTML) comment.h = rt.h;
1253
+ commentList.push(comment);
1254
+ });
1255
+ return commentList;
1256
+ }
1257
+
1258
+ function parse_comments(zip, dirComments, sheets, sheetRels, opts) {
1259
+ for(var i = 0; i != dirComments.length; ++i) {
1260
+ var canonicalpath=dirComments[i];
1261
+ var comments=parse_comments_xml(getzipdata(zip, canonicalpath.replace(/^\//,''), true), opts);
1262
+ if(!comments || !comments.length) continue;
1263
+ // find the sheets targeted by these comments
1264
+ var sheetNames = Object.keys(sheets);
1265
+ for(var j = 0; j != sheetNames.length; ++j) {
1266
+ var sheetName = sheetNames[j];
1267
+ var rels = sheetRels[sheetName];
1268
+ if(rels) {
1269
+ var rel = rels[canonicalpath];
1270
+ if(rel) insertCommentsIntoSheet(sheetName, sheets[sheetName], comments);
1271
+ }
1272
+ }
1273
+ }
1274
+ }
1275
+
1276
+ function insertCommentsIntoSheet(sheetName, sheet, comments) {
1277
+ comments.forEach(function(comment) {
1278
+ var cell = sheet[comment.ref];
1279
+ if (!cell) {
1280
+ cell = {};
1281
+ sheet[comment.ref] = cell;
1282
+ var range = decode_range(sheet["!ref"]);
1283
+ var thisCell = decode_cell(comment.ref);
1284
+ if(range.s.r > thisCell.r) range.s.r = thisCell.r;
1285
+ if(range.e.r < thisCell.r) range.e.r = thisCell.r;
1286
+ if(range.s.c > thisCell.c) range.s.c = thisCell.c;
1287
+ if(range.e.c < thisCell.c) range.e.c = thisCell.c;
1288
+ var encoded = encode_range(range);
1289
+ if (encoded !== sheet["!ref"]) sheet["!ref"] = encoded;
1290
+ }
1291
+
1292
+ if (!cell.c) cell.c = [];
1293
+ var o = {a: comment.author, t: comment.t, r: comment.r};
1294
+ if(comment.h) o.h = comment.h;
1295
+ cell.c.push(o);
1296
+ });
1297
+ }
1298
+
1299
+ /* [MS-XLSB] 2.5.97.4 CellParsedFormula TODO: use similar logic to js-xls */
1300
+ var parse_CellParsedFormula = function(data, length) {
1301
+ var cce = data.read_shift(4);
1302
+ return parsenoop(data, length-4);
1303
+ };
1304
+ var strs = {}; // shared strings
1305
+ var _ssfopts = {}; // spreadsheet formatting options
1306
+
1307
+ /* 18.3 Worksheets */
1308
+ function parse_ws_xml(data, opts) {
1309
+ if(!data) return data;
1310
+ /* 18.3.1.99 worksheet CT_Worksheet */
1311
+ var s = {};
1312
+
1313
+ /* 18.3.1.35 dimension CT_SheetDimension ? */
1314
+ var ref = data.match(/<dimension ref="([^"]*)"\s*\/>/);
1315
+ if(ref && ref.length == 2 && ref[1].indexOf(":") !== -1) s["!ref"] = ref[1];
1316
+
1317
+ var refguess = {s: {r:1000000, c:1000000}, e: {r:0, c:0} };
1318
+ var q = ["v","f"];
1319
+ var sidx = 0;
1320
+ /* 18.3.1.80 sheetData CT_SheetData ? */
1321
+ if(!data.match(/<sheetData *\/>/))
1322
+ data.match(/<sheetData>([^\u2603]*)<\/sheetData>/m)[1].split("</row>").forEach(function(x) {
1323
+ if(x === "" || x.trim() === "") return;
1324
+
1325
+ /* 18.3.1.73 row CT_Row */
1326
+ var row = parsexmltag(x.match(/<row[^>]*>/)[0]);
1327
+ if(opts.sheetRows && opts.sheetRows < +row.r) return;
1328
+ if(refguess.s.r > row.r - 1) refguess.s.r = row.r - 1;
1329
+ if(refguess.e.r < row.r - 1) refguess.e.r = row.r - 1;
1330
+ /* 18.3.1.4 c CT_Cell */
1331
+ var cells = x.substr(x.indexOf('>')+1).split(/<c /);
1332
+ cells.forEach(function(c, idx) { if(c === "" || c.trim() === "") return;
1333
+ var cref = c.match(/r=["']([^"']*)["']/);
1334
+ c = "<c " + c;
1335
+ if(cref && cref.length == 2) idx = decode_cell(cref[1]).c;
1336
+ var cell = parsexmltag((c.match(/<c[^>]*>/)||[c])[0]); delete cell[0];
1337
+ var d = c.substr(c.indexOf('>')+1);
1338
+ var p = {};
1339
+ q.forEach(function(f){var x=d.match(matchtag(f));if(x)p[f]=unescapexml(x[1]);});
1340
+
1341
+ /* SCHEMA IS ACTUALLY INCORRECT HERE. IF A CELL HAS NO T, EMIT "" */
1342
+ if(cell.t === undefined && p.v === undefined) {
1343
+ if(!opts.sheetStubs) return;
1344
+ p.t = "str"; p.v = undefined;
1345
+ }
1346
+ else p.t = (cell.t ? cell.t : "n"); // default is "n" in schema
1347
+ if(refguess.s.c > idx) refguess.s.c = idx;
1348
+ if(refguess.e.c < idx) refguess.e.c = idx;
1349
+ /* 18.18.11 t ST_CellType */
1350
+ switch(p.t) {
1351
+ case 'n': p.v = parseFloat(p.v); break;
1352
+ case 's': {
1353
+ sidx = parseInt(p.v, 10);
1354
+ p.v = strs[sidx].t;
1355
+ p.r = strs[sidx].r;
1356
+ if(opts.cellHTML) p.h = strs[sidx].h;
1357
+ } break;
1358
+ case 'str': if(p.v) p.v = utf8read(p.v); break;
1359
+ case 'inlineStr':
1360
+ var is = d.match(/<is>(.*)<\/is>/);
1361
+ is = is ? parse_si(is[1]) : {t:"",r:""};
1362
+ p.t = 'str'; p.v = is.t;
1363
+ break; // inline string
1364
+ case 'b': if(typeof p.v !== 'boolean') p.v = parsexmlbool(p.v); break;
1365
+ case 'd': /* TODO: date1904 logic */
1366
+ var epoch = Date.parse(p.v);
1367
+ p.v = (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000);
1368
+ p.t = 'n';
1369
+ break;
1370
+ /* in case of error, stick value in .raw */
1371
+ case 'e': p.raw = RBErr[p.v]; break;
1372
+ }
1373
+
1374
+ /* formatting */
1375
+ var fmtid = 0;
1376
+ if(cell.s && styles.CellXf) {
1377
+ var cf = styles.CellXf[cell.s];
1378
+ if(cf && cf.numFmtId) fmtid = cf.numFmtId;
1379
+ }
1380
+ try {
1381
+ p.w = SSF.format(fmtid,p.v,_ssfopts);
1382
+ if(opts.cellNF) p.z = SSF._table[fmtid];
1383
+ } catch(e) { if(opts.WTF) throw e; }
1384
+ s[cell.r] = p;
1385
+ });
1386
+ });
1387
+ if(!s["!ref"]) s["!ref"] = encode_range(refguess);
1388
+ if(opts.sheetRows) {
1389
+ var tmpref = decode_range(s["!ref"]);
1390
+ if(opts.sheetRows < +tmpref.e.r) {
1391
+ tmpref.e.r = opts.sheetRows - 1;
1392
+ if(tmpref.e.r > refguess.e.r) tmpref.e.r = refguess.e.r;
1393
+ if(tmpref.e.r < tmpref.s.r) tmpref.s.r = tmpref.e.r;
1394
+ if(tmpref.e.c > refguess.e.c) tmpref.e.c = refguess.e.c;
1395
+ if(tmpref.e.c < tmpref.s.c) tmpref.s.c = tmpref.e.c;
1396
+ s["!fullref"] = s["!ref"];
1397
+ s["!ref"] = encode_range(tmpref);
1398
+ }
1399
+ }
1400
+ return s;
1401
+ }
1402
+
1403
+
1404
+ /* [MS-XLSB] 2.4.718 BrtRowHdr */
1405
+ var parse_BrtRowHdr = function(data, length) {
1406
+ var z = {};
1407
+ z.r = data.read_shift(4);
1408
+ data.l += length-4;
1409
+ return z;
1410
+ };
1411
+
1412
+ /* [MS-XLSB] 2.4.812 BrtWsDim */
1413
+ var parse_BrtWsDim = parse_UncheckedRfX;
1414
+
1415
+ /* [MS-XLSB] 2.4.815 BrtWsProp */
1416
+ var parse_BrtWsProp = function(data, length) {
1417
+ var z = {};
1418
+ /* TODO: pull flags */
1419
+ data.l += 19;
1420
+ z.name = parse_CodeName(data, length - 19);
1421
+ return z;
1422
+ };
1423
+
1424
+ /* [MS-XLSB] 2.4.303 BrtCellBlank */
1425
+ var parse_BrtCellBlank = parsenoop;
1426
+
1427
+ /* [MS-XLSB] 2.4.304 BrtCellBool */
1428
+ var parse_BrtCellBool = function(data, length) {
1429
+ var cell = parse_Cell(data);
1430
+ var fBool = data.read_shift(1);
1431
+ return [cell, fBool, 'b'];
1432
+ };
1433
+
1434
+ /* [MS-XLSB] 2.4.305 BrtCellError */
1435
+ var parse_BrtCellError = function(data, length) {
1436
+ var cell = parse_Cell(data);
1437
+ var fBool = data.read_shift(1);
1438
+ return [cell, fBool, 'e'];
1439
+ };
1440
+
1441
+ /* [MS-XLSB] 2.4.308 BrtCellIsst */
1442
+ var parse_BrtCellIsst = function(data, length) {
1443
+ var cell = parse_Cell(data);
1444
+ var isst = data.read_shift(4);
1445
+ return [cell, isst, 's'];
1446
+ };
1447
+
1448
+ /* [MS-XLSB] 2.4.310 BrtCellReal */
1449
+ var parse_BrtCellReal = function(data, length) {
1450
+ var cell = parse_Cell(data);
1451
+ var value = parse_Xnum(data);
1452
+ return [cell, value, 'n'];
1453
+ };
1454
+
1455
+ /* [MS-XLSB] 2.4.311 BrtCellRk */
1456
+ var parse_BrtCellRk = function(data, length) {
1457
+ var cell = parse_Cell(data);
1458
+ var value = parse_RkNumber(data);
1459
+ return [cell, value, 'n'];
1460
+ };
1461
+
1462
+ /* [MS-XLSB] 2.4.314 BrtCellSt */
1463
+ var parse_BrtCellSt = function(data, length) {
1464
+ var cell = parse_Cell(data);
1465
+ var value = parse_XLWideString(data);
1466
+ return [cell, value, 'str'];
1467
+ };
1468
+
1469
+ /* [MS-XLSB] 2.4.647 BrtFmlaBool */
1470
+ var parse_BrtFmlaBool = function(data, length, opts) {
1471
+ var cell = parse_Cell(data);
1472
+ var value = data.read_shift(1);
1473
+ var o = [cell, value, 'b'];
1474
+ if(opts.cellFormula) {
1475
+ var formula = parse_CellParsedFormula(data, length-9);
1476
+ o[3] = ""; /* TODO */
1477
+ }
1478
+ else data.l += length-9;
1479
+ return o;
1480
+ };
1481
+
1482
+ /* [MS-XLSB] 2.4.648 BrtFmlaError */
1483
+ var parse_BrtFmlaError = function(data, length, opts) {
1484
+ var cell = parse_Cell(data);
1485
+ var value = data.read_shift(1);
1486
+ var o = [cell, value, 'e'];
1487
+ if(opts.cellFormula) {
1488
+ var formula = parse_CellParsedFormula(data, length-9);
1489
+ o[3] = ""; /* TODO */
1490
+ }
1491
+ else data.l += length-9;
1492
+ return o;
1493
+ };
1494
+
1495
+ /* [MS-XLSB] 2.4.649 BrtFmlaNum */
1496
+ var parse_BrtFmlaNum = function(data, length, opts) {
1497
+ var cell = parse_Cell(data);
1498
+ var value = parse_Xnum(data);
1499
+ var o = [cell, value, 'n'];
1500
+ if(opts.cellFormula) {
1501
+ var formula = parse_CellParsedFormula(data, length - 16);
1502
+ o[3] = ""; /* TODO */
1503
+ }
1504
+ else data.l += length-16;
1505
+ return o;
1506
+ };
1507
+
1508
+ /* [MS-XLSB] 2.4.650 BrtFmlaString */
1509
+ var parse_BrtFmlaString = function(data, length, opts) {
1510
+ var start = data.l;
1511
+ var cell = parse_Cell(data);
1512
+ var value = parse_XLWideString(data);
1513
+ var o = [cell, value, 'str'];
1514
+ if(opts.cellFormula) {
1515
+ var formula = parse_CellParsedFormula(data, start + length - data.l);
1516
+ o[3] = ""; /* TODO */
1517
+ }
1518
+ else data.l = start + length;
1519
+ return o;
1520
+ };
1521
+
1522
+ /* [MS-XLSB] 2.1.7.61 Worksheet */
1523
+ var parse_ws_bin = function(data, opts) {
1524
+ if(!data) return data;
1525
+ var s = {};
1526
+
1527
+ var ref;
1528
+ var refguess = {s: {r:1000000, c:1000000}, e: {r:0, c:0} };
1529
+
1530
+ var pass = false, end = false;
1531
+ var row, p, cf;
1532
+ recordhopper(data, function(val, R) {
1533
+ if(end) return;
1534
+ switch(R.n) {
1535
+ case 'BrtWsDim': ref = val; break;
1536
+ case 'BrtRowHdr':
1537
+ row = val;
1538
+ if(opts.sheetRows && opts.sheetRows <= row.r) end=true;
1539
+ break;
1540
+
1541
+ case 'BrtFmlaBool':
1542
+ case 'BrtFmlaError':
1543
+ case 'BrtFmlaNum':
1544
+ case 'BrtFmlaString':
1545
+ case 'BrtCellBool':
1546
+ case 'BrtCellError':
1547
+ case 'BrtCellIsst':
1548
+ case 'BrtCellReal':
1549
+ case 'BrtCellRk':
1550
+ p = {t:val[2]};
1551
+ switch(val[2]) {
1552
+ case 'n': p.v = val[1]; break;
1553
+ case 's': p.v = strs[val[1]].t; p.r = strs[val[1]].r; break;
1554
+ case 'b': p.v = val[1] ? true : false; break;
1555
+ case 'e': p.raw = val[1]; p.v = BErr[p.raw]; break;
1556
+ case 'str': p.v = utf8read(val[1]); break;
1557
+ }
1558
+ if(opts.cellFormula && val.length > 3) p.f = val[3];
1559
+ if((cf = styles.CellXf[val[0].iStyleRef])) try {
1560
+ p.w = SSF.format(cf.ifmt,p.v,_ssfopts);
1561
+ if(opts.cellNF) p.z = SSF._table[cf.ifmt];
1562
+ } catch(e) { if(opts.WTF) throw e; }
1563
+ s[encode_cell({c:val[0].c,r:row.r})] = p;
1564
+ if(refguess.s.r > row.r) refguess.s.r = row.r;
1565
+ if(refguess.s.c > val[0].c) refguess.s.c = val[0].c;
1566
+ if(refguess.e.r < row.r) refguess.e.r = row.r;
1567
+ if(refguess.e.c < val[0].c) refguess.e.c = val[0].c;
1568
+ break;
1569
+
1570
+ case 'BrtCellBlank': break; // (blank cell)
1571
+
1572
+ case 'BrtArrFmla': break; // TODO
1573
+ case 'BrtShrFmla': break; // TODO
1574
+ case 'BrtBeginSheet': break;
1575
+ case 'BrtWsProp': break; // TODO
1576
+ case 'BrtSheetCalcProp': break; // TODO
1577
+ case 'BrtBeginWsViews': break; // TODO
1578
+ case 'BrtBeginWsView': break; // TODO
1579
+ case 'BrtEndWsView': break; // TODO
1580
+ case 'BrtEndWsViews': break; // TODO
1581
+ case 'BrtSel': break; // TODO
1582
+ case 'BrtACBegin': break; // TODO
1583
+ case 'BrtACEnd': break; // TODO
1584
+ case 'BrtWsFmtInfoEx14': break; // TODO
1585
+ case 'BrtWsFmtInfo': break; // TODO
1586
+ case 'BrtBeginColInfos': break; // TODO
1587
+ case 'BrtColInfo': break; // TODO
1588
+ case 'BrtEndColInfos': break; // TODO
1589
+ case 'BrtBeginSheetData': break; // TODO
1590
+ case 'BrtEndSheetData': break; // TODO
1591
+ case 'BrtSheetProtection': break; // TODO
1592
+ case 'BrtPrintOptions': break; // TODO
1593
+ case 'BrtMargins': break; // TODO
1594
+ case 'BrtPageSetup': break; // TODO
1595
+ case 'BrtFRTBegin': pass = true; break;
1596
+ case 'BrtFRTEnd': pass = false; break;
1597
+ case 'BrtEndSheet': break; // TODO
1598
+ case 'BrtBeginMergeCells': break; // TODO
1599
+ case 'BrtMergeCell': break; // TODO
1600
+ case 'BrtEndMergeCells': break; // TODO
1601
+ case 'BrtLegacyDrawing': break; // TODO
1602
+ //default: if(!pass) throw new Error("Unexpected record " + R.n);
1603
+ }
1604
+ }, opts);
1605
+ s["!ref"] = encode_range(ref);
1606
+ if(opts.sheetRows) {
1607
+ var tmpref = decode_range(s["!ref"]);
1608
+ if(opts.sheetRows < +tmpref.e.r) {
1609
+ tmpref.e.r = opts.sheetRows - 1;
1610
+ if(tmpref.e.r > refguess.e.r) tmpref.e.r = refguess.e.r;
1611
+ if(tmpref.e.r < tmpref.s.r) tmpref.s.r = tmpref.e.r;
1612
+ if(tmpref.e.c > refguess.e.c) tmpref.e.c = refguess.e.c;
1613
+ if(tmpref.e.c < tmpref.s.c) tmpref.s.c = tmpref.e.c;
1614
+ s["!fullref"] = s["!ref"];
1615
+ s["!ref"] = encode_range(tmpref);
1616
+ }
1617
+ }
1618
+ return s;
1619
+ };
1620
+
1621
+ /* 18.2.28 (CT_WorkbookProtection) Defaults */
1622
+ var WBPropsDef = {
1623
+ allowRefreshQuery: '0',
1624
+ autoCompressPictures: '1',
1625
+ backupFile: '0',
1626
+ checkCompatibility: '0',
1627
+ codeName: '',
1628
+ date1904: '0',
1629
+ dateCompatibility: '1',
1630
+ //defaultThemeVersion: '0',
1631
+ filterPrivacy: '0',
1632
+ hidePivotFieldList: '0',
1633
+ promptedSolutions: '0',
1634
+ publishItems: '0',
1635
+ refreshAllConnections: false,
1636
+ saveExternalLinkValues: '1',
1637
+ showBorderUnselectedTables: '1',
1638
+ showInkAnnotation: '1',
1639
+ showObjects: 'all',
1640
+ showPivotChartFilter: '0'
1641
+ //updateLinks: 'userSet'
1642
+ };
1643
+
1644
+ /* 18.2.30 (CT_BookView) Defaults */
1645
+ var WBViewDef = {
1646
+ activeTab: '0',
1647
+ autoFilterDateGrouping: '1',
1648
+ firstSheet: '0',
1649
+ minimized: '0',
1650
+ showHorizontalScroll: '1',
1651
+ showSheetTabs: '1',
1652
+ showVerticalScroll: '1',
1653
+ tabRatio: '600',
1654
+ visibility: 'visible'
1655
+ //window{Height,Width}, {x,y}Window
1656
+ };
1657
+
1658
+ /* 18.2.19 (CT_Sheet) Defaults */
1659
+ var SheetDef = {
1660
+ state: 'visible'
1661
+ };
1662
+
1663
+ /* 18.2.2 (CT_CalcPr) Defaults */
1664
+ var CalcPrDef = {
1665
+ calcCompleted: 'true',
1666
+ calcMode: 'auto',
1667
+ calcOnSave: 'true',
1668
+ concurrentCalc: 'true',
1669
+ fullCalcOnLoad: 'false',
1670
+ fullPrecision: 'true',
1671
+ iterate: 'false',
1672
+ iterateCount: '100',
1673
+ iterateDelta: '0.001',
1674
+ refMode: 'A1'
1675
+ };
1676
+
1677
+ /* 18.2.3 (CT_CustomWorkbookView) Defaults */
1678
+ var CustomWBViewDef = {
1679
+ autoUpdate: 'false',
1680
+ changesSavedWin: 'false',
1681
+ includeHiddenRowCol: 'true',
1682
+ includePrintSettings: 'true',
1683
+ maximized: 'false',
1684
+ minimized: 'false',
1685
+ onlySync: 'false',
1686
+ personalView: 'false',
1687
+ showComments: 'commIndicator',
1688
+ showFormulaBar: 'true',
1689
+ showHorizontalScroll: 'true',
1690
+ showObjects: 'all',
1691
+ showSheetTabs: 'true',
1692
+ showStatusbar: 'true',
1693
+ showVerticalScroll: 'true',
1694
+ tabRatio: '600',
1695
+ xWindow: '0',
1696
+ yWindow: '0'
1697
+ };
1698
+ var XMLNS_WB = [
1699
+ 'http://schemas.openxmlformats.org/spreadsheetml/2006/main',
1700
+ 'http://schemas.microsoft.com/office/excel/2006/main',
1701
+ 'http://schemas.microsoft.com/office/excel/2006/2'
1702
+ ];
1703
+
845
1704
  /* 18.2 Workbook */
846
- function parseWB(data) {
1705
+ function parse_wb_xml(data) {
847
1706
  var wb = { AppVersion:{}, WBProps:{}, WBView:[], Sheets:[], CalcPr:{}, xmlns: "" };
848
1707
  var pass = false;
849
1708
  data.match(/<[^>]*>/g).forEach(function(x) {
@@ -944,7 +1803,7 @@ function parseWB(data) {
944
1803
  case '</mc:AlternateContent>': pass=false; break;
945
1804
  }
946
1805
  });
947
- if(wb.xmlns !== XMLNS_WB) throw new Error("Unknown Namespace: " + wb.xmlns);
1806
+ if(XMLNS_WB.indexOf(wb.xmlns) === -1) throw new Error("Unknown Namespace: " + wb.xmlns);
948
1807
 
949
1808
  var z;
950
1809
  /* defaults */
@@ -959,105 +1818,988 @@ function parseWB(data) {
959
1818
  return wb;
960
1819
  }
961
1820
 
962
- /* 18.8.31 numFmts CT_NumFmts */
963
- function parseNumFmts(t) {
964
- styles.NumberFmt = [];
965
- for(var y in SSF._table) styles.NumberFmt[y] = SSF._table[y];
966
- t[0].match(/<[^>]*>/g).forEach(function(x) {
967
- var y = parsexmltag(x);
968
- switch(y[0]) {
969
- case '<numFmts': case '</numFmts>': case '<numFmts/>': break;
970
- case '<numFmt': {
971
- var f=unescapexml(y.formatCode), i=parseInt(y.numFmtId,10);
972
- styles.NumberFmt[i] = f; SSF.load(f,i);
973
- } break;
974
- default: throw 'unrecognized ' + y[0] + ' in numFmts';
1821
+ /* [MS-XLSB] 2.4.301 BrtBundleSh */
1822
+ var parse_BrtBundleSh = function(data, length) {
1823
+ var z = {};
1824
+ z.hsState = data.read_shift(4); //ST_SheetState
1825
+ z.iTabID = data.read_shift(4);
1826
+ z.strRelID = parse_RelID(data,length-8);
1827
+ z.name = parse_XLWideString(data);
1828
+ return z;
1829
+ };
1830
+
1831
+ /* [MS-XLSB] 2.1.7.60 Workbook */
1832
+ var parse_wb_bin = function(data) {
1833
+ var wb = { AppVersion:{}, WBProps:{}, WBView:[], Sheets:[], CalcPr:{}, xmlns: "" };
1834
+ var pass = false, z;
1835
+
1836
+ recordhopper(data, function(val, R) {
1837
+ switch(R.n) {
1838
+ case 'BrtBundleSh': wb.Sheets.push(val); break;
1839
+
1840
+ case 'BrtBeginBook': break;
1841
+ case 'BrtFileVersion': break;
1842
+ case 'BrtWbProp': break;
1843
+ case 'BrtACBegin': break;
1844
+ case 'BrtAbsPath15': break;
1845
+ case 'BrtACEnd': break;
1846
+ /*case 'BrtBookProtectionIso': break;*/
1847
+ case 'BrtBookProtection': break;
1848
+ case 'BrtBeginBookViews': break;
1849
+ case 'BrtBookView': break;
1850
+ case 'BrtEndBookViews': break;
1851
+ case 'BrtBeginBundleShs': break;
1852
+ case 'BrtEndBundleShs': break;
1853
+ case 'BrtBeginFnGroup': break;
1854
+ case 'BrtEndFnGroup': break;
1855
+ case 'BrtBeginExternals': break;
1856
+ case 'BrtSupSelf': break;
1857
+ case 'BrtSupBookSrc': break;
1858
+ case 'BrtExternSheet': break;
1859
+ case 'BrtEndExternals': break;
1860
+ case 'BrtName': break;
1861
+ case 'BrtCalcProp': break;
1862
+ case 'BrtUserBookView': break;
1863
+ case 'BrtBeginPivotCacheIDs': break;
1864
+ case 'BrtBeginPivotCacheID': break;
1865
+ case 'BrtEndPivotCacheID': break;
1866
+ case 'BrtEndPivotCacheIDs': break;
1867
+ case 'BrtWebOpt': break;
1868
+ case 'BrtFileRecover': break;
1869
+ /*case 'BrtBeginWebPubItems': break;
1870
+ case 'BrtBeginWebPubItem': break;
1871
+ case 'BrtEndWebPubItem': break;
1872
+ case 'BrtEndWebPubItems': break;*/
1873
+ case 'BrtFRTBegin': pass = true; break;
1874
+ case 'BrtFRTEnd': pass = false; break;
1875
+ case 'BrtEndBook': break;
1876
+ //default: if(!pass) throw new Error("Unexpected record " + R.n);
975
1877
  }
976
1878
  });
977
- }
978
1879
 
979
- /* 18.8.10 cellXfs CT_CellXfs */
980
- function parseCXfs(t) {
981
- styles.CellXf = [];
982
- t[0].match(/<[^>]*>/g).forEach(function(x) {
983
- var y = parsexmltag(x);
984
- switch(y[0]) {
985
- case '<cellXfs': case '<cellXfs/>': case '</cellXfs>': break;
1880
+ /* defaults */
1881
+ for(z in WBPropsDef) if(typeof wb.WBProps[z] === 'undefined') wb.WBProps[z] = WBPropsDef[z];
1882
+ for(z in CalcPrDef) if(typeof wb.CalcPr[z] === 'undefined') wb.CalcPr[z] = CalcPrDef[z];
986
1883
 
987
- /* 18.8.45 xf CT_Xf */
988
- case '<xf': if(y.numFmtId) y.numFmtId = parseInt(y.numFmtId, 10);
989
- styles.CellXf.push(y); break;
990
- case '</xf>': break;
1884
+ wb.WBView.forEach(function(w){for(var z in WBViewDef) if(typeof w[z] === 'undefined') w[z]=WBViewDef[z]; });
1885
+ wb.Sheets.forEach(function(w){for(var z in SheetDef) if(typeof w[z] === 'undefined') w[z]=SheetDef[z]; });
991
1886
 
992
- /* 18.8.1 alignment CT_CellAlignment */
993
- case '<alignment': break;
1887
+ _ssfopts.date1904 = parsexmlbool(wb.WBProps.date1904, 'date1904');
994
1888
 
995
- /* 18.8.33 protection CT_CellProtection */
996
- case '<protection': case '</protection>': case '<protection/>': break;
1889
+ return wb;
1890
+ };
1891
+ function parse_wb(data, name, opts) {
1892
+ return name.substr(-4)===".bin" ? parse_wb_bin(data, opts) : parse_wb_xml(data, opts);
1893
+ }
997
1894
 
998
- case '<extLst': case '</extLst>': break;
999
- case '<ext': break;
1000
- default: throw 'unrecognized ' + y[0] + ' in cellXfs';
1001
- }
1002
- });
1895
+ function parse_ws(data, name, opts) {
1896
+ return name.substr(-4)===".bin" ? parse_ws_bin(data, opts) : parse_ws_xml(data, opts);
1003
1897
  }
1004
1898
 
1005
- /* 18.8 Styles CT_Stylesheet*/
1006
- function parseStyles(data) {
1007
- /* 18.8.39 styleSheet CT_Stylesheet */
1008
- var t;
1899
+ function parse_sty(data, name, opts) {
1900
+ return name.substr(-4)===".bin" ? parse_sty_bin(data, opts) : parse_sty_xml(data, opts);
1901
+ }
1009
1902
 
1010
- /* numFmts CT_NumFmts ? */
1011
- if((t=data.match(/<numFmts([^>]*)>.*<\/numFmts>/))) parseNumFmts(t);
1903
+ function parse_sst(data, name, opts) {
1904
+ return name.substr(-4)===".bin" ? parse_sst_bin(data, opts) : parse_sst_xml(data, opts);
1905
+ }
1906
+ /* [MS-XLSB] 2.3 Record Enumeration */
1907
+ var RecordEnum = {
1908
+ 0x0000: { n:"BrtRowHdr", f:parse_BrtRowHdr },
1909
+ 0x0001: { n:"BrtCellBlank", f:parse_BrtCellBlank },
1910
+ 0x0002: { n:"BrtCellRk", f:parse_BrtCellRk },
1911
+ 0x0003: { n:"BrtCellError", f:parse_BrtCellError },
1912
+ 0x0004: { n:"BrtCellBool", f:parse_BrtCellBool },
1913
+ 0x0005: { n:"BrtCellReal", f:parse_BrtCellReal },
1914
+ 0x0006: { n:"BrtCellSt", f:parse_BrtCellSt },
1915
+ 0x0007: { n:"BrtCellIsst", f:parse_BrtCellIsst },
1916
+ 0x0008: { n:"BrtFmlaString", f:parse_BrtFmlaString },
1917
+ 0x0009: { n:"BrtFmlaNum", f:parse_BrtFmlaNum },
1918
+ 0x000A: { n:"BrtFmlaBool", f:parse_BrtFmlaBool },
1919
+ 0x000B: { n:"BrtFmlaError", f:parse_BrtFmlaError },
1920
+ 0x0013: { n:"BrtSSTItem", f:parse_RichStr },
1921
+ 0x0014: { n:"BrtPCDIMissing", f:parsenoop },
1922
+ 0x0015: { n:"BrtPCDINumber", f:parsenoop },
1923
+ 0x0016: { n:"BrtPCDIBoolean", f:parsenoop },
1924
+ 0x0017: { n:"BrtPCDIError", f:parsenoop },
1925
+ 0x0018: { n:"BrtPCDIString", f:parsenoop },
1926
+ 0x0019: { n:"BrtPCDIDatetime", f:parsenoop },
1927
+ 0x001A: { n:"BrtPCDIIndex", f:parsenoop },
1928
+ 0x001B: { n:"BrtPCDIAMissing", f:parsenoop },
1929
+ 0x001C: { n:"BrtPCDIANumber", f:parsenoop },
1930
+ 0x001D: { n:"BrtPCDIABoolean", f:parsenoop },
1931
+ 0x001E: { n:"BrtPCDIAError", f:parsenoop },
1932
+ 0x001F: { n:"BrtPCDIAString", f:parsenoop },
1933
+ 0x0020: { n:"BrtPCDIADatetime", f:parsenoop },
1934
+ 0x0021: { n:"BrtPCRRecord", f:parsenoop },
1935
+ 0x0022: { n:"BrtPCRRecordDt", f:parsenoop },
1936
+ 0x0023: { n:"BrtFRTBegin", f:parsenoop },
1937
+ 0x0024: { n:"BrtFRTEnd", f:parsenoop },
1938
+ 0x0025: { n:"BrtACBegin", f:parsenoop },
1939
+ 0x0026: { n:"BrtACEnd", f:parsenoop },
1940
+ 0x0027: { n:"BrtName", f:parsenoop },
1941
+ 0x0028: { n:"BrtIndexRowBlock", f:parsenoop },
1942
+ 0x002A: { n:"BrtIndexBlock", f:parsenoop },
1943
+ 0x002B: { n:"BrtFont", f:parsenoop },
1944
+ 0x002C: { n:"BrtFmt", f:parse_BrtFmt },
1945
+ 0x002D: { n:"BrtFill", f:parsenoop },
1946
+ 0x002E: { n:"BrtBorder", f:parsenoop },
1947
+ 0x002F: { n:"BrtXF", f:parse_BrtXF },
1948
+ 0x0030: { n:"BrtStyle", f:parsenoop },
1949
+ 0x0031: { n:"BrtCellMeta", f:parsenoop },
1950
+ 0x0032: { n:"BrtValueMeta", f:parsenoop },
1951
+ 0x0033: { n:"BrtMdb", f:parsenoop },
1952
+ 0x0034: { n:"BrtBeginFmd", f:parsenoop },
1953
+ 0x0035: { n:"BrtEndFmd", f:parsenoop },
1954
+ 0x0036: { n:"BrtBeginMdx", f:parsenoop },
1955
+ 0x0037: { n:"BrtEndMdx", f:parsenoop },
1956
+ 0x0038: { n:"BrtBeginMdxTuple", f:parsenoop },
1957
+ 0x0039: { n:"BrtEndMdxTuple", f:parsenoop },
1958
+ 0x003A: { n:"BrtMdxMbrIstr", f:parsenoop },
1959
+ 0x003B: { n:"BrtStr", f:parsenoop },
1960
+ 0x003C: { n:"BrtColInfo", f:parsenoop },
1961
+ 0x003E: { n:"BrtCellRString", f:parsenoop },
1962
+ 0x0040: { n:"BrtDVal", f:parsenoop },
1963
+ 0x0041: { n:"BrtSxvcellNum", f:parsenoop },
1964
+ 0x0042: { n:"BrtSxvcellStr", f:parsenoop },
1965
+ 0x0043: { n:"BrtSxvcellBool", f:parsenoop },
1966
+ 0x0044: { n:"BrtSxvcellErr", f:parsenoop },
1967
+ 0x0045: { n:"BrtSxvcellDate", f:parsenoop },
1968
+ 0x0046: { n:"BrtSxvcellNil", f:parsenoop },
1969
+ 0x0080: { n:"BrtFileVersion", f:parsenoop },
1970
+ 0x0081: { n:"BrtBeginSheet", f:parsenoop },
1971
+ 0x0082: { n:"BrtEndSheet", f:parsenoop },
1972
+ 0x0083: { n:"BrtBeginBook", f:parsenoop },
1973
+ 0x0084: { n:"BrtEndBook", f:parsenoop },
1974
+ 0x0085: { n:"BrtBeginWsViews", f:parsenoop },
1975
+ 0x0086: { n:"BrtEndWsViews", f:parsenoop },
1976
+ 0x0087: { n:"BrtBeginBookViews", f:parsenoop },
1977
+ 0x0088: { n:"BrtEndBookViews", f:parsenoop },
1978
+ 0x0089: { n:"BrtBeginWsView", f:parsenoop },
1979
+ 0x008A: { n:"BrtEndWsView", f:parsenoop },
1980
+ 0x008B: { n:"BrtBeginCsViews", f:parsenoop },
1981
+ 0x008C: { n:"BrtEndCsViews", f:parsenoop },
1982
+ 0x008D: { n:"BrtBeginCsView", f:parsenoop },
1983
+ 0x008E: { n:"BrtEndCsView", f:parsenoop },
1984
+ 0x008F: { n:"BrtBeginBundleShs", f:parsenoop },
1985
+ 0x0090: { n:"BrtEndBundleShs", f:parsenoop },
1986
+ 0x0091: { n:"BrtBeginSheetData", f:parsenoop },
1987
+ 0x0092: { n:"BrtEndSheetData", f:parsenoop },
1988
+ 0x0093: { n:"BrtWsProp", f:parse_BrtWsProp },
1989
+ 0x0094: { n:"BrtWsDim", f:parse_BrtWsDim },
1990
+ 0x0097: { n:"BrtPane", f:parsenoop },
1991
+ 0x0098: { n:"BrtSel", f:parsenoop },
1992
+ 0x0099: { n:"BrtWbProp", f:parsenoop },
1993
+ 0x009A: { n:"BrtWbFactoid", f:parsenoop },
1994
+ 0x009B: { n:"BrtFileRecover", f:parsenoop },
1995
+ 0x009C: { n:"BrtBundleSh", f:parse_BrtBundleSh },
1996
+ 0x009D: { n:"BrtCalcProp", f:parsenoop },
1997
+ 0x009E: { n:"BrtBookView", f:parsenoop },
1998
+ 0x009F: { n:"BrtBeginSst", f:parse_BrtBeginSst },
1999
+ 0x00A0: { n:"BrtEndSst", f:parsenoop },
2000
+ 0x00A1: { n:"BrtBeginAFilter", f:parsenoop },
2001
+ 0x00A2: { n:"BrtEndAFilter", f:parsenoop },
2002
+ 0x00A3: { n:"BrtBeginFilterColumn", f:parsenoop },
2003
+ 0x00A4: { n:"BrtEndFilterColumn", f:parsenoop },
2004
+ 0x00A5: { n:"BrtBeginFilters", f:parsenoop },
2005
+ 0x00A6: { n:"BrtEndFilters", f:parsenoop },
2006
+ 0x00A7: { n:"BrtFilter", f:parsenoop },
2007
+ 0x00A8: { n:"BrtColorFilter", f:parsenoop },
2008
+ 0x00A9: { n:"BrtIconFilter", f:parsenoop },
2009
+ 0x00AA: { n:"BrtTop10Filter", f:parsenoop },
2010
+ 0x00AB: { n:"BrtDynamicFilter", f:parsenoop },
2011
+ 0x00AC: { n:"BrtBeginCustomFilters", f:parsenoop },
2012
+ 0x00AD: { n:"BrtEndCustomFilters", f:parsenoop },
2013
+ 0x00AE: { n:"BrtCustomFilter", f:parsenoop },
2014
+ 0x00AF: { n:"BrtAFilterDateGroupItem", f:parsenoop },
2015
+ 0x00B0: { n:"BrtMergeCell", f:parsenoop },
2016
+ 0x00B1: { n:"BrtBeginMergeCells", f:parsenoop },
2017
+ 0x00B2: { n:"BrtEndMergeCells", f:parsenoop },
2018
+ 0x00B3: { n:"BrtBeginPivotCacheDef", f:parsenoop },
2019
+ 0x00B4: { n:"BrtEndPivotCacheDef", f:parsenoop },
2020
+ 0x00B5: { n:"BrtBeginPCDFields", f:parsenoop },
2021
+ 0x00B6: { n:"BrtEndPCDFields", f:parsenoop },
2022
+ 0x00B7: { n:"BrtBeginPCDField", f:parsenoop },
2023
+ 0x00B8: { n:"BrtEndPCDField", f:parsenoop },
2024
+ 0x00B9: { n:"BrtBeginPCDSource", f:parsenoop },
2025
+ 0x00BA: { n:"BrtEndPCDSource", f:parsenoop },
2026
+ 0x00BB: { n:"BrtBeginPCDSRange", f:parsenoop },
2027
+ 0x00BC: { n:"BrtEndPCDSRange", f:parsenoop },
2028
+ 0x00BD: { n:"BrtBeginPCDFAtbl", f:parsenoop },
2029
+ 0x00BE: { n:"BrtEndPCDFAtbl", f:parsenoop },
2030
+ 0x00BF: { n:"BrtBeginPCDIRun", f:parsenoop },
2031
+ 0x00C0: { n:"BrtEndPCDIRun", f:parsenoop },
2032
+ 0x00C1: { n:"BrtBeginPivotCacheRecords", f:parsenoop },
2033
+ 0x00C2: { n:"BrtEndPivotCacheRecords", f:parsenoop },
2034
+ 0x00C3: { n:"BrtBeginPCDHierarchies", f:parsenoop },
2035
+ 0x00C4: { n:"BrtEndPCDHierarchies", f:parsenoop },
2036
+ 0x00C5: { n:"BrtBeginPCDHierarchy", f:parsenoop },
2037
+ 0x00C6: { n:"BrtEndPCDHierarchy", f:parsenoop },
2038
+ 0x00C7: { n:"BrtBeginPCDHFieldsUsage", f:parsenoop },
2039
+ 0x00C8: { n:"BrtEndPCDHFieldsUsage", f:parsenoop },
2040
+ 0x00C9: { n:"BrtBeginExtConnection", f:parsenoop },
2041
+ 0x00CA: { n:"BrtEndExtConnection", f:parsenoop },
2042
+ 0x00CB: { n:"BrtBeginECDbProps", f:parsenoop },
2043
+ 0x00CC: { n:"BrtEndECDbProps", f:parsenoop },
2044
+ 0x00CD: { n:"BrtBeginECOlapProps", f:parsenoop },
2045
+ 0x00CE: { n:"BrtEndECOlapProps", f:parsenoop },
2046
+ 0x00CF: { n:"BrtBeginPCDSConsol", f:parsenoop },
2047
+ 0x00D0: { n:"BrtEndPCDSConsol", f:parsenoop },
2048
+ 0x00D1: { n:"BrtBeginPCDSCPages", f:parsenoop },
2049
+ 0x00D2: { n:"BrtEndPCDSCPages", f:parsenoop },
2050
+ 0x00D3: { n:"BrtBeginPCDSCPage", f:parsenoop },
2051
+ 0x00D4: { n:"BrtEndPCDSCPage", f:parsenoop },
2052
+ 0x00D5: { n:"BrtBeginPCDSCPItem", f:parsenoop },
2053
+ 0x00D6: { n:"BrtEndPCDSCPItem", f:parsenoop },
2054
+ 0x00D7: { n:"BrtBeginPCDSCSets", f:parsenoop },
2055
+ 0x00D8: { n:"BrtEndPCDSCSets", f:parsenoop },
2056
+ 0x00D9: { n:"BrtBeginPCDSCSet", f:parsenoop },
2057
+ 0x00DA: { n:"BrtEndPCDSCSet", f:parsenoop },
2058
+ 0x00DB: { n:"BrtBeginPCDFGroup", f:parsenoop },
2059
+ 0x00DC: { n:"BrtEndPCDFGroup", f:parsenoop },
2060
+ 0x00DD: { n:"BrtBeginPCDFGItems", f:parsenoop },
2061
+ 0x00DE: { n:"BrtEndPCDFGItems", f:parsenoop },
2062
+ 0x00DF: { n:"BrtBeginPCDFGRange", f:parsenoop },
2063
+ 0x00E0: { n:"BrtEndPCDFGRange", f:parsenoop },
2064
+ 0x00E1: { n:"BrtBeginPCDFGDiscrete", f:parsenoop },
2065
+ 0x00E2: { n:"BrtEndPCDFGDiscrete", f:parsenoop },
2066
+ 0x00E3: { n:"BrtBeginPCDSDTupleCache", f:parsenoop },
2067
+ 0x00E4: { n:"BrtEndPCDSDTupleCache", f:parsenoop },
2068
+ 0x00E5: { n:"BrtBeginPCDSDTCEntries", f:parsenoop },
2069
+ 0x00E6: { n:"BrtEndPCDSDTCEntries", f:parsenoop },
2070
+ 0x00E7: { n:"BrtBeginPCDSDTCEMembers", f:parsenoop },
2071
+ 0x00E8: { n:"BrtEndPCDSDTCEMembers", f:parsenoop },
2072
+ 0x00E9: { n:"BrtBeginPCDSDTCEMember", f:parsenoop },
2073
+ 0x00EA: { n:"BrtEndPCDSDTCEMember", f:parsenoop },
2074
+ 0x00EB: { n:"BrtBeginPCDSDTCQueries", f:parsenoop },
2075
+ 0x00EC: { n:"BrtEndPCDSDTCQueries", f:parsenoop },
2076
+ 0x00ED: { n:"BrtBeginPCDSDTCQuery", f:parsenoop },
2077
+ 0x00EE: { n:"BrtEndPCDSDTCQuery", f:parsenoop },
2078
+ 0x00EF: { n:"BrtBeginPCDSDTCSets", f:parsenoop },
2079
+ 0x00F0: { n:"BrtEndPCDSDTCSets", f:parsenoop },
2080
+ 0x00F1: { n:"BrtBeginPCDSDTCSet", f:parsenoop },
2081
+ 0x00F2: { n:"BrtEndPCDSDTCSet", f:parsenoop },
2082
+ 0x00F3: { n:"BrtBeginPCDCalcItems", f:parsenoop },
2083
+ 0x00F4: { n:"BrtEndPCDCalcItems", f:parsenoop },
2084
+ 0x00F5: { n:"BrtBeginPCDCalcItem", f:parsenoop },
2085
+ 0x00F6: { n:"BrtEndPCDCalcItem", f:parsenoop },
2086
+ 0x00F7: { n:"BrtBeginPRule", f:parsenoop },
2087
+ 0x00F8: { n:"BrtEndPRule", f:parsenoop },
2088
+ 0x00F9: { n:"BrtBeginPRFilters", f:parsenoop },
2089
+ 0x00FA: { n:"BrtEndPRFilters", f:parsenoop },
2090
+ 0x00FB: { n:"BrtBeginPRFilter", f:parsenoop },
2091
+ 0x00FC: { n:"BrtEndPRFilter", f:parsenoop },
2092
+ 0x00FD: { n:"BrtBeginPNames", f:parsenoop },
2093
+ 0x00FE: { n:"BrtEndPNames", f:parsenoop },
2094
+ 0x00FF: { n:"BrtBeginPName", f:parsenoop },
2095
+ 0x0100: { n:"BrtEndPName", f:parsenoop },
2096
+ 0x0101: { n:"BrtBeginPNPairs", f:parsenoop },
2097
+ 0x0102: { n:"BrtEndPNPairs", f:parsenoop },
2098
+ 0x0103: { n:"BrtBeginPNPair", f:parsenoop },
2099
+ 0x0104: { n:"BrtEndPNPair", f:parsenoop },
2100
+ 0x0105: { n:"BrtBeginECWebProps", f:parsenoop },
2101
+ 0x0106: { n:"BrtEndECWebProps", f:parsenoop },
2102
+ 0x0107: { n:"BrtBeginEcWpTables", f:parsenoop },
2103
+ 0x0108: { n:"BrtEndECWPTables", f:parsenoop },
2104
+ 0x0109: { n:"BrtBeginECParams", f:parsenoop },
2105
+ 0x010A: { n:"BrtEndECParams", f:parsenoop },
2106
+ 0x010B: { n:"BrtBeginECParam", f:parsenoop },
2107
+ 0x010C: { n:"BrtEndECParam", f:parsenoop },
2108
+ 0x010D: { n:"BrtBeginPCDKPIs", f:parsenoop },
2109
+ 0x010E: { n:"BrtEndPCDKPIs", f:parsenoop },
2110
+ 0x010F: { n:"BrtBeginPCDKPI", f:parsenoop },
2111
+ 0x0110: { n:"BrtEndPCDKPI", f:parsenoop },
2112
+ 0x0111: { n:"BrtBeginDims", f:parsenoop },
2113
+ 0x0112: { n:"BrtEndDims", f:parsenoop },
2114
+ 0x0113: { n:"BrtBeginDim", f:parsenoop },
2115
+ 0x0114: { n:"BrtEndDim", f:parsenoop },
2116
+ 0x0115: { n:"BrtIndexPartEnd", f:parsenoop },
2117
+ 0x0116: { n:"BrtBeginStyleSheet", f:parsenoop },
2118
+ 0x0117: { n:"BrtEndStyleSheet", f:parsenoop },
2119
+ 0x0118: { n:"BrtBeginSXView", f:parsenoop },
2120
+ 0x0119: { n:"BrtEndSXVI", f:parsenoop },
2121
+ 0x011A: { n:"BrtBeginSXVI", f:parsenoop },
2122
+ 0x011B: { n:"BrtBeginSXVIs", f:parsenoop },
2123
+ 0x011C: { n:"BrtEndSXVIs", f:parsenoop },
2124
+ 0x011D: { n:"BrtBeginSXVD", f:parsenoop },
2125
+ 0x011E: { n:"BrtEndSXVD", f:parsenoop },
2126
+ 0x011F: { n:"BrtBeginSXVDs", f:parsenoop },
2127
+ 0x0120: { n:"BrtEndSXVDs", f:parsenoop },
2128
+ 0x0121: { n:"BrtBeginSXPI", f:parsenoop },
2129
+ 0x0122: { n:"BrtEndSXPI", f:parsenoop },
2130
+ 0x0123: { n:"BrtBeginSXPIs", f:parsenoop },
2131
+ 0x0124: { n:"BrtEndSXPIs", f:parsenoop },
2132
+ 0x0125: { n:"BrtBeginSXDI", f:parsenoop },
2133
+ 0x0126: { n:"BrtEndSXDI", f:parsenoop },
2134
+ 0x0127: { n:"BrtBeginSXDIs", f:parsenoop },
2135
+ 0x0128: { n:"BrtEndSXDIs", f:parsenoop },
2136
+ 0x0129: { n:"BrtBeginSXLI", f:parsenoop },
2137
+ 0x012A: { n:"BrtEndSXLI", f:parsenoop },
2138
+ 0x012B: { n:"BrtBeginSXLIRws", f:parsenoop },
2139
+ 0x012C: { n:"BrtEndSXLIRws", f:parsenoop },
2140
+ 0x012D: { n:"BrtBeginSXLICols", f:parsenoop },
2141
+ 0x012E: { n:"BrtEndSXLICols", f:parsenoop },
2142
+ 0x012F: { n:"BrtBeginSXFormat", f:parsenoop },
2143
+ 0x0130: { n:"BrtEndSXFormat", f:parsenoop },
2144
+ 0x0131: { n:"BrtBeginSXFormats", f:parsenoop },
2145
+ 0x0132: { n:"BrtEndSxFormats", f:parsenoop },
2146
+ 0x0133: { n:"BrtBeginSxSelect", f:parsenoop },
2147
+ 0x0134: { n:"BrtEndSxSelect", f:parsenoop },
2148
+ 0x0135: { n:"BrtBeginISXVDRws", f:parsenoop },
2149
+ 0x0136: { n:"BrtEndISXVDRws", f:parsenoop },
2150
+ 0x0137: { n:"BrtBeginISXVDCols", f:parsenoop },
2151
+ 0x0138: { n:"BrtEndISXVDCols", f:parsenoop },
2152
+ 0x0139: { n:"BrtEndSXLocation", f:parsenoop },
2153
+ 0x013A: { n:"BrtBeginSXLocation", f:parsenoop },
2154
+ 0x013B: { n:"BrtEndSXView", f:parsenoop },
2155
+ 0x013C: { n:"BrtBeginSXTHs", f:parsenoop },
2156
+ 0x013D: { n:"BrtEndSXTHs", f:parsenoop },
2157
+ 0x013E: { n:"BrtBeginSXTH", f:parsenoop },
2158
+ 0x013F: { n:"BrtEndSXTH", f:parsenoop },
2159
+ 0x0140: { n:"BrtBeginISXTHRws", f:parsenoop },
2160
+ 0x0141: { n:"BrtEndISXTHRws", f:parsenoop },
2161
+ 0x0142: { n:"BrtBeginISXTHCols", f:parsenoop },
2162
+ 0x0143: { n:"BrtEndISXTHCols", f:parsenoop },
2163
+ 0x0144: { n:"BrtBeginSXTDMPS", f:parsenoop },
2164
+ 0x0145: { n:"BrtEndSXTDMPs", f:parsenoop },
2165
+ 0x0146: { n:"BrtBeginSXTDMP", f:parsenoop },
2166
+ 0x0147: { n:"BrtEndSXTDMP", f:parsenoop },
2167
+ 0x0148: { n:"BrtBeginSXTHItems", f:parsenoop },
2168
+ 0x0149: { n:"BrtEndSXTHItems", f:parsenoop },
2169
+ 0x014A: { n:"BrtBeginSXTHItem", f:parsenoop },
2170
+ 0x014B: { n:"BrtEndSXTHItem", f:parsenoop },
2171
+ 0x014C: { n:"BrtBeginMetadata", f:parsenoop },
2172
+ 0x014D: { n:"BrtEndMetadata", f:parsenoop },
2173
+ 0x014E: { n:"BrtBeginEsmdtinfo", f:parsenoop },
2174
+ 0x014F: { n:"BrtMdtinfo", f:parsenoop },
2175
+ 0x0150: { n:"BrtEndEsmdtinfo", f:parsenoop },
2176
+ 0x0151: { n:"BrtBeginEsmdb", f:parsenoop },
2177
+ 0x0152: { n:"BrtEndEsmdb", f:parsenoop },
2178
+ 0x0153: { n:"BrtBeginEsfmd", f:parsenoop },
2179
+ 0x0154: { n:"BrtEndEsfmd", f:parsenoop },
2180
+ 0x0155: { n:"BrtBeginSingleCells", f:parsenoop },
2181
+ 0x0156: { n:"BrtEndSingleCells", f:parsenoop },
2182
+ 0x0157: { n:"BrtBeginList", f:parsenoop },
2183
+ 0x0158: { n:"BrtEndList", f:parsenoop },
2184
+ 0x0159: { n:"BrtBeginListCols", f:parsenoop },
2185
+ 0x015A: { n:"BrtEndListCols", f:parsenoop },
2186
+ 0x015B: { n:"BrtBeginListCol", f:parsenoop },
2187
+ 0x015C: { n:"BrtEndListCol", f:parsenoop },
2188
+ 0x015D: { n:"BrtBeginListXmlCPr", f:parsenoop },
2189
+ 0x015E: { n:"BrtEndListXmlCPr", f:parsenoop },
2190
+ 0x015F: { n:"BrtListCCFmla", f:parsenoop },
2191
+ 0x0160: { n:"BrtListTrFmla", f:parsenoop },
2192
+ 0x0161: { n:"BrtBeginExternals", f:parsenoop },
2193
+ 0x0162: { n:"BrtEndExternals", f:parsenoop },
2194
+ 0x0163: { n:"BrtSupBookSrc", f:parsenoop },
2195
+ 0x0165: { n:"BrtSupSelf", f:parsenoop },
2196
+ 0x0166: { n:"BrtSupSame", f:parsenoop },
2197
+ 0x0167: { n:"BrtSupTabs", f:parsenoop },
2198
+ 0x0168: { n:"BrtBeginSupBook", f:parsenoop },
2199
+ 0x0169: { n:"BrtPlaceholderName", f:parsenoop },
2200
+ 0x016A: { n:"BrtExternSheet", f:parsenoop },
2201
+ 0x016B: { n:"BrtExternTableStart", f:parsenoop },
2202
+ 0x016C: { n:"BrtExternTableEnd", f:parsenoop },
2203
+ 0x016E: { n:"BrtExternRowHdr", f:parsenoop },
2204
+ 0x016F: { n:"BrtExternCellBlank", f:parsenoop },
2205
+ 0x0170: { n:"BrtExternCellReal", f:parsenoop },
2206
+ 0x0171: { n:"BrtExternCellBool", f:parsenoop },
2207
+ 0x0172: { n:"BrtExternCellError", f:parsenoop },
2208
+ 0x0173: { n:"BrtExternCellString", f:parsenoop },
2209
+ 0x0174: { n:"BrtBeginEsmdx", f:parsenoop },
2210
+ 0x0175: { n:"BrtEndEsmdx", f:parsenoop },
2211
+ 0x0176: { n:"BrtBeginMdxSet", f:parsenoop },
2212
+ 0x0177: { n:"BrtEndMdxSet", f:parsenoop },
2213
+ 0x0178: { n:"BrtBeginMdxMbrProp", f:parsenoop },
2214
+ 0x0179: { n:"BrtEndMdxMbrProp", f:parsenoop },
2215
+ 0x017A: { n:"BrtBeginMdxKPI", f:parsenoop },
2216
+ 0x017B: { n:"BrtEndMdxKPI", f:parsenoop },
2217
+ 0x017C: { n:"BrtBeginEsstr", f:parsenoop },
2218
+ 0x017D: { n:"BrtEndEsstr", f:parsenoop },
2219
+ 0x017E: { n:"BrtBeginPRFItem", f:parsenoop },
2220
+ 0x017F: { n:"BrtEndPRFItem", f:parsenoop },
2221
+ 0x0180: { n:"BrtBeginPivotCacheIDs", f:parsenoop },
2222
+ 0x0181: { n:"BrtEndPivotCacheIDs", f:parsenoop },
2223
+ 0x0182: { n:"BrtBeginPivotCacheID", f:parsenoop },
2224
+ 0x0183: { n:"BrtEndPivotCacheID", f:parsenoop },
2225
+ 0x0184: { n:"BrtBeginISXVIs", f:parsenoop },
2226
+ 0x0185: { n:"BrtEndISXVIs", f:parsenoop },
2227
+ 0x0186: { n:"BrtBeginColInfos", f:parsenoop },
2228
+ 0x0187: { n:"BrtEndColInfos", f:parsenoop },
2229
+ 0x0188: { n:"BrtBeginRwBrk", f:parsenoop },
2230
+ 0x0189: { n:"BrtEndRwBrk", f:parsenoop },
2231
+ 0x018A: { n:"BrtBeginColBrk", f:parsenoop },
2232
+ 0x018B: { n:"BrtEndColBrk", f:parsenoop },
2233
+ 0x018C: { n:"BrtBrk", f:parsenoop },
2234
+ 0x018D: { n:"BrtUserBookView", f:parsenoop },
2235
+ 0x018E: { n:"BrtInfo", f:parsenoop },
2236
+ 0x018F: { n:"BrtCUsr", f:parsenoop },
2237
+ 0x0190: { n:"BrtUsr", f:parsenoop },
2238
+ 0x0191: { n:"BrtBeginUsers", f:parsenoop },
2239
+ 0x0193: { n:"BrtEOF", f:parsenoop },
2240
+ 0x0194: { n:"BrtUCR", f:parsenoop },
2241
+ 0x0195: { n:"BrtRRInsDel", f:parsenoop },
2242
+ 0x0196: { n:"BrtRREndInsDel", f:parsenoop },
2243
+ 0x0197: { n:"BrtRRMove", f:parsenoop },
2244
+ 0x0198: { n:"BrtRREndMove", f:parsenoop },
2245
+ 0x0199: { n:"BrtRRChgCell", f:parsenoop },
2246
+ 0x019A: { n:"BrtRREndChgCell", f:parsenoop },
2247
+ 0x019B: { n:"BrtRRHeader", f:parsenoop },
2248
+ 0x019C: { n:"BrtRRUserView", f:parsenoop },
2249
+ 0x019D: { n:"BrtRRRenSheet", f:parsenoop },
2250
+ 0x019E: { n:"BrtRRInsertSh", f:parsenoop },
2251
+ 0x019F: { n:"BrtRRDefName", f:parsenoop },
2252
+ 0x01A0: { n:"BrtRRNote", f:parsenoop },
2253
+ 0x01A1: { n:"BrtRRConflict", f:parsenoop },
2254
+ 0x01A2: { n:"BrtRRTQSIF", f:parsenoop },
2255
+ 0x01A3: { n:"BrtRRFormat", f:parsenoop },
2256
+ 0x01A4: { n:"BrtRREndFormat", f:parsenoop },
2257
+ 0x01A5: { n:"BrtRRAutoFmt", f:parsenoop },
2258
+ 0x01A6: { n:"BrtBeginUserShViews", f:parsenoop },
2259
+ 0x01A7: { n:"BrtBeginUserShView", f:parsenoop },
2260
+ 0x01A8: { n:"BrtEndUserShView", f:parsenoop },
2261
+ 0x01A9: { n:"BrtEndUserShViews", f:parsenoop },
2262
+ 0x01AA: { n:"BrtArrFmla", f:parsenoop },
2263
+ 0x01AB: { n:"BrtShrFmla", f:parsenoop },
2264
+ 0x01AC: { n:"BrtTable", f:parsenoop },
2265
+ 0x01AD: { n:"BrtBeginExtConnections", f:parsenoop },
2266
+ 0x01AE: { n:"BrtEndExtConnections", f:parsenoop },
2267
+ 0x01AF: { n:"BrtBeginPCDCalcMems", f:parsenoop },
2268
+ 0x01B0: { n:"BrtEndPCDCalcMems", f:parsenoop },
2269
+ 0x01B1: { n:"BrtBeginPCDCalcMem", f:parsenoop },
2270
+ 0x01B2: { n:"BrtEndPCDCalcMem", f:parsenoop },
2271
+ 0x01B3: { n:"BrtBeginPCDHGLevels", f:parsenoop },
2272
+ 0x01B4: { n:"BrtEndPCDHGLevels", f:parsenoop },
2273
+ 0x01B5: { n:"BrtBeginPCDHGLevel", f:parsenoop },
2274
+ 0x01B6: { n:"BrtEndPCDHGLevel", f:parsenoop },
2275
+ 0x01B7: { n:"BrtBeginPCDHGLGroups", f:parsenoop },
2276
+ 0x01B8: { n:"BrtEndPCDHGLGroups", f:parsenoop },
2277
+ 0x01B9: { n:"BrtBeginPCDHGLGroup", f:parsenoop },
2278
+ 0x01BA: { n:"BrtEndPCDHGLGroup", f:parsenoop },
2279
+ 0x01BB: { n:"BrtBeginPCDHGLGMembers", f:parsenoop },
2280
+ 0x01BC: { n:"BrtEndPCDHGLGMembers", f:parsenoop },
2281
+ 0x01BD: { n:"BrtBeginPCDHGLGMember", f:parsenoop },
2282
+ 0x01BE: { n:"BrtEndPCDHGLGMember", f:parsenoop },
2283
+ 0x01BF: { n:"BrtBeginQSI", f:parsenoop },
2284
+ 0x01C0: { n:"BrtEndQSI", f:parsenoop },
2285
+ 0x01C1: { n:"BrtBeginQSIR", f:parsenoop },
2286
+ 0x01C2: { n:"BrtEndQSIR", f:parsenoop },
2287
+ 0x01C3: { n:"BrtBeginDeletedNames", f:parsenoop },
2288
+ 0x01C4: { n:"BrtEndDeletedNames", f:parsenoop },
2289
+ 0x01C5: { n:"BrtBeginDeletedName", f:parsenoop },
2290
+ 0x01C6: { n:"BrtEndDeletedName", f:parsenoop },
2291
+ 0x01C7: { n:"BrtBeginQSIFs", f:parsenoop },
2292
+ 0x01C8: { n:"BrtEndQSIFs", f:parsenoop },
2293
+ 0x01C9: { n:"BrtBeginQSIF", f:parsenoop },
2294
+ 0x01CA: { n:"BrtEndQSIF", f:parsenoop },
2295
+ 0x01CB: { n:"BrtBeginAutoSortScope", f:parsenoop },
2296
+ 0x01CC: { n:"BrtEndAutoSortScope", f:parsenoop },
2297
+ 0x01CD: { n:"BrtBeginConditionalFormatting", f:parsenoop },
2298
+ 0x01CE: { n:"BrtEndConditionalFormatting", f:parsenoop },
2299
+ 0x01CF: { n:"BrtBeginCFRule", f:parsenoop },
2300
+ 0x01D0: { n:"BrtEndCFRule", f:parsenoop },
2301
+ 0x01D1: { n:"BrtBeginIconSet", f:parsenoop },
2302
+ 0x01D2: { n:"BrtEndIconSet", f:parsenoop },
2303
+ 0x01D3: { n:"BrtBeginDatabar", f:parsenoop },
2304
+ 0x01D4: { n:"BrtEndDatabar", f:parsenoop },
2305
+ 0x01D5: { n:"BrtBeginColorScale", f:parsenoop },
2306
+ 0x01D6: { n:"BrtEndColorScale", f:parsenoop },
2307
+ 0x01D7: { n:"BrtCFVO", f:parsenoop },
2308
+ 0x01D8: { n:"BrtExternValueMeta", f:parsenoop },
2309
+ 0x01D9: { n:"BrtBeginColorPalette", f:parsenoop },
2310
+ 0x01DA: { n:"BrtEndColorPalette", f:parsenoop },
2311
+ 0x01DB: { n:"BrtIndexedColor", f:parsenoop },
2312
+ 0x01DC: { n:"BrtMargins", f:parsenoop },
2313
+ 0x01DD: { n:"BrtPrintOptions", f:parsenoop },
2314
+ 0x01DE: { n:"BrtPageSetup", f:parsenoop },
2315
+ 0x01DF: { n:"BrtBeginHeaderFooter", f:parsenoop },
2316
+ 0x01E0: { n:"BrtEndHeaderFooter", f:parsenoop },
2317
+ 0x01E1: { n:"BrtBeginSXCrtFormat", f:parsenoop },
2318
+ 0x01E2: { n:"BrtEndSXCrtFormat", f:parsenoop },
2319
+ 0x01E3: { n:"BrtBeginSXCrtFormats", f:parsenoop },
2320
+ 0x01E4: { n:"BrtEndSXCrtFormats", f:parsenoop },
2321
+ 0x01E5: { n:"BrtWsFmtInfo", f:parsenoop },
2322
+ 0x01E6: { n:"BrtBeginMgs", f:parsenoop },
2323
+ 0x01E7: { n:"BrtEndMGs", f:parsenoop },
2324
+ 0x01E8: { n:"BrtBeginMGMaps", f:parsenoop },
2325
+ 0x01E9: { n:"BrtEndMGMaps", f:parsenoop },
2326
+ 0x01EA: { n:"BrtBeginMG", f:parsenoop },
2327
+ 0x01EB: { n:"BrtEndMG", f:parsenoop },
2328
+ 0x01EC: { n:"BrtBeginMap", f:parsenoop },
2329
+ 0x01ED: { n:"BrtEndMap", f:parsenoop },
2330
+ 0x01EE: { n:"BrtHLink", f:parsenoop },
2331
+ 0x01EF: { n:"BrtBeginDCon", f:parsenoop },
2332
+ 0x01F0: { n:"BrtEndDCon", f:parsenoop },
2333
+ 0x01F1: { n:"BrtBeginDRefs", f:parsenoop },
2334
+ 0x01F2: { n:"BrtEndDRefs", f:parsenoop },
2335
+ 0x01F3: { n:"BrtDRef", f:parsenoop },
2336
+ 0x01F4: { n:"BrtBeginScenMan", f:parsenoop },
2337
+ 0x01F5: { n:"BrtEndScenMan", f:parsenoop },
2338
+ 0x01F6: { n:"BrtBeginSct", f:parsenoop },
2339
+ 0x01F7: { n:"BrtEndSct", f:parsenoop },
2340
+ 0x01F8: { n:"BrtSlc", f:parsenoop },
2341
+ 0x01F9: { n:"BrtBeginDXFs", f:parsenoop },
2342
+ 0x01FA: { n:"BrtEndDXFs", f:parsenoop },
2343
+ 0x01FB: { n:"BrtDXF", f:parsenoop },
2344
+ 0x01FC: { n:"BrtBeginTableStyles", f:parsenoop },
2345
+ 0x01FD: { n:"BrtEndTableStyles", f:parsenoop },
2346
+ 0x01FE: { n:"BrtBeginTableStyle", f:parsenoop },
2347
+ 0x01FF: { n:"BrtEndTableStyle", f:parsenoop },
2348
+ 0x0200: { n:"BrtTableStyleElement", f:parsenoop },
2349
+ 0x0201: { n:"BrtTableStyleClient", f:parsenoop },
2350
+ 0x0202: { n:"BrtBeginVolDeps", f:parsenoop },
2351
+ 0x0203: { n:"BrtEndVolDeps", f:parsenoop },
2352
+ 0x0204: { n:"BrtBeginVolType", f:parsenoop },
2353
+ 0x0205: { n:"BrtEndVolType", f:parsenoop },
2354
+ 0x0206: { n:"BrtBeginVolMain", f:parsenoop },
2355
+ 0x0207: { n:"BrtEndVolMain", f:parsenoop },
2356
+ 0x0208: { n:"BrtBeginVolTopic", f:parsenoop },
2357
+ 0x0209: { n:"BrtEndVolTopic", f:parsenoop },
2358
+ 0x020A: { n:"BrtVolSubtopic", f:parsenoop },
2359
+ 0x020B: { n:"BrtVolRef", f:parsenoop },
2360
+ 0x020C: { n:"BrtVolNum", f:parsenoop },
2361
+ 0x020D: { n:"BrtVolErr", f:parsenoop },
2362
+ 0x020E: { n:"BrtVolStr", f:parsenoop },
2363
+ 0x020F: { n:"BrtVolBool", f:parsenoop },
2364
+ 0x0212: { n:"BrtBeginSortState", f:parsenoop },
2365
+ 0x0213: { n:"BrtEndSortState", f:parsenoop },
2366
+ 0x0214: { n:"BrtBeginSortCond", f:parsenoop },
2367
+ 0x0215: { n:"BrtEndSortCond", f:parsenoop },
2368
+ 0x0216: { n:"BrtBookProtection", f:parsenoop },
2369
+ 0x0217: { n:"BrtSheetProtection", f:parsenoop },
2370
+ 0x0218: { n:"BrtRangeProtection", f:parsenoop },
2371
+ 0x0219: { n:"BrtPhoneticInfo", f:parsenoop },
2372
+ 0x021A: { n:"BrtBeginECTxtWiz", f:parsenoop },
2373
+ 0x021B: { n:"BrtEndECTxtWiz", f:parsenoop },
2374
+ 0x021C: { n:"BrtBeginECTWFldInfoLst", f:parsenoop },
2375
+ 0x021D: { n:"BrtEndECTWFldInfoLst", f:parsenoop },
2376
+ 0x021E: { n:"BrtBeginECTwFldInfo", f:parsenoop },
2377
+ 0x0224: { n:"BrtFileSharing", f:parsenoop },
2378
+ 0x0225: { n:"BrtOleSize", f:parsenoop },
2379
+ 0x0226: { n:"BrtDrawing", f:parsenoop },
2380
+ 0x0227: { n:"BrtLegacyDrawing", f:parsenoop },
2381
+ 0x0228: { n:"BrtLegacyDrawingHF", f:parsenoop },
2382
+ 0x0229: { n:"BrtWebOpt", f:parsenoop },
2383
+ 0x022A: { n:"BrtBeginWebPubItems", f:parsenoop },
2384
+ 0x022B: { n:"BrtEndWebPubItems", f:parsenoop },
2385
+ 0x022C: { n:"BrtBeginWebPubItem", f:parsenoop },
2386
+ 0x022D: { n:"BrtEndWebPubItem", f:parsenoop },
2387
+ 0x022E: { n:"BrtBeginSXCondFmt", f:parsenoop },
2388
+ 0x022F: { n:"BrtEndSXCondFmt", f:parsenoop },
2389
+ 0x0230: { n:"BrtBeginSXCondFmts", f:parsenoop },
2390
+ 0x0231: { n:"BrtEndSXCondFmts", f:parsenoop },
2391
+ 0x0232: { n:"BrtBkHim", f:parsenoop },
2392
+ 0x0234: { n:"BrtColor", f:parsenoop },
2393
+ 0x0235: { n:"BrtBeginIndexedColors", f:parsenoop },
2394
+ 0x0236: { n:"BrtEndIndexedColors", f:parsenoop },
2395
+ 0x0239: { n:"BrtBeginMRUColors", f:parsenoop },
2396
+ 0x023A: { n:"BrtEndMRUColors", f:parsenoop },
2397
+ 0x023C: { n:"BrtMRUColor", f:parsenoop },
2398
+ 0x023D: { n:"BrtBeginDVals", f:parsenoop },
2399
+ 0x023E: { n:"BrtEndDVals", f:parsenoop },
2400
+ 0x0241: { n:"BrtSupNameStart", f:parsenoop },
2401
+ 0x0242: { n:"BrtSupNameValueStart", f:parsenoop },
2402
+ 0x0243: { n:"BrtSupNameValueEnd", f:parsenoop },
2403
+ 0x0244: { n:"BrtSupNameNum", f:parsenoop },
2404
+ 0x0245: { n:"BrtSupNameErr", f:parsenoop },
2405
+ 0x0246: { n:"BrtSupNameSt", f:parsenoop },
2406
+ 0x0247: { n:"BrtSupNameNil", f:parsenoop },
2407
+ 0x0248: { n:"BrtSupNameBool", f:parsenoop },
2408
+ 0x0249: { n:"BrtSupNameFmla", f:parsenoop },
2409
+ 0x024A: { n:"BrtSupNameBits", f:parsenoop },
2410
+ 0x024B: { n:"BrtSupNameEnd", f:parsenoop },
2411
+ 0x024C: { n:"BrtEndSupBook", f:parsenoop },
2412
+ 0x024D: { n:"BrtCellSmartTagProperty", f:parsenoop },
2413
+ 0x024E: { n:"BrtBeginCellSmartTag", f:parsenoop },
2414
+ 0x024F: { n:"BrtEndCellSmartTag", f:parsenoop },
2415
+ 0x0250: { n:"BrtBeginCellSmartTags", f:parsenoop },
2416
+ 0x0251: { n:"BrtEndCellSmartTags", f:parsenoop },
2417
+ 0x0252: { n:"BrtBeginSmartTags", f:parsenoop },
2418
+ 0x0253: { n:"BrtEndSmartTags", f:parsenoop },
2419
+ 0x0254: { n:"BrtSmartTagType", f:parsenoop },
2420
+ 0x0255: { n:"BrtBeginSmartTagTypes", f:parsenoop },
2421
+ 0x0256: { n:"BrtEndSmartTagTypes", f:parsenoop },
2422
+ 0x0257: { n:"BrtBeginSXFilters", f:parsenoop },
2423
+ 0x0258: { n:"BrtEndSXFilters", f:parsenoop },
2424
+ 0x0259: { n:"BrtBeginSXFILTER", f:parsenoop },
2425
+ 0x025A: { n:"BrtEndSXFilter", f:parsenoop },
2426
+ 0x025B: { n:"BrtBeginFills", f:parsenoop },
2427
+ 0x025C: { n:"BrtEndFills", f:parsenoop },
2428
+ 0x025D: { n:"BrtBeginCellWatches", f:parsenoop },
2429
+ 0x025E: { n:"BrtEndCellWatches", f:parsenoop },
2430
+ 0x025F: { n:"BrtCellWatch", f:parsenoop },
2431
+ 0x0260: { n:"BrtBeginCRErrs", f:parsenoop },
2432
+ 0x0261: { n:"BrtEndCRErrs", f:parsenoop },
2433
+ 0x0262: { n:"BrtCrashRecErr", f:parsenoop },
2434
+ 0x0263: { n:"BrtBeginFonts", f:parsenoop },
2435
+ 0x0264: { n:"BrtEndFonts", f:parsenoop },
2436
+ 0x0265: { n:"BrtBeginBorders", f:parsenoop },
2437
+ 0x0266: { n:"BrtEndBorders", f:parsenoop },
2438
+ 0x0267: { n:"BrtBeginFmts", f:parsenoop },
2439
+ 0x0268: { n:"BrtEndFmts", f:parsenoop },
2440
+ 0x0269: { n:"BrtBeginCellXFs", f:parsenoop },
2441
+ 0x026A: { n:"BrtEndCellXFs", f:parsenoop },
2442
+ 0x026B: { n:"BrtBeginStyles", f:parsenoop },
2443
+ 0x026C: { n:"BrtEndStyles", f:parsenoop },
2444
+ 0x0271: { n:"BrtBigName", f:parsenoop },
2445
+ 0x0272: { n:"BrtBeginCellStyleXFs", f:parsenoop },
2446
+ 0x0273: { n:"BrtEndCellStyleXFs", f:parsenoop },
2447
+ 0x0274: { n:"BrtBeginComments", f:parsenoop },
2448
+ 0x0275: { n:"BrtEndComments", f:parsenoop },
2449
+ 0x0276: { n:"BrtBeginCommentAuthors", f:parsenoop },
2450
+ 0x0277: { n:"BrtEndCommentAuthors", f:parsenoop },
2451
+ 0x0278: { n:"BrtCommentAuthor", f:parsenoop },
2452
+ 0x0279: { n:"BrtBeginCommentList", f:parsenoop },
2453
+ 0x027A: { n:"BrtEndCommentList", f:parsenoop },
2454
+ 0x027B: { n:"BrtBeginComment", f:parsenoop },
2455
+ 0x027C: { n:"BrtEndComment", f:parsenoop },
2456
+ 0x027D: { n:"BrtCommentText", f:parsenoop },
2457
+ 0x027E: { n:"BrtBeginOleObjects", f:parsenoop },
2458
+ 0x027F: { n:"BrtOleObject", f:parsenoop },
2459
+ 0x0280: { n:"BrtEndOleObjects", f:parsenoop },
2460
+ 0x0281: { n:"BrtBeginSxrules", f:parsenoop },
2461
+ 0x0282: { n:"BrtEndSxRules", f:parsenoop },
2462
+ 0x0283: { n:"BrtBeginActiveXControls", f:parsenoop },
2463
+ 0x0284: { n:"BrtActiveX", f:parsenoop },
2464
+ 0x0285: { n:"BrtEndActiveXControls", f:parsenoop },
2465
+ 0x0286: { n:"BrtBeginPCDSDTCEMembersSortBy", f:parsenoop },
2466
+ 0x0288: { n:"BrtBeginCellIgnoreECs", f:parsenoop },
2467
+ 0x0289: { n:"BrtCellIgnoreEC", f:parsenoop },
2468
+ 0x028A: { n:"BrtEndCellIgnoreECs", f:parsenoop },
2469
+ 0x028B: { n:"BrtCsProp", f:parsenoop },
2470
+ 0x028C: { n:"BrtCsPageSetup", f:parsenoop },
2471
+ 0x028D: { n:"BrtBeginUserCsViews", f:parsenoop },
2472
+ 0x028E: { n:"BrtEndUserCsViews", f:parsenoop },
2473
+ 0x028F: { n:"BrtBeginUserCsView", f:parsenoop },
2474
+ 0x0290: { n:"BrtEndUserCsView", f:parsenoop },
2475
+ 0x0291: { n:"BrtBeginPcdSFCIEntries", f:parsenoop },
2476
+ 0x0292: { n:"BrtEndPCDSFCIEntries", f:parsenoop },
2477
+ 0x0293: { n:"BrtPCDSFCIEntry", f:parsenoop },
2478
+ 0x0294: { n:"BrtBeginListParts", f:parsenoop },
2479
+ 0x0295: { n:"BrtListPart", f:parsenoop },
2480
+ 0x0296: { n:"BrtEndListParts", f:parsenoop },
2481
+ 0x0297: { n:"BrtSheetCalcProp", f:parsenoop },
2482
+ 0x0298: { n:"BrtBeginFnGroup", f:parsenoop },
2483
+ 0x0299: { n:"BrtFnGroup", f:parsenoop },
2484
+ 0x029A: { n:"BrtEndFnGroup", f:parsenoop },
2485
+ 0x029B: { n:"BrtSupAddin", f:parsenoop },
2486
+ 0x029C: { n:"BrtSXTDMPOrder", f:parsenoop },
2487
+ 0x029D: { n:"BrtCsProtection", f:parsenoop },
2488
+ 0x029F: { n:"BrtBeginWsSortMap", f:parsenoop },
2489
+ 0x02A0: { n:"BrtEndWsSortMap", f:parsenoop },
2490
+ 0x02A1: { n:"BrtBeginRRSort", f:parsenoop },
2491
+ 0x02A2: { n:"BrtEndRRSort", f:parsenoop },
2492
+ 0x02A3: { n:"BrtRRSortItem", f:parsenoop },
2493
+ 0x02A4: { n:"BrtFileSharingIso", f:parsenoop },
2494
+ 0x02A5: { n:"BrtBookProtectionIso", f:parsenoop },
2495
+ 0x02A6: { n:"BrtSheetProtectionIso", f:parsenoop },
2496
+ 0x02A7: { n:"BrtCsProtectionIso", f:parsenoop },
2497
+ 0x02A8: { n:"BrtRangeProtectionIso", f:parsenoop },
2498
+ 0x0400: { n:"BrtRwDescent", f:parsenoop },
2499
+ 0x0401: { n:"BrtKnownFonts", f:parsenoop },
2500
+ 0x0402: { n:"BrtBeginSXTupleSet", f:parsenoop },
2501
+ 0x0403: { n:"BrtEndSXTupleSet", f:parsenoop },
2502
+ 0x0404: { n:"BrtBeginSXTupleSetHeader", f:parsenoop },
2503
+ 0x0405: { n:"BrtEndSXTupleSetHeader", f:parsenoop },
2504
+ 0x0406: { n:"BrtSXTupleSetHeaderItem", f:parsenoop },
2505
+ 0x0407: { n:"BrtBeginSXTupleSetData", f:parsenoop },
2506
+ 0x0408: { n:"BrtEndSXTupleSetData", f:parsenoop },
2507
+ 0x0409: { n:"BrtBeginSXTupleSetRow", f:parsenoop },
2508
+ 0x040A: { n:"BrtEndSXTupleSetRow", f:parsenoop },
2509
+ 0x040B: { n:"BrtSXTupleSetRowItem", f:parsenoop },
2510
+ 0x040C: { n:"BrtNameExt", f:parsenoop },
2511
+ 0x040D: { n:"BrtPCDH14", f:parsenoop },
2512
+ 0x040E: { n:"BrtBeginPCDCalcMem14", f:parsenoop },
2513
+ 0x040F: { n:"BrtEndPCDCalcMem14", f:parsenoop },
2514
+ 0x0410: { n:"BrtSXTH14", f:parsenoop },
2515
+ 0x0411: { n:"BrtBeginSparklineGroup", f:parsenoop },
2516
+ 0x0412: { n:"BrtEndSparklineGroup", f:parsenoop },
2517
+ 0x0413: { n:"BrtSparkline", f:parsenoop },
2518
+ 0x0414: { n:"BrtSXDI14", f:parsenoop },
2519
+ 0x0415: { n:"BrtWsFmtInfoEx14", f:parsenoop },
2520
+ 0x0416: { n:"BrtBeginConditionalFormatting14", f:parsenoop },
2521
+ 0x0417: { n:"BrtEndConditionalFormatting14", f:parsenoop },
2522
+ 0x0418: { n:"BrtBeginCFRule14", f:parsenoop },
2523
+ 0x0419: { n:"BrtEndCFRule14", f:parsenoop },
2524
+ 0x041A: { n:"BrtCFVO14", f:parsenoop },
2525
+ 0x041B: { n:"BrtBeginDatabar14", f:parsenoop },
2526
+ 0x041C: { n:"BrtBeginIconSet14", f:parsenoop },
2527
+ 0x041D: { n:"BrtDVal14", f:parsenoop },
2528
+ 0x041E: { n:"BrtBeginDVals14", f:parsenoop },
2529
+ 0x041F: { n:"BrtColor14", f:parsenoop },
2530
+ 0x0420: { n:"BrtBeginSparklines", f:parsenoop },
2531
+ 0x0421: { n:"BrtEndSparklines", f:parsenoop },
2532
+ 0x0422: { n:"BrtBeginSparklineGroups", f:parsenoop },
2533
+ 0x0423: { n:"BrtEndSparklineGroups", f:parsenoop },
2534
+ 0x0425: { n:"BrtSXVD14", f:parsenoop },
2535
+ 0x0426: { n:"BrtBeginSxview14", f:parsenoop },
2536
+ 0x0427: { n:"BrtEndSxview14", f:parsenoop },
2537
+ 0x042A: { n:"BrtBeginPCD14", f:parsenoop },
2538
+ 0x042B: { n:"BrtEndPCD14", f:parsenoop },
2539
+ 0x042C: { n:"BrtBeginExtConn14", f:parsenoop },
2540
+ 0x042D: { n:"BrtEndExtConn14", f:parsenoop },
2541
+ 0x042E: { n:"BrtBeginSlicerCacheIDs", f:parsenoop },
2542
+ 0x042F: { n:"BrtEndSlicerCacheIDs", f:parsenoop },
2543
+ 0x0430: { n:"BrtBeginSlicerCacheID", f:parsenoop },
2544
+ 0x0431: { n:"BrtEndSlicerCacheID", f:parsenoop },
2545
+ 0x0433: { n:"BrtBeginSlicerCache", f:parsenoop },
2546
+ 0x0434: { n:"BrtEndSlicerCache", f:parsenoop },
2547
+ 0x0435: { n:"BrtBeginSlicerCacheDef", f:parsenoop },
2548
+ 0x0436: { n:"BrtEndSlicerCacheDef", f:parsenoop },
2549
+ 0x0437: { n:"BrtBeginSlicersEx", f:parsenoop },
2550
+ 0x0438: { n:"BrtEndSlicersEx", f:parsenoop },
2551
+ 0x0439: { n:"BrtBeginSlicerEx", f:parsenoop },
2552
+ 0x043A: { n:"BrtEndSlicerEx", f:parsenoop },
2553
+ 0x043B: { n:"BrtBeginSlicer", f:parsenoop },
2554
+ 0x043C: { n:"BrtEndSlicer", f:parsenoop },
2555
+ 0x043D: { n:"BrtSlicerCachePivotTables", f:parsenoop },
2556
+ 0x043E: { n:"BrtBeginSlicerCacheOlapImpl", f:parsenoop },
2557
+ 0x043F: { n:"BrtEndSlicerCacheOlapImpl", f:parsenoop },
2558
+ 0x0440: { n:"BrtBeginSlicerCacheLevelsData", f:parsenoop },
2559
+ 0x0441: { n:"BrtEndSlicerCacheLevelsData", f:parsenoop },
2560
+ 0x0442: { n:"BrtBeginSlicerCacheLevelData", f:parsenoop },
2561
+ 0x0443: { n:"BrtEndSlicerCacheLevelData", f:parsenoop },
2562
+ 0x0444: { n:"BrtBeginSlicerCacheSiRanges", f:parsenoop },
2563
+ 0x0445: { n:"BrtEndSlicerCacheSiRanges", f:parsenoop },
2564
+ 0x0446: { n:"BrtBeginSlicerCacheSiRange", f:parsenoop },
2565
+ 0x0447: { n:"BrtEndSlicerCacheSiRange", f:parsenoop },
2566
+ 0x0448: { n:"BrtSlicerCacheOlapItem", f:parsenoop },
2567
+ 0x0449: { n:"BrtBeginSlicerCacheSelections", f:parsenoop },
2568
+ 0x044A: { n:"BrtSlicerCacheSelection", f:parsenoop },
2569
+ 0x044B: { n:"BrtEndSlicerCacheSelections", f:parsenoop },
2570
+ 0x044C: { n:"BrtBeginSlicerCacheNative", f:parsenoop },
2571
+ 0x044D: { n:"BrtEndSlicerCacheNative", f:parsenoop },
2572
+ 0x044E: { n:"BrtSlicerCacheNativeItem", f:parsenoop },
2573
+ 0x044F: { n:"BrtRangeProtection14", f:parsenoop },
2574
+ 0x0450: { n:"BrtRangeProtectionIso14", f:parsenoop },
2575
+ 0x0451: { n:"BrtCellIgnoreEC14", f:parsenoop },
2576
+ 0x0457: { n:"BrtList14", f:parsenoop },
2577
+ 0x0458: { n:"BrtCFIcon", f:parsenoop },
2578
+ 0x0459: { n:"BrtBeginSlicerCachesPivotCacheIDs", f:parsenoop },
2579
+ 0x045A: { n:"BrtEndSlicerCachesPivotCacheIDs", f:parsenoop },
2580
+ 0x045B: { n:"BrtBeginSlicers", f:parsenoop },
2581
+ 0x045C: { n:"BrtEndSlicers", f:parsenoop },
2582
+ 0x045D: { n:"BrtWbProp14", f:parsenoop },
2583
+ 0x045E: { n:"BrtBeginSXEdit", f:parsenoop },
2584
+ 0x045F: { n:"BrtEndSXEdit", f:parsenoop },
2585
+ 0x0460: { n:"BrtBeginSXEdits", f:parsenoop },
2586
+ 0x0461: { n:"BrtEndSXEdits", f:parsenoop },
2587
+ 0x0462: { n:"BrtBeginSXChange", f:parsenoop },
2588
+ 0x0463: { n:"BrtEndSXChange", f:parsenoop },
2589
+ 0x0464: { n:"BrtBeginSXChanges", f:parsenoop },
2590
+ 0x0465: { n:"BrtEndSXChanges", f:parsenoop },
2591
+ 0x0466: { n:"BrtSXTupleItems", f:parsenoop },
2592
+ 0x0468: { n:"BrtBeginSlicerStyle", f:parsenoop },
2593
+ 0x0469: { n:"BrtEndSlicerStyle", f:parsenoop },
2594
+ 0x046A: { n:"BrtSlicerStyleElement", f:parsenoop },
2595
+ 0x046B: { n:"BrtBeginStyleSheetExt14", f:parsenoop },
2596
+ 0x046C: { n:"BrtEndStyleSheetExt14", f:parsenoop },
2597
+ 0x046D: { n:"BrtBeginSlicerCachesPivotCacheID", f:parsenoop },
2598
+ 0x046E: { n:"BrtEndSlicerCachesPivotCacheID", f:parsenoop },
2599
+ 0x046F: { n:"BrtBeginConditionalFormattings", f:parsenoop },
2600
+ 0x0470: { n:"BrtEndConditionalFormattings", f:parsenoop },
2601
+ 0x0471: { n:"BrtBeginPCDCalcMemExt", f:parsenoop },
2602
+ 0x0472: { n:"BrtEndPCDCalcMemExt", f:parsenoop },
2603
+ 0x0473: { n:"BrtBeginPCDCalcMemsExt", f:parsenoop },
2604
+ 0x0474: { n:"BrtEndPCDCalcMemsExt", f:parsenoop },
2605
+ 0x0475: { n:"BrtPCDField14", f:parsenoop },
2606
+ 0x0476: { n:"BrtBeginSlicerStyles", f:parsenoop },
2607
+ 0x0477: { n:"BrtEndSlicerStyles", f:parsenoop },
2608
+ 0x0478: { n:"BrtBeginSlicerStyleElements", f:parsenoop },
2609
+ 0x0479: { n:"BrtEndSlicerStyleElements", f:parsenoop },
2610
+ 0x047A: { n:"BrtCFRuleExt", f:parsenoop },
2611
+ 0x047B: { n:"BrtBeginSXCondFmt14", f:parsenoop },
2612
+ 0x047C: { n:"BrtEndSXCondFmt14", f:parsenoop },
2613
+ 0x047D: { n:"BrtBeginSXCondFmts14", f:parsenoop },
2614
+ 0x047E: { n:"BrtEndSXCondFmts14", f:parsenoop },
2615
+ 0x0480: { n:"BrtBeginSortCond14", f:parsenoop },
2616
+ 0x0481: { n:"BrtEndSortCond14", f:parsenoop },
2617
+ 0x0482: { n:"BrtEndDVals14", f:parsenoop },
2618
+ 0x0483: { n:"BrtEndIconSet14", f:parsenoop },
2619
+ 0x0484: { n:"BrtEndDatabar14", f:parsenoop },
2620
+ 0x0485: { n:"BrtBeginColorScale14", f:parsenoop },
2621
+ 0x0486: { n:"BrtEndColorScale14", f:parsenoop },
2622
+ 0x0487: { n:"BrtBeginSxrules14", f:parsenoop },
2623
+ 0x0488: { n:"BrtEndSxrules14", f:parsenoop },
2624
+ 0x0489: { n:"BrtBeginPRule14", f:parsenoop },
2625
+ 0x048A: { n:"BrtEndPRule14", f:parsenoop },
2626
+ 0x048B: { n:"BrtBeginPRFilters14", f:parsenoop },
2627
+ 0x048C: { n:"BrtEndPRFilters14", f:parsenoop },
2628
+ 0x048D: { n:"BrtBeginPRFilter14", f:parsenoop },
2629
+ 0x048E: { n:"BrtEndPRFilter14", f:parsenoop },
2630
+ 0x048F: { n:"BrtBeginPRFItem14", f:parsenoop },
2631
+ 0x0490: { n:"BrtEndPRFItem14", f:parsenoop },
2632
+ 0x0491: { n:"BrtBeginCellIgnoreECs14", f:parsenoop },
2633
+ 0x0492: { n:"BrtEndCellIgnoreECs14", f:parsenoop },
2634
+ 0x0493: { n:"BrtDxf14", f:parsenoop },
2635
+ 0x0494: { n:"BrtBeginDxF14s", f:parsenoop },
2636
+ 0x0495: { n:"BrtEndDxf14s", f:parsenoop },
2637
+ 0x0499: { n:"BrtFilter14", f:parsenoop },
2638
+ 0x049A: { n:"BrtBeginCustomFilters14", f:parsenoop },
2639
+ 0x049C: { n:"BrtCustomFilter14", f:parsenoop },
2640
+ 0x049D: { n:"BrtIconFilter14", f:parsenoop },
2641
+ 0x049E: { n:"BrtPivotCacheConnectionName", f:parsenoop },
2642
+ 0x0800: { n:"BrtBeginDecoupledPivotCacheIDs", f:parsenoop },
2643
+ 0x0801: { n:"BrtEndDecoupledPivotCacheIDs", f:parsenoop },
2644
+ 0x0802: { n:"BrtDecoupledPivotCacheID", f:parsenoop },
2645
+ 0x0803: { n:"BrtBeginPivotTableRefs", f:parsenoop },
2646
+ 0x0804: { n:"BrtEndPivotTableRefs", f:parsenoop },
2647
+ 0x0805: { n:"BrtPivotTableRef", f:parsenoop },
2648
+ 0x0806: { n:"BrtSlicerCacheBookPivotTables", f:parsenoop },
2649
+ 0x0807: { n:"BrtBeginSxvcells", f:parsenoop },
2650
+ 0x0808: { n:"BrtEndSxvcells", f:parsenoop },
2651
+ 0x0809: { n:"BrtBeginSxRow", f:parsenoop },
2652
+ 0x080A: { n:"BrtEndSxRow", f:parsenoop },
2653
+ 0x080C: { n:"BrtPcdCalcMem15", f:parsenoop },
2654
+ 0x0813: { n:"BrtQsi15", f:parsenoop },
2655
+ 0x0814: { n:"BrtBeginWebExtensions", f:parsenoop },
2656
+ 0x0815: { n:"BrtEndWebExtensions", f:parsenoop },
2657
+ 0x0816: { n:"BrtWebExtension", f:parsenoop },
2658
+ 0x0817: { n:"BrtAbsPath15", f:parsenoop },
2659
+ 0x0818: { n:"BrtBeginPivotTableUISettings", f:parsenoop },
2660
+ 0x0819: { n:"BrtEndPivotTableUISettings", f:parsenoop },
2661
+ 0x081B: { n:"BrtTableSlicerCacheIDs", f:parsenoop },
2662
+ 0x081C: { n:"BrtTableSlicerCacheID", f:parsenoop },
2663
+ 0x081D: { n:"BrtBeginTableSlicerCache", f:parsenoop },
2664
+ 0x081E: { n:"BrtEndTableSlicerCache", f:parsenoop },
2665
+ 0x081F: { n:"BrtSxFilter15", f:parsenoop },
2666
+ 0x0820: { n:"BrtBeginTimelineCachePivotCacheIDs", f:parsenoop },
2667
+ 0x0821: { n:"BrtEndTimelineCachePivotCacheIDs", f:parsenoop },
2668
+ 0x0822: { n:"BrtTimelineCachePivotCacheID", f:parsenoop },
2669
+ 0x0823: { n:"BrtBeginTimelineCacheIDs", f:parsenoop },
2670
+ 0x0824: { n:"BrtEndTimelineCacheIDs", f:parsenoop },
2671
+ 0x0825: { n:"BrtBeginTimelineCacheID", f:parsenoop },
2672
+ 0x0826: { n:"BrtEndTimelineCacheID", f:parsenoop },
2673
+ 0x0827: { n:"BrtBeginTimelinesEx", f:parsenoop },
2674
+ 0x0828: { n:"BrtEndTimelinesEx", f:parsenoop },
2675
+ 0x0829: { n:"BrtBeginTimelineEx", f:parsenoop },
2676
+ 0x082A: { n:"BrtEndTimelineEx", f:parsenoop },
2677
+ 0x082B: { n:"BrtWorkBookPr15", f:parsenoop },
2678
+ 0x082C: { n:"BrtPCDH15", f:parsenoop },
2679
+ 0x082D: { n:"BrtBeginTimelineStyle", f:parsenoop },
2680
+ 0x082E: { n:"BrtEndTimelineStyle", f:parsenoop },
2681
+ 0x082F: { n:"BrtTimelineStyleElement", f:parsenoop },
2682
+ 0x0830: { n:"BrtBeginTimelineStylesheetExt15", f:parsenoop },
2683
+ 0x0831: { n:"BrtEndTimelineStylesheetExt15", f:parsenoop },
2684
+ 0x0832: { n:"BrtBeginTimelineStyles", f:parsenoop },
2685
+ 0x0833: { n:"BrtEndTimelineStyles", f:parsenoop },
2686
+ 0x0834: { n:"BrtBeginTimelineStyleElements", f:parsenoop },
2687
+ 0x0835: { n:"BrtEndTimelineStyleElements", f:parsenoop },
2688
+ 0x0836: { n:"BrtDxf15", f:parsenoop },
2689
+ 0x0837: { n:"BrtBeginDxfs15", f:parsenoop },
2690
+ 0x0838: { n:"brtEndDxfs15", f:parsenoop },
2691
+ 0x0839: { n:"BrtSlicerCacheHideItemsWithNoData", f:parsenoop },
2692
+ 0x083A: { n:"BrtBeginItemUniqueNames", f:parsenoop },
2693
+ 0x083B: { n:"BrtEndItemUniqueNames", f:parsenoop },
2694
+ 0x083C: { n:"BrtItemUniqueName", f:parsenoop },
2695
+ 0x083D: { n:"BrtBeginExtConn15", f:parsenoop },
2696
+ 0x083E: { n:"BrtEndExtConn15", f:parsenoop },
2697
+ 0x083F: { n:"BrtBeginOledbPr15", f:parsenoop },
2698
+ 0x0840: { n:"BrtEndOledbPr15", f:parsenoop },
2699
+ 0x0841: { n:"BrtBeginDataFeedPr15", f:parsenoop },
2700
+ 0x0842: { n:"BrtEndDataFeedPr15", f:parsenoop },
2701
+ 0x0843: { n:"BrtTextPr15", f:parsenoop },
2702
+ 0x0844: { n:"BrtRangePr15", f:parsenoop },
2703
+ 0x0845: { n:"BrtDbCommand15", f:parsenoop },
2704
+ 0x0846: { n:"BrtBeginDbTables15", f:parsenoop },
2705
+ 0x0847: { n:"BrtEndDbTables15", f:parsenoop },
2706
+ 0x0848: { n:"BrtDbTable15", f:parsenoop },
2707
+ 0x0849: { n:"BrtBeginDataModel", f:parsenoop },
2708
+ 0x084A: { n:"BrtEndDataModel", f:parsenoop },
2709
+ 0x084B: { n:"BrtBeginModelTables", f:parsenoop },
2710
+ 0x084C: { n:"BrtEndModelTables", f:parsenoop },
2711
+ 0x084D: { n:"BrtModelTable", f:parsenoop },
2712
+ 0x084E: { n:"BrtBeginModelRelationships", f:parsenoop },
2713
+ 0x084F: { n:"BrtEndModelRelationships", f:parsenoop },
2714
+ 0x0850: { n:"BrtModelRelationship", f:parsenoop },
2715
+ 0x0851: { n:"BrtBeginECTxtWiz15", f:parsenoop },
2716
+ 0x0852: { n:"BrtEndECTxtWiz15", f:parsenoop },
2717
+ 0x0853: { n:"BrtBeginECTWFldInfoLst15", f:parsenoop },
2718
+ 0x0854: { n:"BrtEndECTWFldInfoLst15", f:parsenoop },
2719
+ 0x0855: { n:"BrtBeginECTWFldInfo15", f:parsenoop },
2720
+ 0x0856: { n:"BrtFieldListActiveItem", f:parsenoop },
2721
+ 0x0857: { n:"BrtPivotCacheIdVersion", f:parsenoop },
2722
+ 0x0858: { n:"BrtSXDI15", f:parsenoop },
2723
+ 0xFFFF: { n:"", f:parsenoop }
2724
+ };
1012
2725
 
1013
- /* fonts CT_Fonts ? */
1014
- /* fills CT_Fills ? */
1015
- /* borders CT_Borders ? */
1016
- /* cellStyleXfs CT_CellStyleXfs ? */
2726
+ function fixopts(opts) {
2727
+ var defaults = [
2728
+ ['cellNF', false], /* emit cell number format string as .z */
2729
+ ['cellHTML', true], /* emit html string as .h */
2730
+ ['cellFormula', true], /* emit formulae as .f */
2731
+
2732
+ ['sheetStubs', false], /* emit empty cells */
2733
+ ['sheetRows', 0, 'n'], /* read n rows (0 = read all rows) */
2734
+ ['bookDeps', false], /* parse calculation chains */
2735
+ ['bookSheets', false], /* only try to get sheet names (no Sheets) */
2736
+ ['bookProps', false], /* only try to get properties (no Sheets) */
2737
+ ['bookFiles', false], /* include raw file structure (keys, files) */
2738
+
2739
+ ['WTF', false] /* WTF mode (throws errors) */
2740
+ ];
2741
+ defaults.forEach(function(d) {
2742
+ if(typeof opts[d[0]] === 'undefined') opts[d[0]] = d[1];
2743
+ if(d[2] === 'n') opts[d[0]] = Number(opts[d[0]]);
2744
+ });
2745
+ }
2746
+ function parseZip(zip, opts) {
2747
+ opts = opts || {};
2748
+ fixopts(opts);
2749
+ reset_cp();
2750
+ var entries = Object.keys(zip.files);
2751
+ var keys = entries.filter(function(x){return x.substr(-1) != '/';}).sort();
2752
+ var dir = parseCT(getzipdata(zip, '[Content_Types].xml'));
2753
+ var xlsb = false;
2754
+ var sheets;
2755
+ if(dir.workbooks.length === 0) {
2756
+ var binname = "xl/workbook.bin";
2757
+ if(!getzipfile(zip,binname)) throw new Error("Could not find workbook entry");
2758
+ dir.workbooks.push(binname);
2759
+ xlsb = true;
2760
+ }
1017
2761
 
1018
- /* cellXfs CT_CellXfs ? */
1019
- if((t=data.match(/<cellXfs([^>]*)>.*<\/cellXfs>/))) parseCXfs(t);
2762
+ if(!opts.bookSheets && !opts.bookProps) {
2763
+ strs = {};
2764
+ if(dir.sst) strs=parse_sst(getzipdata(zip, dir.sst.replace(/^\//,'')), dir.sst, opts);
1020
2765
 
1021
- /* dxfs CT_Dxfs ? */
1022
- /* tableStyles CT_TableStyles ? */
1023
- /* colors CT_Colors ? */
1024
- /* extLst CT_ExtensionList ? */
2766
+ styles = {};
2767
+ if(dir.style) styles = parse_sty(getzipdata(zip, dir.style.replace(/^\//,'')),dir.style);
2768
+ }
1025
2769
 
1026
- return styles;
1027
- }
2770
+ var wb = parse_wb(getzipdata(zip, dir.workbooks[0].replace(/^\//,'')), dir.workbooks[0], opts);
1028
2771
 
1029
- function getdata(data) {
1030
- if(!data) return null;
1031
- if(data.data) return data.data;
1032
- if(data._data && data._data.getContent) return Array.prototype.slice.call(data._data.getContent(),0).map(function(x) { return String.fromCharCode(x); }).join("");
1033
- return null;
1034
- }
2772
+ var props = {}, propdata = "";
2773
+ try {
2774
+ propdata = dir.coreprops.length !== 0 ? getzipdata(zip, dir.coreprops[0].replace(/^\//,'')) : "";
2775
+ propdata += dir.extprops.length !== 0 ? getzipdata(zip, dir.extprops[0].replace(/^\//,'')) : "";
2776
+ props = propdata !== "" ? parseProps(propdata) : {};
2777
+ } catch(e) { }
1035
2778
 
1036
- function getzipfile(zip, file) {
1037
- var f = file; if(zip.files[f]) return zip.files[f];
1038
- f = file.toLowerCase(); if(zip.files[f]) return zip.files[f];
1039
- f = f.replace(/\//g,'\\'); if(zip.files[f]) return zip.files[f];
1040
- throw new Error("Cannot find file " + file + " in zip");
1041
- }
2779
+ var custprops = {};
2780
+ if(!opts.bookSheets || opts.bookProps) {
2781
+ if (dir.custprops.length !== 0) {
2782
+ propdata = getzipdata(zip, dir.custprops[0].replace(/^\//,''), true);
2783
+ if(propdata) custprops = parseCustomProps(propdata);
2784
+ }
2785
+ }
2786
+
2787
+ var out = {};
2788
+ if(opts.bookSheets || opts.bookProps) {
2789
+ if(props.Worksheets && props.SheetNames.length > 0) sheets=props.SheetNames;
2790
+ else if(wb.Sheets) sheets = wb.Sheets.map(function(x){ return x.name; });
2791
+ if(opts.bookProps) { out.Props = props; out.Custprops = custprops; }
2792
+ if(typeof sheets !== 'undefined') out.SheetNames = sheets;
2793
+ if(opts.bookSheets ? out.SheetNames : opts.bookProps) return out;
2794
+ }
2795
+ sheets = {};
1042
2796
 
1043
- function parseZip(zip) {
1044
- var entries = Object.keys(zip.files);
1045
- var keys = entries.filter(function(x){return x.substr(-1) != '/';}).sort();
1046
- var dir = parseCT(getdata(getzipfile(zip, '[Content_Types].xml')));
1047
- if(dir.workbooks.length === 0) throw new Error("Could not find workbook entry");
1048
- strs = {};
1049
- if(dir.sst) strs=parse_sst(getdata(getzipfile(zip, dir.sst.replace(/^\//,''))));
1050
-
1051
- styles = {};
1052
- if(dir.style) styles = parseStyles(getdata(getzipfile(zip, dir.style.replace(/^\//,''))));
1053
-
1054
- var wb = parseWB(getdata(getzipfile(zip, dir.workbooks[0].replace(/^\//,''))));
1055
- var propdata = dir.coreprops.length !== 0 ? getdata(getzipfile(zip, dir.coreprops[0].replace(/^\//,''))) : "";
1056
- propdata += dir.extprops.length !== 0 ? getdata(getzipfile(zip, dir.extprops[0].replace(/^\//,''))) : "";
1057
- var props = propdata !== "" ? parseProps(propdata) : {};
1058
2797
  var deps = {};
1059
- if(dir.calcchain) deps=parseDeps(getdata(getzipfile(zip, dir.calcchain.replace(/^\//,''))));
1060
- var sheets = {}, i=0;
2798
+ if(opts.bookDeps && dir.calcchain) deps=parseDeps(getzipdata(zip, dir.calcchain.replace(/^\//,'')));
2799
+
2800
+ var i=0;
2801
+ var sheetRels = {};
2802
+ var path, relsPath;
1061
2803
  if(!props.Worksheets) {
1062
2804
  /* Google Docs doesn't generate the appropriate metadata, so we impute: */
1063
2805
  var wbsheets = wb.Sheets;
@@ -1066,52 +2808,51 @@ function parseZip(zip) {
1066
2808
  for(var j = 0; j != wbsheets.length; ++j) {
1067
2809
  props.SheetNames[j] = wbsheets[j].name;
1068
2810
  }
1069
- for(i = 0; i != props.Worksheets; ++i) {
1070
- try { /* TODO: remove these guards */
1071
- sheets[props.SheetNames[i]]=parseSheet(getdata(getzipfile(zip, 'xl/worksheets/sheet' + (i+1) + '.xml')));
1072
- } catch(e) {}
1073
- }
1074
2811
  }
1075
- else {
1076
- for(i = 0; i != props.Worksheets; ++i) {
1077
- try {
1078
- sheets[props.SheetNames[i]]=parseSheet(getdata(getzipfile(zip, dir.sheets[i].replace(/^\//,''))));
1079
- } catch(e) {}
1080
- }
2812
+ /* Numbers iOS hack TODO: parse workbook rels to get names */
2813
+ var nmode = (getzipdata(zip,"xl/worksheets/sheet.xml",true))?1:0;
2814
+ for(i = 0; i != props.Worksheets; ++i) {
2815
+ try {
2816
+ //path = dir.sheets[i].replace(/^\//,'');
2817
+ path = 'xl/worksheets/sheet'+(i+1-nmode)+(xlsb?'.bin':'.xml');
2818
+ path = path.replace(/sheet0\./,"sheet.");
2819
+ relsPath = path.replace(/^(.*)(\/)([^\/]*)$/, "$1/_rels/$3.rels");
2820
+ sheets[props.SheetNames[i]]=parse_ws(getzipdata(zip, path),path,opts);
2821
+ sheetRels[props.SheetNames[i]]=parseRels(getzipdata(zip, relsPath, true), path);
2822
+ } catch(e) { if(opts.WTF) throw e; }
1081
2823
  }
1082
- return {
2824
+
2825
+ if(dir.comments) parse_comments(zip, dir.comments, sheets, sheetRels, opts);
2826
+
2827
+ out = {
1083
2828
  Directory: dir,
1084
2829
  Workbook: wb,
1085
2830
  Props: props,
2831
+ Custprops: custprops,
1086
2832
  Deps: deps,
1087
2833
  Sheets: sheets,
1088
2834
  SheetNames: props.SheetNames,
1089
2835
  Strings: strs,
1090
2836
  Styles: styles,
1091
- keys: keys,
1092
- files: zip.files
1093
2837
  };
1094
- }
1095
-
1096
- var _fs, jszip;
1097
- if(typeof JSZip !== 'undefined') jszip = JSZip;
1098
- if (typeof exports !== 'undefined') {
1099
- if (typeof module !== 'undefined' && module.exports) {
1100
- if(typeof jszip === 'undefined') jszip = require('./jszip').JSZip;
1101
- _fs = require('fs');
2838
+ if(opts.bookFiles) {
2839
+ out.keys = keys;
2840
+ out.files = zip.files;
1102
2841
  }
2842
+ return out;
1103
2843
  }
1104
-
1105
2844
  function readSync(data, options) {
1106
2845
  var zip, d = data;
1107
2846
  var o = options||{};
1108
2847
  switch((o.type||"base64")){
1109
- case "file": d = _fs.readFileSync(data).toString('base64');
2848
+ case "file":
2849
+ if(typeof Buffer !== 'undefined') { zip=new jszip(d=_fs.readFileSync(data)); break; }
2850
+ d = _fs.readFileSync(data).toString('base64');
1110
2851
  /* falls through */
1111
2852
  case "base64": zip = new jszip(d, { base64:true }); break;
1112
2853
  case "binary": zip = new jszip(d, { base64:false }); break;
1113
2854
  }
1114
- return parseZip(zip);
2855
+ return parseZip(zip, o);
1115
2856
  }
1116
2857
 
1117
2858
  function readFileSync(data, options) {
@@ -1138,83 +2879,78 @@ function split_cell(cstr) { return cstr.replace(/(\$?[A-Z]*)(\$?[0-9]*)/,"$1,$2"
1138
2879
  function decode_cell(cstr) { var splt = split_cell(cstr); return { c:decode_col(splt[0]), r:decode_row(splt[1]) }; }
1139
2880
  function decode_range(range) { var x =range.split(":").map(decode_cell); return {s:x[0],e:x[x.length-1]}; }
1140
2881
  function encode_range(range) { return encode_cell(range.s) + ":" + encode_cell(range.e); }
1141
- /**
1142
- * Convert a sheet into an array of objects where the column headers are keys.
1143
- **/
1144
- function sheet_to_row_object_array(sheet){
1145
- var val, rowObject, range, columnHeaders, emptyRow, C;
1146
- var outSheet = [];
1147
- if (sheet["!ref"]) {
1148
- range = decode_range(sheet["!ref"]);
1149
-
1150
- columnHeaders = {};
1151
- for (C = range.s.c; C <= range.e.c; ++C) {
1152
- val = sheet[encode_cell({
1153
- c: C,
1154
- r: range.s.r
1155
- })];
1156
- if(val){
1157
- switch(val.t) {
1158
- case 's': case 'str': columnHeaders[C] = val.v; break;
1159
- case 'n': columnHeaders[C] = val.v; break;
1160
- }
1161
- }
2882
+
2883
+ function sheet_to_row_object_array(sheet, opts){
2884
+ var val, row, r, hdr = {}, isempty, R, C;
2885
+ var out = [];
2886
+ opts = opts || {};
2887
+ if(!sheet || !sheet["!ref"]) return out;
2888
+ r = XLSX.utils.decode_range(sheet["!ref"]);
2889
+ for(R=r.s.r, C = r.s.c; C <= r.e.c; ++C) {
2890
+ val = sheet[encode_cell({c:C,r:R})];
2891
+ if(!val) continue;
2892
+ if(val.w) hdr[C] = val.w;
2893
+ else switch(val.t) {
2894
+ case 's': case 'str': hdr[C] = val.v; break;
2895
+ case 'n': hdr[C] = val.v; break;
1162
2896
  }
2897
+ }
1163
2898
 
1164
- for (var R = range.s.r + 1; R <= range.e.r; ++R) {
1165
- emptyRow = true;
1166
- //Row number is recorded in the prototype
1167
- //so that it doesn't appear when stringified.
1168
- rowObject = Object.create({ __rowNum__ : R });
1169
- for (C = range.s.c; C <= range.e.c; ++C) {
1170
- val = sheet[encode_cell({
1171
- c: C,
1172
- r: R
1173
- })];
1174
- if(val !== undefined) switch(val.t){
1175
- case 's': case 'str': case 'b': case 'n':
1176
- if(val.v !== undefined) {
1177
- rowObject[columnHeaders[C]] = val.v;
1178
- emptyRow = false;
1179
- }
1180
- break;
1181
- case 'e': break; /* throw */
1182
- default: throw 'unrecognized type ' + val.t;
1183
- }
1184
- }
1185
- if(!emptyRow) {
1186
- outSheet.push(rowObject);
2899
+ for (R = r.s.r + 1; R <= r.e.r; ++R) {
2900
+ isempty = true;
2901
+ /* row index available as __rowNum__ */
2902
+ row = Object.create({ __rowNum__ : R });
2903
+ for (C = r.s.c; C <= r.e.c; ++C) {
2904
+ val = sheet[encode_cell({c: C,r: R})];
2905
+ if(!val || !val.t) continue;
2906
+ if(typeof val.w !== 'undefined' && !opts.raw) { row[hdr[C]] = val.w; isempty = false; }
2907
+ else switch(val.t){
2908
+ case 's': case 'str': case 'b': case 'n':
2909
+ if(typeof val.v !== 'undefined') {
2910
+ row[hdr[C]] = val.v;
2911
+ isempty = false;
2912
+ }
2913
+ break;
2914
+ case 'e': break; /* throw */
2915
+ default: throw 'unrecognized type ' + val.t;
1187
2916
  }
1188
2917
  }
2918
+ if(!isempty) out.push(row);
1189
2919
  }
1190
- return outSheet;
2920
+ return out;
1191
2921
  }
1192
2922
 
1193
- function sheet_to_csv(sheet) {
2923
+ function sheet_to_csv(sheet, opts) {
1194
2924
  var stringify = function stringify(val) {
2925
+ if(!val.t) return "";
2926
+ if(typeof val.w !== 'undefined') return val.w;
1195
2927
  switch(val.t){
1196
2928
  case 'n': return String(val.v);
1197
- case 's': case 'str':
1198
- if(typeof val.v === 'undefined') return "";
1199
- return JSON.stringify(val.v);
2929
+ case 's': case 'str': return typeof val.v !== 'undefined' ? val.v : "";
1200
2930
  case 'b': return val.v ? "TRUE" : "FALSE";
1201
- case 'e': return ""; /* throw out value in case of error */
2931
+ case 'e': return val.v; /* throw out value in case of error */
1202
2932
  default: throw 'unrecognized type ' + val.t;
1203
2933
  }
1204
2934
  };
1205
- var out = "";
1206
- if(sheet["!ref"]) {
1207
- var r = XLSX.utils.decode_range(sheet["!ref"]);
1208
- for(var R = r.s.r; R <= r.e.r; ++R) {
1209
- var row = [];
1210
- for(var C = r.s.c; C <= r.e.c; ++C) {
1211
- var val = sheet[XLSX.utils.encode_cell({c:C,r:R})];
1212
- row.push(val ? stringify(val).replace(/\\r\\n/g,"\n").replace(/\\t/g,"\t").replace(/\\\\/g,"\\").replace("\\\"","\"\"") : "");
1213
- }
1214
- out += row.join(",") + "\n";
2935
+ var out = [], txt = "";
2936
+ opts = opts || {};
2937
+ if(!sheet || !sheet["!ref"]) return "";
2938
+ var r = XLSX.utils.decode_range(sheet["!ref"]);
2939
+ var fs = opts.FS||",", rs = opts.RS||"\n";
2940
+
2941
+ for(var R = r.s.r; R <= r.e.r; ++R) {
2942
+ var row = [];
2943
+ for(var C = r.s.c; C <= r.e.c; ++C) {
2944
+ var val = sheet[XLSX.utils.encode_cell({c:C,r:R})];
2945
+ if(!val) { row.push(""); continue; }
2946
+ txt = String(stringify(val));
2947
+ if(txt.indexOf(fs)!==-1 || txt.indexOf(rs)!==-1 || txt.indexOf('"')!==-1)
2948
+ txt = "\"" + txt.replace(/"/g, '""') + "\"";
2949
+ row.push(txt);
1215
2950
  }
2951
+ out.push(row.join(fs));
1216
2952
  }
1217
- return out;
2953
+ return out.join(rs) + (out.length ? rs : "");
1218
2954
  }
1219
2955
  var make_csv = sheet_to_csv;
1220
2956
 
@@ -1224,7 +2960,8 @@ function get_formulae(ws) {
1224
2960
  var x = ws[y];
1225
2961
  var val = "";
1226
2962
  if(x.f) val = x.f;
1227
- else if(typeof x.v === 'number') val = x.v;
2963
+ else if(typeof x.w !== 'undefined') val = "'" + x.w;
2964
+ else if(typeof x.v === 'undefined') continue;
1228
2965
  else val = x.v;
1229
2966
  cmds.push(y + "=" + val);
1230
2967
  }
@@ -1251,10 +2988,5 @@ if(typeof require !== 'undefined' && typeof exports !== 'undefined') {
1251
2988
  exports.read = XLSX.read;
1252
2989
  exports.readFile = XLSX.readFile;
1253
2990
  exports.utils = XLSX.utils;
1254
- exports.main = function(args) {
1255
- var zip = XLSX.read(args[0], {type:'file'});
1256
- console.log(zip.Sheets);
1257
- };
1258
- if(typeof module !== 'undefined' && require.main === module)
1259
- exports.main(process.argv.slice(2));
2991
+ exports.version = XLSX.version;
1260
2992
  }