/* OpenDocument */
var write_styles_ods/*:{(wb:any, opts:any):string}*/ = /* @__PURE__ */(function() {
	var master_styles = [
		'',
			'',
				'',
				'',
				'',
				'',
			'',
		''
	].join("");
	var payload = '' + master_styles + '';
	return function wso(/*::wb, opts*/) {
		return XML_HEADER + payload;
	};
})();
// TODO: find out if anyone actually read the spec.  LO has some wild errors
function write_number_format_ods(nf/*:string*/, nfidx/*:string*/)/*:string*/ {
	var type = "number", payload = "", nopts = { "style:name": nfidx }, c = "", i = 0;
	nf = nf.replace(/"[$]"/g, "$");
	/* TODO: replace with an actual parser based on a real grammar */
	j: {
		// TODO: support style maps
		if(nf.indexOf(";") > -1) {
			console.error("Unsupported ODS Style Map exported.  Using first branch of " + nf);
			nf = nf.slice(0, nf.indexOf(";"));
		}
		if(nf == "@") { type = "text"; payload = ""; break j; }
		/* currency flag */
		if(nf.indexOf(/\$/) > -1) { type = "currency"; }
		/* opening string literal */
		if(nf[i] == '"') {
			c = "";
			while(nf[++i] != '"' || nf[++i] == '"') c += nf[i]; --i;
			if(nf[i+1] == "*") {
				i++;
				payload += '' + escapexml(c.replace(/""/g, '"')) + '';
			} else {
				payload += '' + escapexml(c.replace(/""/g, '"')) + '';
			}
			nf = nf.slice(i+1); i = 0;
		}
		/* fractions */
		var t = nf.match(/# (\?+)\/(\?+)/);
		if(t) { payload += writextag("number:fraction", null, {"number:min-integer-digits":0, "number:min-numerator-digits": t[1].length, "number:max-denominator-value": Math.max(+(t[1].replace(/./g, "9")), +(t[2].replace(/./g, "9"))) }); break j; }
		if((t=nf.match(/# (\?+)\/(\d+)/))) { payload += writextag("number:fraction", null, {"number:min-integer-digits":0, "number:min-numerator-digits": t[1].length, "number:denominator-value": +t[2]}); break j; }
		/* percentages */
		if((t=nf.match(/\b(\d+)(|\.\d+)%/))) { type = "percentage"; payload += writextag("number:number", null, {"number:decimal-places": t[2] && t.length - 1 || 0, "number:min-decimal-places": t[2] && t.length - 1 || 0, "number:min-integer-digits": t[1].length }) + "%"; break j; }
		/* datetime */
		var has_time = false;
		if(["y","m","d"].indexOf(nf[0]) > -1) {
			type = "date";
			k: for(; i < nf.length; ++i) switch((c = nf[i].toLowerCase())) {
				case "h": case "s": has_time = true; --i; break k;
				case "m":
					l: for(var h = i+1; h < nf.length; ++h) switch(nf[h]) {
						case "y": case "d": break l;
						case "h": case "s": has_time = true; --i; break k;
					}
					/* falls through */
				case "y": case "d":
					while((nf[++i]||"").toLowerCase() == c[0]) c += c[0]; --i;
					switch(c) {
						case "y": case "yy": payload += ""; break;
						case "yyy": case "yyyy": payload += ''; break;
						case "mmmmm": console.error("ODS has no equivalent of format |mmmmm|");
							/* falls through */
						case "m": case "mm": case "mmm": case "mmmm":
							payload += '';
							break;
						case "d": case "dd": payload += ''; break;
						case "ddd": case "dddd": payload += ''; break;
					}
					break;
				case '"':
					while(nf[++i] != '"' || nf[++i] == '"') c += nf[i]; --i;
					payload += '' + escapexml(c.slice(1).replace(/""/g, '"')) + '';
					break;
				case '\\': c = nf[++i];
					payload += '' + escapexml(c) + ''; break;
				case '/': case ':': payload += '' + escapexml(c) + ''; break;
				default: console.error("unrecognized character " + c + " in ODF format " + nf);
			}
			if(!has_time) break j;
			nf = nf.slice(i+1); i = 0;
		}
		if(nf.match(/^\[?[hms]/)) {
			if(type == "number") type = "time";
			if(nf.match(/\[/)) {
				nf = nf.replace(/[\[\]]/g, "");
				nopts['number:truncate-on-overflow'] = "false";
			}
			for(; i < nf.length; ++i) switch((c = nf[i].toLowerCase())) {
				case "h": case "m": case "s":
					while((nf[++i]||"").toLowerCase() == c[0]) c += c[0]; --i;
					switch(c) {
						case "h": case "hh": payload += ''; break;
						case "m": case "mm": payload += ''; break;
						case "s": case "ss":
							if(nf[i+1] == ".") do { c += nf[i+1]; ++i; } while(nf[i+1] == "0");
							payload += ''; break;
					}
					break;
				case '"':
					while(nf[++i] != '"' || nf[++i] == '"') c += nf[i]; --i;
					payload += '' + escapexml(c.slice(1).replace(/""/g, '"')) + '';
					break;
				case '/': case ':': payload += '' + escapexml(c) + ''; break;
				case "a":
					if(nf.slice(i, i+3).toLowerCase() == "a/p") { payload += ''; i += 2; break; } // Note: ODF does not support A/P
					if(nf.slice(i, i+5).toLowerCase() == "am/pm")  { payload += ''; i += 4; break; }
					/* falls through */
				default: console.error("unrecognized character " + c + " in ODF format " + nf);
			}
			break j;
		}
		/* currency flag */
		if(nf.indexOf(/\$/) > -1) { type = "currency"; }
		/* should be in a char loop */
		if(nf[0] == "$") { payload += '$'; nf = nf.slice(1); i = 0; }
		i = 0; if(nf[i] == '"') {
			while(nf[++i] != '"' || nf[++i] == '"') c += nf[i]; --i;
			if(nf[i+1] == "*") {
				i++;
				payload += '' + escapexml(c.replace(/""/g, '"')) + '';
			} else {
				payload += '' + escapexml(c.replace(/""/g, '"')) + '';
			}
			nf = nf.slice(i+1); i = 0;
		}
		/* number TODO: interstitial text e.g. 000)000-0000 */
		var np = nf.match(/([#0][0#,]*)(\.[0#]*|)(E[+]?0*|)/i);
		if(!np || !np[0]) console.error("Could not find numeric part of " + nf);
		else {
			var base = np[1].replace(/,/g, "");
			payload += ' -1 ? ' number:grouping="true"' : "") +
				(np[2] && ' number:decimal-places="' + (np[2].length - 1) + '"' || ' number:decimal-places="0"') +
				(np[3] && np[3].indexOf("+") > -1 ? ' number:forced-exponent-sign="true"' : "" ) +
				(np[3] ? ' number:min-exponent-digits="' + np[3].match(/0+/)[0].length + '"' : "" ) +
				'>' +
				/* TODO: interstitial text placeholders */
				'';
			i = np.index + np[0].length;
		}
		/* residual text */
		if(nf[i] == '"') {
			c = "";
			while(nf[++i] != '"' || nf[++i] == '"') c += nf[i]; --i;
			payload += '' + escapexml(c.replace(/""/g, '"')) + '';
		}
	}
	if(!payload) { console.error("Could not generate ODS number format for |" + nf + "|"); return ""; }
	return writextag("number:" + type + "-style", payload, nopts);
}
function write_names_ods(Names, SheetNames, idx) {
	//var scoped = Names.filter(function(name) { return name.Sheet == (idx == -1 ? null : idx); });
	var scoped = []; for(var namei = 0; namei < Names.length; ++namei) {
		var name = Names[namei];
		if(!name) continue;
		if(name.Sheet == (idx == -1 ? null : idx)) scoped.push(name);
	}
	if(!scoped.length) return "";
	return "      \n" + scoped.map(function(name) {
		var odsref =  (idx == -1 ? "$" : "") + csf_to_ods_3D(name.Ref);
		return "        " + writextag("table:named-range", null, {
			"table:name": name.Name,
			"table:cell-range-address": odsref,
			"table:base-cell-address": odsref.replace(/[\.][^\.]*$/, ".$A$1")
		});
	}).join("\n") + "\n      \n";
}
var write_content_ods/*:{(wb:any, opts:any):string}*/ = /* @__PURE__ */(function() {
	/* 6.1.2 White Space Characters */
	var write_text_p = function(text/*:string*/, span)/*:string*/ {
		return escapexml(text)
			.replace(/  +/g, function($$){return '';})
			.replace(/\t/g, "")
			.replace(/\n/g, span ? "": "")
			.replace(/^ /, "").replace(/ $/, "");
	};
	var null_cell_xml = '          \n';
	var write_ws = function(ws, wb/*:Workbook*/, i/*:number*/, opts, nfs, date1904)/*:string*/ {
		/* Section 9 Tables */
		var o/*:Array*/ = [];
		o.push('      \n');
		var R=0,C=0, range = decode_range(ws['!ref']||"A1");
		var marr/*:Array*/ = ws['!merges'] || [], mi = 0;
		var dense = ws["!data"] != null;
		if(ws["!cols"]) {
			for(C = 0; C <= range.e.c; ++C) o.push('        \n');
		}
		var H = "", ROWS = ws["!rows"]||[];
		for(R = 0; R < range.s.r; ++R) {
			H = ROWS[R] ? ' table:style-name="ro' + ROWS[R].ods + '"' : "";
			o.push('        \n');
		}
		for(; R <= range.e.r; ++R) {
			H = ROWS[R] ? ' table:style-name="ro' + ROWS[R].ods + '"' : "";
			o.push('        \n');
			for(C=0; C < range.s.c; ++C) o.push(null_cell_xml);
			for(; C <= range.e.c; ++C) {
				var skip = false, ct = {}, textp = "";
				for(mi = 0; mi != marr.length; ++mi) {
					if(marr[mi].s.c > C) continue;
					if(marr[mi].s.r > R) continue;
					if(marr[mi].e.c < C) continue;
					if(marr[mi].e.r < R) continue;
					if(marr[mi].s.c != C || marr[mi].s.r != R) skip = true;
					ct['table:number-columns-spanned'] = (marr[mi].e.c - marr[mi].s.c + 1);
					ct['table:number-rows-spanned'] =    (marr[mi].e.r - marr[mi].s.r + 1);
					break;
				}
				if(skip) { o.push('          \n'); continue; }
				var ref = encode_cell({r:R, c:C}), cell = dense ? (ws["!data"][R]||[])[C]: ws[ref];
				if(cell && cell.f) {
					ct['table:formula'] = escapexml(csf_to_ods_formula(cell.f));
					if(cell.F) {
						if(cell.F.slice(0, ref.length) == ref) {
							var _Fref = decode_range(cell.F);
							ct['table:number-matrix-columns-spanned'] = (_Fref.e.c - _Fref.s.c + 1);
							ct['table:number-matrix-rows-spanned'] =    (_Fref.e.r - _Fref.s.r + 1);
						}
					}
				}
				if(!cell) { o.push(null_cell_xml); continue; }
				switch(cell.t) {
					case 'b':
						textp = (cell.v ? 'TRUE' : 'FALSE');
						ct['office:value-type'] = "boolean";
						ct['office:boolean-value'] = (cell.v ? 'true' : 'false');
						break;
					case 'n':
						if(!isFinite(cell.v)) {
							if(isNaN(cell.v)) {
								textp = "#NUM!";
								ct['table:formula'] = "of:=#NUM!";
							} else {
								textp = "#DIV/0!";
								ct['table:formula'] = "of:=" + (cell.v < 0 ? "-" : "") + "1/0";
							}
							ct['office:string-value'] = "";
							ct['office:value-type'] = "string";
							ct['calcext:value-type'] = "error";
						} else {
							textp = (cell.w||String(cell.v||0));
							ct['office:value-type'] = "float";
							ct['office:value'] = (cell.v||0);
						}
						break;
					case 's': case 'str':
						textp = cell.v == null ? "" : cell.v;
						ct['office:value-type'] = "string";
						break;
					case 'd':
						textp = (cell.w||(parseDate(cell.v, date1904).toISOString()));
						ct['office:value-type'] = "date";
						ct['office:date-value'] = (parseDate(cell.v, date1904).toISOString());
						ct['table:style-name'] = "ce1";
						break;
					//case 'e': // TODO: translate to ODS errors
					default: o.push(null_cell_xml); continue; // TODO: empty cell with comments
				}
				var text_p = write_text_p(textp);
				if(cell.l && cell.l.Target) {
					var _tgt = cell.l.Target;
					_tgt = _tgt.charAt(0) == "#" ? "#" + csf_to_ods_3D(_tgt.slice(1)) : _tgt;
					// TODO: choose correct parent path format based on link delimiters
					if(_tgt.charAt(0) != "#" && !_tgt.match(/^\w+:/)) _tgt = '../' + _tgt;
					text_p = writextag('text:a', text_p, {'xlink:href': _tgt.replace(/&/g, "&")});
				}
				if(nfs[cell.z]) ct["table:style-name"] = "ce" + nfs[cell.z].slice(1);
				var payload = writextag('text:p', text_p, {});
				if(cell.c) {
					var acreator = "", apayload = "", aprops = {};
					for(var ci = 0; ci < cell.c.length; ++ci) {
						if(!acreator && cell.c[ci].a) acreator = cell.c[ci].a;
						apayload += "" + write_text_p(cell.c[ci].t) + "";
					}
					if(!cell.c.hidden) aprops["office:display"] = true;
					payload = writextag('office:annotation', apayload, aprops) + payload;
				}
				o.push('          ' + writextag('table:table-cell', payload, ct) + '\n');
			}
			o.push('        \n');
		}
		if((wb.Workbook||{}).Names) o.push(write_names_ods(wb.Workbook.Names, wb.SheetNames, i));
		o.push('      \n');
		return o.join("");
	};
	var write_automatic_styles_ods = function(o/*:Array*/, wb) {
		o.push(' \n');
		/* column styles */
		var cidx = 0;
		wb.SheetNames.map(function(n) { return wb.Sheets[n]; }).forEach(function(ws) {
			if(!ws) return;
			if(ws["!cols"]) {
				for(var C = 0; C < ws["!cols"].length; ++C) if(ws["!cols"][C]) {
					var colobj = ws["!cols"][C];
					if(colobj.width == null && colobj.wpx == null && colobj.wch == null) continue;
					process_col(colobj);
					colobj.ods = cidx;
					var w = ws["!cols"][C].wpx + "px";
					o.push('  \n');
					o.push('   \n');
					o.push('  \n');
					++cidx;
				}
			}
		});
		/* row styles */
		var ridx = 0;
		wb.SheetNames.map(function(n) { return wb.Sheets[n]; }).forEach(function(ws) {
			if(!ws) return;
			if(ws["!rows"]) {
				for(var R = 0; R < ws["!rows"].length; ++R) if(ws["!rows"][R]) {
					ws["!rows"][R].ods = ridx;
					var h = ws["!rows"][R].hpx + "px";
					o.push('  \n');
					o.push('   \n');
					o.push('  \n');
					++ridx;
				}
			}
		});
		/* table */
		o.push('  \n');
		o.push('   \n');
		o.push('  \n');
		o.push('  \n');
		o.push('   \n');
		o.push('   /\n');
		o.push('   \n');
		o.push('   /\n');
		o.push('   \n');
		o.push('  \n');
		/* number formats, table cells, text */
		var nfs = {};
		var nfi = 69;
		wb.SheetNames.map(function(n) { return wb.Sheets[n]; }).forEach(function(ws) {
			if(!ws) return;
			var dense = (ws["!data"] != null);
			if(!ws["!ref"]) return;
			var range = decode_range(ws["!ref"]);
			for(var R = 0; R <= range.e.r; ++R) for(var C = 0; C <= range.e.c; ++C) {
				var c = dense ? (ws["!data"][R]||[])[C] : ws[encode_cell({r:R,c:C})];
				if(!c || !c.z || c.z.toLowerCase() == "general") continue;
				if(!nfs[c.z]) {
					var out = write_number_format_ods(c.z, "N" + nfi);
					if(out) { nfs[c.z] = "N" + nfi; ++nfi; o.push(out + "\n"); }
				}
			}
		});
		o.push('  \n');
		keys(nfs).forEach(function(nf) {
			o.push('\n');
		});
		/* page-layout */
		o.push(' \n');
		return nfs;
	};
	return function wcx(wb, opts) {
		var o = [XML_HEADER];
		/* 3.1.3.2 */
		var attr = wxt_helper({
			'xmlns:office':       "urn:oasis:names:tc:opendocument:xmlns:office:1.0",
			'xmlns:table':        "urn:oasis:names:tc:opendocument:xmlns:table:1.0",
			'xmlns:style':        "urn:oasis:names:tc:opendocument:xmlns:style:1.0",
			'xmlns:text':         "urn:oasis:names:tc:opendocument:xmlns:text:1.0",
			'xmlns:draw':         "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0",
			'xmlns:fo':           "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0",
			'xmlns:xlink':        "http://www.w3.org/1999/xlink",
			'xmlns:dc':           "http://purl.org/dc/elements/1.1/",
			'xmlns:meta':         "urn:oasis:names:tc:opendocument:xmlns:meta:1.0",
			'xmlns:number':       "urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0",
			'xmlns:presentation': "urn:oasis:names:tc:opendocument:xmlns:presentation:1.0",
			'xmlns:svg':          "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0",
			'xmlns:chart':        "urn:oasis:names:tc:opendocument:xmlns:chart:1.0",
			'xmlns:dr3d':         "urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0",
			'xmlns:math':         "http://www.w3.org/1998/Math/MathML",
			'xmlns:form':         "urn:oasis:names:tc:opendocument:xmlns:form:1.0",
			'xmlns:script':       "urn:oasis:names:tc:opendocument:xmlns:script:1.0",
			'xmlns:ooo':          "http://openoffice.org/2004/office",
			'xmlns:ooow':         "http://openoffice.org/2004/writer",
			'xmlns:oooc':         "http://openoffice.org/2004/calc",
			'xmlns:dom':          "http://www.w3.org/2001/xml-events",
			'xmlns:xforms':       "http://www.w3.org/2002/xforms",
			'xmlns:xsd':          "http://www.w3.org/2001/XMLSchema",
			'xmlns:xsi':          "http://www.w3.org/2001/XMLSchema-instance",
			'xmlns:sheet':        "urn:oasis:names:tc:opendocument:sh33tjs:1.0",
			'xmlns:rpt':          "http://openoffice.org/2005/report",
			'xmlns:of':           "urn:oasis:names:tc:opendocument:xmlns:of:1.2",
			'xmlns:xhtml':        "http://www.w3.org/1999/xhtml",
			'xmlns:grddl':        "http://www.w3.org/2003/g/data-view#",
			'xmlns:tableooo':     "http://openoffice.org/2009/table",
			'xmlns:drawooo':      "http://openoffice.org/2010/draw",
			'xmlns:calcext':      "urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0",
			'xmlns:loext':        "urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0",
			'xmlns:field':        "urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0",
			'xmlns:formx':        "urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0",
			'xmlns:css3t':        "http://www.w3.org/TR/css3-text/",
			'office:version':     "1.2"
		});
		var fods = wxt_helper({
			'xmlns:config':    "urn:oasis:names:tc:opendocument:xmlns:config:1.0",
			'office:mimetype': "application/vnd.oasis.opendocument.spreadsheet"
		});
		if(opts.bookType == "fods") {
			o.push('\n');
			o.push(write_meta_ods().replace(/]*?>/, "").replace(/<\/office:document-meta>/, "") + "\n");
			// TODO: settings (equiv of settings.xml for ODS)
		} else o.push('\n');
		// o.push('  \n');
		var nfs = write_automatic_styles_ods(o, wb);
		o.push('  \n');
		o.push('    \n');
		if(((wb.Workbook||{}).WBProps||{}).date1904) o.push('      \n        \n      \n');
		for(var i = 0; i != wb.SheetNames.length; ++i) o.push(write_ws(wb.Sheets[wb.SheetNames[i]], wb, i, opts, nfs, ((wb.Workbook||{}).WBProps||{}).date1904));
		if((wb.Workbook||{}).Names) o.push(write_names_ods(wb.Workbook.Names, wb.SheetNames, -1));
		o.push('    \n');
		o.push('  \n');
		if(opts.bookType == "fods") o.push('');
		else o.push('');
		return o.join("");
	};
})();
function write_ods(wb/*:any*/, opts/*:any*/) {
	if(opts.bookType == "fods") return write_content_ods(wb, opts);
	var zip = zip_new();
	var f = "";
	var manifest/*:Array >*/ = [];
	var rdf/*:Array<[string, string]>*/ = [];
	/* Part 3 Section 3.3 MIME Media Type */
	f = "mimetype";
	zip_add_file(zip, f, "application/vnd.oasis.opendocument.spreadsheet");
	/* Part 1 Section 2.2 Documents */
	f = "content.xml";
	zip_add_file(zip, f, write_content_ods(wb, opts));
	manifest.push([f, "text/xml"]);
	rdf.push([f, "ContentFile"]);
	/* TODO: these are hard-coded styles to satiate excel */
	f = "styles.xml";
	zip_add_file(zip, f, write_styles_ods(wb, opts));
	manifest.push([f, "text/xml"]);
	rdf.push([f, "StylesFile"]);
	/* TODO: this is hard-coded to satiate excel */
	f = "meta.xml";
	zip_add_file(zip, f, XML_HEADER + write_meta_ods(/*::wb, opts*/));
	manifest.push([f, "text/xml"]);
	rdf.push([f, "MetadataFile"]);
	/* Part 3 Section 6 Metadata Manifest File */
	f = "manifest.rdf";
	zip_add_file(zip, f, write_rdf(rdf/*, opts*/));
	manifest.push([f, "application/rdf+xml"]);
	/* Part 3 Section 4 Manifest File */
	f = "META-INF/manifest.xml";
	zip_add_file(zip, f, write_manifest(manifest/*, opts*/));
	return zip;
}