diff --git a/src/components/App.tsx b/src/components/App.tsx index 1a86f7658..c1ef8d6ef 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -152,22 +152,34 @@ export default class App extends React.Component { console.log("WARNING: ExceLint does not work on protected spreadsheets. Please unprotect the sheet and try again."); return; } - + + let backupName = this.saved_original_sheetname(currentWorksheet.id); // If it's there already, restore it. try { let backupSheet = worksheets.getItemOrNullObject(backupName); if (backupSheet) { + // Get the current used range. let destRange = currentWorksheet.getUsedRange(false) as any; -// let destRange = currentWorksheet.getRange("A1") as any; + + // Clear all formatting. + destRange.load(['format']); + await context.sync(); + destRange.format.fill.clear(); + + await context.sync(); + // Now get the used range again. + destRange = currentWorksheet.getUsedRange(false) as any; + + // Grab the backup sheet info. backupSheet.load(['format', 'address']); - let usedRange = backupSheet.getUsedRange(false) as any; - usedRange.load(['address']); + let backupSheetUsedRange = backupSheet.getUsedRange(false) as any; + backupSheetUsedRange.load(['address']); await context.sync(); - console.log("copying out " + JSON.stringify(usedRange.address)); - // destRange.copyFrom(usedRange, Excel.RangeCopyType.formats); // FIX ME FIXME WAS THIS - destRange.copyFrom(usedRange, Excel.RangeCopyType.all); // used for restoring VALUES FIXME NOT NEEDED IN GENERAL + console.log("copying out " + JSON.stringify(backupSheetUsedRange.address)); + // destRange.copyFrom(backupSheetUsedRange, Excel.RangeCopyType.formats); // FIX ME FIXME WAS THIS + destRange.copyFrom(backupSheetUsedRange, Excel.RangeCopyType.all); // used for restoring VALUES FIXME NOT NEEDED IN GENERAL await context.sync(); } else { console.log("restoreFormats: didn't find the sheet " + backupName); @@ -379,7 +391,8 @@ export default class App extends React.Component { await setTimeout(() => {}, 0); t.split("processed formulas"); - let refs = Colorize.generate_all_references(formulas); + console.log("UPPER LEFT CORNER = " + JSON.stringify(upperLeftCorner)); + let refs = ExcelUtils.generate_all_references(formulas); t.split("generated all references"); await setTimeout(() => {}, 0); let processed_data = Colorize.color_all_data(refs); diff --git a/src/components/colorize.js b/src/components/colorize.js index c53be4fbd..39a17988d 100644 --- a/src/components/colorize.js +++ b/src/components/colorize.js @@ -1,4 +1,30 @@ "use strict"; +var __values = (this && this.__values) || function (o) { + var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0; + if (m) return m.call(o); + return { + next: function () { + if (o && i >= o.length) o = void 0; + return { value: o && o[i++], done: !o }; + } + }; +}; +var __read = (this && this.__read) || function (o, n) { + var m = typeof Symbol === "function" && o[Symbol.iterator]; + if (!m) return o; + var i = m.call(o), r, ar = [], e; + try { + while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); + } + catch (error) { e = { error: error }; } + finally { + try { + if (r && !r.done && (m = i["return"])) m.call(i); + } + finally { if (e) throw e.error; } + } + return ar; +}; exports.__esModule = true; var colorutils_1 = require("./colorutils"); var excelutils_1 = require("./excelutils"); @@ -9,12 +35,22 @@ var Colorize = /** @class */ (function () { function Colorize() { } Colorize.initialize = function () { + var e_1, _a; if (!this.initialized) { this.make_light_color_versions(); - for (var _i = 0, _a = Object.keys(this.light_color_dict); _i < _a.length; _i++) { - var i = _a[_i]; - this.color_list.push(i); - this.light_color_list.push(this.light_color_dict[i]); + try { + for (var _b = __values(Object.keys(this.light_color_dict)), _c = _b.next(); !_c.done; _c = _b.next()) { + var i = _c.value; + this.color_list.push(i); + this.light_color_list.push(this.light_color_dict[i]); + } + } + catch (e_1_1) { e_1 = { error: e_1_1 }; } + finally { + try { + if (_c && !_c.done && (_a = _b["return"])) _a.call(_b); + } + finally { if (e_1) throw e_1.error; } } this.initialized = true; } @@ -26,7 +62,7 @@ var Colorize = /** @class */ (function () { }; Colorize.is_banned_color = function (h, s, v) { var ban_it = false; - var _a = colorutils_1.ColorUtils.HSVtoRGB(h, s, v), r = _a[0], g = _a[1], b = _a[2]; + var _a = __read(colorutils_1.ColorUtils.HSVtoRGB(h, s, v), 3), r = _a[0], g = _a[1], b = _a[2]; if ((r > 128) && (g < 128) && (b < 128)) { // Too red. ban_it = true; @@ -65,7 +101,7 @@ var Colorize = /** @class */ (function () { continue; } var rgb = colorutils_1.ColorUtils.HSVtoRGB(h, s, v); - var _a = rgb.map(function (x) { return Math.round(x).toString(16).padStart(2, '0'); }), rs = _a[0], gs = _a[1], bs = _a[2]; + var _a = __read(rgb.map(function (x) { return Math.round(x).toString(16).padStart(2, '0'); }), 3), rs = _a[0], gs = _a[1], bs = _a[2]; var str = '#' + rs + gs + bs; str = str.toUpperCase(); this.light_color_dict[str] = ''; @@ -90,43 +126,66 @@ var Colorize = /** @class */ (function () { Colorize.process_formulas = function (formulas, origin_col, origin_row) { var lastHash = 0; var lastHashString = lastHash.toString(); + var all_deps = {}; + var reducer = function (acc, curr) { return [acc[0] + curr[0], acc[1] + curr[1]]; }; var output = []; - // Build up all of the columns of colors. - for (var i = 0; i < formulas.length; i++) { + var _loop_1 = function (i) { var row = formulas[i]; - // console.log("process_formulas: formulas[" + i + "] = " + JSON.stringify(row)); - for (var j = 0; j < row.length; j++) { + var _loop_2 = function (j) { if ((row[j].length > 0) && (row[j][0] === '=')) { var cell = row[j]; // console.log("process_formulas: i = " + i + ", j = " + j); // console.log("process_formulas: origin_col, row = " + origin_col + ", " + origin_row); // console.log("process_formulas: row = " + JSON.stringify(cell)); - var vec = excelutils_1.ExcelUtils.dependencies(cell, j + origin_col + 1, i + origin_row + 1); - if (vec[0] === 0 && vec[1] === 0) { + // let vec = ExcelUtils.dependencies(cell, j + origin_col + 1, i + origin_row + 1); + console.log("about to check " + i + ", " + j); + var vec_array = excelutils_1.ExcelUtils.transitive_closure(i, j, origin_row, origin_col, formulas, all_deps); + console.log("vec_array WAS = " + JSON.stringify(vec_array)); + vec_array = vec_array.map(function (x) { return [x[1] - i - 1, x[0] - j - 1]; }); + console.log("RELATIVE transitive closure of " + i + ", " + j + " (vec_array) NOW = " + JSON.stringify(vec_array) + " (i = " + i + ", j = " + j + ", origin_row = " + origin_row + ", origin_col = " + origin_col + ")"); + if (vec_array.length == 0) { // No dependencies! Use a distinguished "0" value (always the same color?). output.push([[j + origin_col + 1, i + origin_row + 1], "0"]); } else { - // console.log("process_formulas: vector = " + JSON.stringify(vec)); - var hash = this.hash_vector(vec); - var str = ""; - if (hash == lastHash) { + var vec = vec_array.reduce(reducer); + console.log("vec = " + JSON.stringify(vec)); + if (vec[0] === 0 && vec[1] === 0) { + // No dependencies! Use a distinguished "0" value (always the same color?). + output.push([[j + origin_col + 1, i + origin_row + 1], "0"]); } else { - lastHash = hash; - lastHashString = hash.toString(); + // console.log("process_formulas: vector = " + JSON.stringify(vec)); + var hash = this_1.hash_vector(vec); + var str = ""; + if (hash == lastHash) { + } + else { + lastHash = hash; + lastHashString = hash.toString(); + } + str = lastHashString; + // console.log("process_formulas: hash of this vector = " + hash); + output.push([[j + origin_col + 1, i + origin_row + 1], str]); } - str = lastHashString; - // console.log("process_formulas: hash of this vector = " + hash); - output.push([[j + origin_col + 1, i + origin_row + 1], str]); } } + }; + // console.log("process_formulas: formulas[" + i + "] = " + JSON.stringify(row)); + for (var j = 0; j < row.length; j++) { + _loop_2(j); } + }; + var this_1 = this; + // Build up all of the columns of colors. + for (var i = 0; i < formulas.length; i++) { + _loop_1(i); } return output; }; // public static color_all_data(formulas: Array>, processed_formulas: Array<[[number, number], string]>) { Colorize.color_all_data = function (refs) { + var e_2, _a; var t = new timer_1.Timer("color_all_data"); //console.log('color_all_data'); //console.log("formula length = " + formulas.length); @@ -136,13 +195,22 @@ var Colorize = /** @class */ (function () { //console.log("generated all references: length = " + Object.keys(refs).length); // console.log("all refs = " + JSON.stringify(refs)); var processed_data = []; - for (var _i = 0, _a = Object.keys(refs); _i < _a.length; _i++) { - var refvec = _a[_i]; - // let rv = JSON.parse('[' + refvec + ']'); - var rv = refvec.split(','); - var row = Number(rv[0]); - var col = Number(rv[1]); - processed_data.push([[row, col], 1]); + try { + for (var _b = __values(Object.keys(refs)), _c = _b.next(); !_c.done; _c = _b.next()) { + var refvec = _c.value; + // let rv = JSON.parse('[' + refvec + ']'); + var rv = refvec.split(','); + var row = Number(rv[0]); + var col = Number(rv[1]); + processed_data.push([[row, col], 1]); + } + } + catch (e_2_1) { e_2 = { error: e_2_1 }; } + finally { + try { + if (_c && !_c.done && (_a = _b["return"])) _a.call(_b); + } + finally { if (e_2) throw e_2.error; } } t.split("processed all data"); // console.log("color_all_data: processed_data = " + JSON.stringify(processed_data)); @@ -151,23 +219,43 @@ var Colorize = /** @class */ (function () { // Take in a list of [[row, col], color] pairs and group them, // sorting them (e.g., by columns). Colorize.identify_ranges = function (list, sortfn) { + var e_3, _a, e_4, _b; // Separate into groups based on their string value. var groups = {}; - for (var _i = 0, list_1 = list; _i < list_1.length; _i++) { - var r = list_1[_i]; - groups[r[1]] = groups[r[1]] || []; - groups[r[1]].push(r[0]); + try { + for (var list_1 = __values(list), list_1_1 = list_1.next(); !list_1_1.done; list_1_1 = list_1.next()) { + var r = list_1_1.value; + groups[r[1]] = groups[r[1]] || []; + groups[r[1]].push(r[0]); + } + } + catch (e_3_1) { e_3 = { error: e_3_1 }; } + finally { + try { + if (list_1_1 && !list_1_1.done && (_a = list_1["return"])) _a.call(list_1); + } + finally { if (e_3) throw e_3.error; } + } + try { + // Now sort them all. + for (var _c = __values(Object.keys(groups)), _d = _c.next(); !_d.done; _d = _c.next()) { + var k = _d.value; + // console.log(k); + groups[k].sort(sortfn); + // console.log(groups[k]); + } } - // Now sort them all. - for (var _a = 0, _b = Object.keys(groups); _a < _b.length; _a++) { - var k = _b[_a]; - // console.log(k); - groups[k].sort(sortfn); - // console.log(groups[k]); + catch (e_4_1) { e_4 = { error: e_4_1 }; } + finally { + try { + if (_d && !_d.done && (_b = _c["return"])) _b.call(_c); + } + finally { if (e_4) throw e_4.error; } } return groups; }; Colorize.group_ranges = function (groups, columnFirst) { + var e_5, _a, e_6, _b; var output = {}; var index0 = 0; // column var index1 = 1; // row @@ -175,24 +263,42 @@ var Colorize = /** @class */ (function () { index0 = 1; // row index1 = 0; // column } - for (var _i = 0, _a = Object.keys(groups); _i < _a.length; _i++) { - var k = _a[_i]; - output[k] = []; - var prev = groups[k].shift(); - var last = prev; - for (var _b = 0, _c = groups[k]; _b < _c.length; _b++) { - var v = _c[_b]; - // Check if in the same column, adjacent row (if columnFirst; otherwise, vice versa). - if ((v[index0] === last[index0]) && (v[index1] === last[index1] + 1)) { - last = v; + try { + for (var _c = __values(Object.keys(groups)), _d = _c.next(); !_d.done; _d = _c.next()) { + var k = _d.value; + output[k] = []; + var prev = groups[k].shift(); + var last = prev; + try { + for (var _e = __values(groups[k]), _f = _e.next(); !_f.done; _f = _e.next()) { + var v = _f.value; + // Check if in the same column, adjacent row (if columnFirst; otherwise, vice versa). + if ((v[index0] === last[index0]) && (v[index1] === last[index1] + 1)) { + last = v; + } + else { + output[k].push([prev, last]); + prev = v; + last = v; + } + } } - else { - output[k].push([prev, last]); - prev = v; - last = v; + catch (e_6_1) { e_6 = { error: e_6_1 }; } + finally { + try { + if (_f && !_f.done && (_b = _e["return"])) _b.call(_e); + } + finally { if (e_6) throw e_6.error; } } + output[k].push([prev, last]); } - output[k].push([prev, last]); + } + catch (e_5_1) { e_5 = { error: e_5_1 }; } + finally { + try { + if (_d && !_d.done && (_a = _c["return"])) _a.call(_c); + } + finally { if (e_5) throw e_5.error; } } return output; }; @@ -261,48 +367,77 @@ var Colorize = /** @class */ (function () { return count; }; Colorize.generate_proposed_fixes = function (groups, diagonal, area) { + var e_7, _a, e_8, _b; var proposed_fixes = []; var already_proposed_pair = {}; - for (var _i = 0, _a = Object.keys(groups); _i < _a.length; _i++) { - var k1 = _a[_i]; - // Look for possible fixes in OTHER groups. - for (var i = 0; i < groups[k1].length; i++) { - var r1 = groups[k1][i]; - var sr1 = JSON.stringify(r1); - for (var _b = 0, _c = Object.keys(groups); _b < _c.length; _b++) { - var k2 = _c[_b]; - if (k1 === k2) { - continue; - } - for (var j = 0; j < groups[k2].length; j++) { - var r2 = groups[k2][j]; - var sr2 = JSON.stringify(r2); - // Only add these if we have not already added them. - if (!(sr1 + sr2 in already_proposed_pair) && !(sr2 + sr1 in already_proposed_pair)) { - // If both are compatible rectangles AND the regions include more than two cells, propose them as fixes. - if (rectangleutils_1.RectangleUtils.is_mergeable(r1, r2) && (rectangleutils_1.RectangleUtils.area(r1) + rectangleutils_1.RectangleUtils.area(r2) > 2)) { - already_proposed_pair[sr1 + sr2] = true; - already_proposed_pair[sr2 + sr1] = true; - /// console.log("generate_proposed_fixes: could merge (" + k1 + ") " + JSON.stringify(groups[k1][i]) + " and (" + k2 + ") " + JSON.stringify(groups[k2][j])); - var metric = this.fix_metric(parseFloat(k1), r1, parseFloat(k2), r2, diagonal, area); - // was Math.abs(parseFloat(k2) - parseFloat(k1)) - proposed_fixes.push([metric, r1, r2]); + try { + for (var _c = __values(Object.keys(groups)), _d = _c.next(); !_d.done; _d = _c.next()) { + var k1 = _d.value; + // Look for possible fixes in OTHER groups. + for (var i = 0; i < groups[k1].length; i++) { + var r1 = groups[k1][i]; + var sr1 = JSON.stringify(r1); + try { + for (var _e = __values(Object.keys(groups)), _f = _e.next(); !_f.done; _f = _e.next()) { + var k2 = _f.value; + if (k1 === k2) { + continue; + } + for (var j = 0; j < groups[k2].length; j++) { + var r2 = groups[k2][j]; + var sr2 = JSON.stringify(r2); + // Only add these if we have not already added them. + if (!(sr1 + sr2 in already_proposed_pair) && !(sr2 + sr1 in already_proposed_pair)) { + // If both are compatible rectangles AND the regions include more than two cells, propose them as fixes. + if (rectangleutils_1.RectangleUtils.is_mergeable(r1, r2) && (rectangleutils_1.RectangleUtils.area(r1) + rectangleutils_1.RectangleUtils.area(r2) > 2)) { + already_proposed_pair[sr1 + sr2] = true; + already_proposed_pair[sr2 + sr1] = true; + /// console.log("generate_proposed_fixes: could merge (" + k1 + ") " + JSON.stringify(groups[k1][i]) + " and (" + k2 + ") " + JSON.stringify(groups[k2][j])); + var metric = this.fix_metric(parseFloat(k1), r1, parseFloat(k2), r2, diagonal, area); + // was Math.abs(parseFloat(k2) - parseFloat(k1)) + proposed_fixes.push([metric, r1, r2]); + } + } } } } + catch (e_8_1) { e_8 = { error: e_8_1 }; } + finally { + try { + if (_f && !_f.done && (_b = _e["return"])) _b.call(_e); + } + finally { if (e_8) throw e_8.error; } + } } } } + catch (e_7_1) { e_7 = { error: e_7_1 }; } + finally { + try { + if (_d && !_d.done && (_a = _c["return"])) _a.call(_c); + } + finally { if (e_7) throw e_7.error; } + } // First attribute is the Euclidean norm of the vectors. Differencing corresponds roughly to earth-mover distance. // Other attributes are the rectangles themselves. Sort by biggest entropy reduction first. proposed_fixes.sort(function (a, b) { return a[0] - b[0]; }); return proposed_fixes; }; Colorize.merge_groups = function (groups) { - for (var _i = 0, _a = Object.keys(groups); _i < _a.length; _i++) { - var k = _a[_i]; - var g = groups[k].slice(); - groups[k] = this.merge_individual_groups(g); // JSON.parse(JSON.stringify(groups[k]))); + var e_9, _a; + try { + for (var _b = __values(Object.keys(groups)), _c = _b.next(); !_c.done; _c = _b.next()) { + var k = _c.value; + var g = groups[k].slice(); + groups[k] = this.merge_individual_groups(g); // JSON.parse(JSON.stringify(groups[k]))); + } + } + catch (e_9_1) { e_9 = { error: e_9_1 }; } + finally { + try { + if (_c && !_c.done && (_a = _b["return"])) _a.call(_b); + } + finally { if (e_9) throw e_9.error; } } return groups; }; @@ -352,33 +487,6 @@ var Colorize = /** @class */ (function () { } } }; - Colorize.generate_all_references = function (formulas) { - // Generate all references. - var refs = {}; - var counter = 0; - for (var i = 0; i < formulas.length; i++) { - var row = formulas[i]; - for (var j = 0; j < row.length; j++) { - var cell = row[j]; - counter++; - if (counter % 1000 == 0) { - console.log(counter + " references down"); - } - // console.log('origin_col = '+origin_col+', origin_row = ' + origin_row); - if (cell[0] === '=') { - var all_deps = excelutils_1.ExcelUtils.all_cell_dependencies(cell); // , origin_col + j, origin_row + i); - for (var _i = 0, all_deps_1 = all_deps; _i < all_deps_1.length; _i++) { - var dep = all_deps_1[_i]; - var key = dep.join(','); - refs[key] = true; // refs[key] || []; - // NOTE: we are disabling pushing the src onto the list because we don't need it. - // refs[dep2.join(',')].push(src); - } - } - } - } - return refs; - }; Colorize.hash_vector = function (vec) { var baseX = 0; // was 7; var baseY = 0; // was 3; diff --git a/src/components/colorize.ts b/src/components/colorize.ts index 2271cf478..d763a088a 100644 --- a/src/components/colorize.ts +++ b/src/components/colorize.ts @@ -105,7 +105,9 @@ export class Colorize { public static process_formulas(formulas: Array>, origin_col: number, origin_row: number): Array<[[number, number], string]> { let lastHash = 0; let lastHashString = lastHash.toString(); - let output: Array<[[number, number], string]> = []; + let all_deps = {}; + let reducer = (acc:[number,number],curr:[number,number]) : [number,number] => [acc[0] + curr[0], acc[1] + curr[1]]; + let output: Array<[[number, number], string]> = []; // Build up all of the columns of colors. for (let i = 0; i < formulas.length; i++) { let row = formulas[i]; @@ -118,28 +120,40 @@ export class Colorize { // console.log("process_formulas: i = " + i + ", j = " + j); // console.log("process_formulas: origin_col, row = " + origin_col + ", " + origin_row); // console.log("process_formulas: row = " + JSON.stringify(cell)); - let vec = ExcelUtils.dependencies(cell, j + origin_col + 1, i + origin_row + 1); - if (vec[0] === 0 && vec[1] === 0) { + // let vec = ExcelUtils.dependencies(cell, j + origin_col + 1, i + origin_row + 1); + console.log("about to check " + i + ", " + j); + let vec_array = ExcelUtils.transitive_closure(i, j, origin_row, origin_col, formulas, all_deps); + console.log("vec_array WAS = " + JSON.stringify(vec_array)); + vec_array = vec_array.map((x) => [x[1] - i - 1, x[0] - j - 1]); + console.log("RELATIVE transitive closure of " + i + ", " + j + " (vec_array) NOW = " + JSON.stringify(vec_array) + " (i = " + i + ", j = " + j + ", origin_row = " + origin_row + ", origin_col = " + origin_col + ")"); + if (vec_array.length == 0) { // No dependencies! Use a distinguished "0" value (always the same color?). output.push([[j + origin_col + 1, i + origin_row + 1], "0"]); } else { -// console.log("process_formulas: vector = " + JSON.stringify(vec)); - let hash = this.hash_vector(vec); - let str = ""; - if (hash == lastHash) { + let vec = vec_array.reduce(reducer); + console.log("vec = " + JSON.stringify(vec)); + if (vec[0] === 0 && vec[1] === 0) { + // No dependencies! Use a distinguished "0" value (always the same color?). + output.push([[j + origin_col + 1, i + origin_row + 1], "0"]); } else { - lastHash = hash; - lastHashString = hash.toString(); - } - str = lastHashString; -// console.log("process_formulas: hash of this vector = " + hash); + // console.log("process_formulas: vector = " + JSON.stringify(vec)); + let hash = this.hash_vector(vec); + let str = ""; + if (hash == lastHash) { + } else { + lastHash = hash; + lastHashString = hash.toString(); + } + str = lastHashString; + // console.log("process_formulas: hash of this vector = " + hash); output.push([[j + origin_col + 1, i + origin_row + 1], str]); + } } - } + } } } - return output; - } + return output; + } // public static color_all_data(formulas: Array>, processed_formulas: Array<[[number, number], string]>) { @@ -384,35 +398,6 @@ export class Colorize { } } - public static generate_all_references(formulas: Array>): { [dep: string]: Array<[number, number]> } { - // Generate all references. - let refs = {}; - let counter = 0; - for (let i = 0; i < formulas.length; i++) { - let row = formulas[i]; - for (let j = 0; j < row.length; j++) { - let cell = row[j]; - counter++; - if (counter % 1000 == 0) { - console.log(counter + " references down"); - } - - // console.log('origin_col = '+origin_col+', origin_row = ' + origin_row); - if (cell[0] === '=') { - let all_deps = ExcelUtils.all_cell_dependencies(cell); // , origin_col + j, origin_row + i); - for (let dep of all_deps) { - let key = dep.join(','); - refs[key] = true; // refs[key] || []; - // NOTE: we are disabling pushing the src onto the list because we don't need it. - // refs[dep2.join(',')].push(src); - } - } - } - } - return refs; - } - - public static hash_vector(vec: Array): number { let baseX = 0; // was 7; let baseY = 0; // was 3; diff --git a/src/components/colorutils.js b/src/components/colorutils.js index a3aef9bf7..3d42364ee 100644 --- a/src/components/colorutils.js +++ b/src/components/colorutils.js @@ -1,5 +1,21 @@ "use strict"; // colorutils +var __read = (this && this.__read) || function (o, n) { + var m = typeof Symbol === "function" && o[Symbol.iterator]; + if (!m) return o; + var i = m.call(o), r, ar = [], e; + try { + while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); + } + catch (error) { e = { error: error }; } + finally { + try { + if (r && !r.done && (m = i["return"])) m.call(i); + } + finally { if (e) throw e.error; } + } + return ar; +}; exports.__esModule = true; var ColorUtils = /** @class */ (function () { function ColorUtils() { @@ -82,8 +98,8 @@ var ColorUtils = /** @class */ (function () { }; ColorUtils.adjust_brightness = function (color, multiplier) { var c = ColorUtils.rgb_ex.exec(color); - var _a = [parseInt(c[1], 16), parseInt(c[2], 16), parseInt(c[3], 16)], r = _a[0], g = _a[1], b = _a[2]; - var _b = ColorUtils.RGBtoHSV(r, g, b), h = _b[0], s = _b[1], v = _b[2]; + var _a = __read([parseInt(c[1], 16), parseInt(c[2], 16), parseInt(c[3], 16)], 3), r = _a[0], g = _a[1], b = _a[2]; + var _b = __read(ColorUtils.RGBtoHSV(r, g, b), 3), h = _b[0], s = _b[1], v = _b[2]; v = multiplier * v; if (v <= 0.0) { v = 0.0; @@ -92,7 +108,7 @@ var ColorUtils = /** @class */ (function () { v = 0.99; } var rgb = ColorUtils.HSVtoRGB(h, s, v); - var _c = rgb.map(function (x) { return Math.round(x).toString(16).padStart(2, '0'); }), rs = _c[0], gs = _c[1], bs = _c[2]; + var _c = __read(rgb.map(function (x) { return Math.round(x).toString(16).padStart(2, '0'); }), 3), rs = _c[0], gs = _c[1], bs = _c[2]; var str = '#' + rs + gs + bs; str = str.toUpperCase(); return str; diff --git a/src/components/excelutils.js b/src/components/excelutils.js index b565af1c4..c90468f48 100644 --- a/src/components/excelutils.js +++ b/src/components/excelutils.js @@ -1,5 +1,35 @@ "use strict"; // excel-utils +var __values = (this && this.__values) || function (o) { + var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0; + if (m) return m.call(o); + return { + next: function () { + if (o && i >= o.length) o = void 0; + return { value: o && o[i++], done: !o }; + } + }; +}; +var __read = (this && this.__read) || function (o, n) { + var m = typeof Symbol === "function" && o[Symbol.iterator]; + if (!m) return o; + var i = m.call(o), r, ar = [], e; + try { + while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); + } + catch (error) { e = { error: error }; } + finally { + try { + if (r && !r.done && (m = i["return"])) m.call(i); + } + finally { if (e) throw e.error; } + } + return ar; +}; +var __spread = (this && this.__spread) || function () { + for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); + return ar; +}; exports.__esModule = true; var sjcl = require("sjcl"); var rectangleutils_js_1 = require("./rectangleutils.js"); @@ -34,15 +64,25 @@ var ExcelUtils = /** @class */ (function () { }; // Convert an Excel column name (a string of alphabetical charcaters) into a number. ExcelUtils.column_name_to_index = function (name) { + var e_1, _a; if (name.length === 1) { // optimizing for the overwhelmingly common case return name[0].charCodeAt(0) - 'A'.charCodeAt(0) + 1; } var value = 0; var split_name = name.split(''); - for (var _i = 0, split_name_1 = split_name; _i < split_name_1.length; _i++) { - var i = split_name_1[_i]; - value *= 26; - value += (i.charCodeAt(0) - 'A'.charCodeAt(0)) + 1; + try { + for (var split_name_1 = __values(split_name), split_name_1_1 = split_name_1.next(); !split_name_1_1.done; split_name_1_1 = split_name_1.next()) { + var i = split_name_1_1.value; + value *= 26; + value += (i.charCodeAt(0) - 'A'.charCodeAt(0)) + 1; + } + } + catch (e_1_1) { e_1 = { error: e_1_1 }; } + finally { + try { + if (split_name_1_1 && !split_name_1_1.done && (_a = split_name_1["return"])) _a.call(split_name_1); + } + finally { if (e_1) throw e_1.error; } } return value; }; @@ -226,6 +266,141 @@ var ExcelUtils = /** @class */ (function () { } return base_vector; }; + ExcelUtils.transitive_closure = function (row, col, origin_row, origin_col, formulas, all_deps) { + var e_2, _a; + console.log("tc1: transitive closure of " + row + ", " + col + ", origin_row = " + origin_row + ", origin_col = " + origin_col); + var index = row * formulas[0].length + col; + // console.log("index = " + index); + if (index in all_deps) { + // We already processed this index: return it. + return all_deps[index]; + } + // console.log("tc2"); + console.log("formulas[" + row + "][" + col + "]"); + if ((row >= formulas.length) || (col >= formulas[0].length)) { + // Discard references to cells outside the formula range. + return []; + } + var cell = formulas[row][col]; + console.log("formulas[" + row + "][" + col + "] = " + cell); + if (cell.length <= 1 || cell[0] !== "=") { + // Not a formula -- no dependencies. + return []; + } + // console.log("tc3: cell = " + cell); + var deps = ExcelUtils.all_cell_dependencies(cell); + if (deps.length >= 1) { + var tcs = deps; + console.log("cell deps = " + JSON.stringify(tcs)); + try { + for (var deps_1 = __values(deps), deps_1_1 = deps_1.next(); !deps_1_1.done; deps_1_1 = deps_1.next()) { + var dep = deps_1_1.value; + dep[0] -= origin_col; + // dep[0] -= 1; + dep[1] -= origin_row; + // dep[1] -= 1; + // console.log("tc4 " + JSON.stringify(dep)); + tcs = tcs.concat(ExcelUtils.transitive_closure(dep[1] - 1, dep[0] - 1, origin_row, origin_col, formulas, all_deps)); + } + } + catch (e_2_1) { e_2 = { error: e_2_1 }; } + finally { + try { + if (deps_1_1 && !deps_1_1.done && (_a = deps_1["return"])) _a.call(deps_1); + } + finally { if (e_2) throw e_2.error; } + } + // console.log("tc5: tcs = " + JSON.stringify(tcs)); + // Remove any duplicates. + tcs = __spread(new Set(tcs.map(function (x) { return JSON.stringify(x); }))).map(function (x) { return JSON.parse(x); }); + all_deps[index] = tcs; + console.log("tc6: all_deps[" + index + "] = " + JSON.stringify(tcs)); + return tcs; + } + else { + return []; + } + }; + ExcelUtils.generate_all_references = function (formulas) { + var e_3, _a; + var refs = {}; + var counter = 0; + // let all_deps = {}; + console.log(JSON.stringify(formulas)); + for (var i = 0; i < formulas.length; i++) { + var row = formulas[i]; + for (var j = 0; j < row.length; j++) { + var cell = row[j]; + counter++; + if (counter % 1000 == 0) { + console.log(counter + " references down"); + } + // console.log('origin_col = '+origin_col+', origin_row = ' + origin_row); + if (cell[0] === '=') { // It's a formula. + var index = i * formulas[0].length + j; + var direct_refs = ExcelUtils.all_cell_dependencies(cell); // , origin_col + j, origin_row + i); + console.log("direct refs for " + i + ", " + j + " (" + cell + ") = " + JSON.stringify(direct_refs)); + try { + // let transitive_deps = ExcelUtils.transitive_closure(i, j, origin_row, origin_col, formulas, all_deps); + // console.log("TRANSITIVE CLOSURE FOR " + i + ", " + j + " = " + JSON.stringify(transitive_deps)); + // all_deps[index] = transitive_deps; // + for (var direct_refs_1 = __values(direct_refs), direct_refs_1_1 = direct_refs_1.next(); !direct_refs_1_1.done; direct_refs_1_1 = direct_refs_1.next()) { // direct_refs) { + var dep = direct_refs_1_1.value; + var key = dep.join(','); + refs[key] = true; // refs[key] || []; + // NOTE: we are disabling pushing the src onto the list because we don't need it. + // refs[dep2.join(',')].push(src); + } + } + catch (e_3_1) { e_3 = { error: e_3_1 }; } + finally { + try { + if (direct_refs_1_1 && !direct_refs_1_1.done && (_a = direct_refs_1["return"])) _a.call(direct_refs_1); + } + finally { if (e_3) throw e_3.error; } + } + } + } + } + return refs; + }; + ExcelUtils.generate_all_references_old = function (formulas) { + var e_4, _a; + // Generate all references. + var refs = {}; + var counter = 0; + for (var i = 0; i < formulas.length; i++) { + var row = formulas[i]; + for (var j = 0; j < row.length; j++) { + var cell = row[j]; + counter++; + if (counter % 1000 == 0) { + console.log(counter + " references down"); + } + // console.log('origin_col = '+origin_col+', origin_row = ' + origin_row); + if (cell[0] === '=') { + var all_deps = ExcelUtils.all_cell_dependencies(cell); // , origin_col + j, origin_row + i); + try { + for (var all_deps_1 = __values(all_deps), all_deps_1_1 = all_deps_1.next(); !all_deps_1_1.done; all_deps_1_1 = all_deps_1.next()) { + var dep = all_deps_1_1.value; + var key = dep.join(','); + refs[key] = true; // refs[key] || []; + // NOTE: we are disabling pushing the src onto the list because we don't need it. + // refs[dep2.join(',')].push(src); + } + } + catch (e_4_1) { e_4 = { error: e_4_1 }; } + finally { + try { + if (all_deps_1_1 && !all_deps_1_1.done && (_a = all_deps_1["return"])) _a.call(all_deps_1); + } + finally { if (e_4) throw e_4.error; } + } + } + } + } + return refs; + }; // Matchers for all kinds of Excel expressions. ExcelUtils.general_re = '\\$?[A-Z][A-Z]?\\$?\\d+'; // column and row number, optionally with $ ExcelUtils.sheet_re = '[^\\!]+'; diff --git a/src/components/excelutils.ts b/src/components/excelutils.ts index 3f2f10ddf..b7b0808f4 100644 --- a/src/components/excelutils.ts +++ b/src/components/excelutils.ts @@ -276,5 +276,112 @@ export class ExcelUtils { } + public static transitive_closure(row: number, col: number, origin_row: number, origin_col: number, formulas: Array>, all_deps : { [index: number]: Array<[number,number]> }) : Array<[number, number]> { + console.log("tc1: transitive closure of "+row+", "+col+", origin_row = " + origin_row + ", origin_col = " + origin_col); + const index = row * formulas[0].length + col; +// console.log("index = " + index); + if (index in all_deps) { + // We already processed this index: return it. + return all_deps[index]; + } +// console.log("tc2"); + console.log("formulas[" + row + "][" + col + "]"); + if ((row >= formulas.length) || (col >= formulas[0].length)) { + // Discard references to cells outside the formula range. + return []; + } + const cell = formulas[row][col]; + console.log("formulas[" + row + "][" + col + "] = " + cell); + if (cell.length <= 1 || cell[0] !== "=") { + // Not a formula -- no dependencies. + return []; + } +// console.log("tc3: cell = " + cell); + let deps = ExcelUtils.all_cell_dependencies(cell); + if (deps.length >= 1) { + let tcs = deps; + console.log("cell deps = " + JSON.stringify(tcs)); + for (let dep of deps) { + dep[0] -= origin_col; +// dep[0] -= 1; + dep[1] -= origin_row; +// dep[1] -= 1; +// console.log("tc4 " + JSON.stringify(dep)); + tcs = tcs.concat(ExcelUtils.transitive_closure(dep[1]-1, dep[0]-1, origin_row, origin_col, formulas, all_deps)); + } +// console.log("tc5: tcs = " + JSON.stringify(tcs)); + // Remove any duplicates. + tcs = [...new Set(tcs.map(x => JSON.stringify(x)))].map(x => JSON.parse(x)) + all_deps[index] = tcs; + console.log("tc6: all_deps[" + index + "] = " + JSON.stringify(tcs)); + return tcs; + } else { + return []; + } + } + + public static generate_all_references(formulas: Array>): { [dep: string]: Array<[number, number]> } { + let refs = {}; + let counter = 0; +// let all_deps = {}; + console.log(JSON.stringify(formulas)); + for (let i = 0; i < formulas.length; i++) { + let row = formulas[i]; + for (let j = 0; j < row.length; j++) { + let cell = row[j]; + counter++; + if (counter % 1000 == 0) { + console.log(counter + " references down"); + } + + // console.log('origin_col = '+origin_col+', origin_row = ' + origin_row); + if (cell[0] === '=') { // It's a formula. + const index = i * formulas[0].length + j; + let direct_refs = ExcelUtils.all_cell_dependencies(cell); // , origin_col + j, origin_row + i); + console.log("direct refs for " + i + ", " + j + " (" + cell +") = " + JSON.stringify(direct_refs)); +// let transitive_deps = ExcelUtils.transitive_closure(i, j, origin_row, origin_col, formulas, all_deps); +// console.log("TRANSITIVE CLOSURE FOR " + i + ", " + j + " = " + JSON.stringify(transitive_deps)); +// all_deps[index] = transitive_deps; // + for (let dep of direct_refs) { // direct_refs) { + let key = dep.join(','); + refs[key] = true; // refs[key] || []; + // NOTE: we are disabling pushing the src onto the list because we don't need it. + // refs[dep2.join(',')].push(src); + } + } + } + } + return refs; + } + + public static generate_all_references_old(formulas: Array>): { [dep: string]: Array<[number, number]> } { + // Generate all references. + let refs = {}; + let counter = 0; + for (let i = 0; i < formulas.length; i++) { + let row = formulas[i]; + for (let j = 0; j < row.length; j++) { + let cell = row[j]; + counter++; + if (counter % 1000 == 0) { + console.log(counter + " references down"); + } + + // console.log('origin_col = '+origin_col+', origin_row = ' + origin_row); + if (cell[0] === '=') { + let all_deps = ExcelUtils.all_cell_dependencies(cell); // , origin_col + j, origin_row + i); + for (let dep of all_deps) { + let key = dep.join(','); + refs[key] = true; // refs[key] || []; + // NOTE: we are disabling pushing the src onto the list because we don't need it. + // refs[dep2.join(',')].push(src); + } + } + } + } + return refs; + } + + } diff --git a/src/components/jsonclone.js b/src/components/jsonclone.js index b567b4b82..f6faa9818 100644 --- a/src/components/jsonclone.js +++ b/src/components/jsonclone.js @@ -1,18 +1,38 @@ "use strict"; +var __values = (this && this.__values) || function (o) { + var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0; + if (m) return m.call(o); + return { + next: function () { + if (o && i >= o.length) o = void 0; + return { value: o && o[i++], done: !o }; + } + }; +}; exports.__esModule = true; var JSONclone = /** @class */ (function () { function JSONclone() { } JSONclone.clone = function (data) { + var e_1, _a; if (data) { if (Array.isArray(data)) { return data.slice(); } if (data.constructor === Object) { var obj = {}; - for (var _i = 0, _a = Object.keys(data); _i < _a.length; _i++) { - var k = _a[_i]; - obj[k] = JSONclone.clone(data[k]); + try { + for (var _b = __values(Object.keys(data)), _c = _b.next(); !_c.done; _c = _b.next()) { + var k = _c.value; + obj[k] = JSONclone.clone(data[k]); + } + } + catch (e_1_1) { e_1 = { error: e_1_1 }; } + finally { + try { + if (_c && !_c.done && (_a = _b["return"])) _a.call(_b); + } + finally { if (e_1) throw e_1.error; } } return obj; } diff --git a/src/components/rectangleutils.js b/src/components/rectangleutils.js index 643109b6c..1dbc991fd 100644 --- a/src/components/rectangleutils.js +++ b/src/components/rectangleutils.js @@ -1,11 +1,27 @@ "use strict"; +var __read = (this && this.__read) || function (o, n) { + var m = typeof Symbol === "function" && o[Symbol.iterator]; + if (!m) return o; + var i = m.call(o), r, ar = [], e; + try { + while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); + } + catch (error) { e = { error: error }; } + finally { + try { + if (r && !r.done && (m = i["return"])) m.call(i); + } + finally { if (e) throw e.error; } + } + return ar; +}; exports.__esModule = true; var RectangleUtils = /** @class */ (function () { function RectangleUtils() { } RectangleUtils.is_adjacent = function (A, B) { - var _a = A[0], ax1 = _a[0], ay1 = _a[1], _b = A[1], ax2 = _b[0], ay2 = _b[1]; - var _c = B[0], bx1 = _c[0], by1 = _c[1], _d = B[1], bx2 = _d[0], by2 = _d[1]; + var _a = __read(A, 2), _b = __read(_a[0], 2), ax1 = _b[0], ay1 = _b[1], _c = __read(_a[1], 2), ax2 = _c[0], ay2 = _c[1]; + var _d = __read(B, 2), _e = __read(_d[0], 2), bx1 = _e[0], by1 = _e[1], _f = __read(_d[1], 2), bx2 = _f[0], by2 = _f[1]; var tolerance = 1; var adj = !(((ax1 - bx2) > tolerance) || ((bx1 - ax2) > tolerance) @@ -14,26 +30,26 @@ var RectangleUtils = /** @class */ (function () { return adj; }; RectangleUtils.bounding_box = function (A, B) { - var _a = A[0], ax1 = _a[0], ay1 = _a[1], _b = A[1], ax2 = _b[0], ay2 = _b[1]; - var _c = B[0], bx1 = _c[0], by1 = _c[1], _d = B[1], bx2 = _d[0], by2 = _d[1]; + var _a = __read(A, 2), _b = __read(_a[0], 2), ax1 = _b[0], ay1 = _b[1], _c = __read(_a[1], 2), ax2 = _c[0], ay2 = _c[1]; + var _d = __read(B, 2), _e = __read(_d[0], 2), bx1 = _e[0], by1 = _e[1], _f = __read(_d[1], 2), bx2 = _f[0], by2 = _f[1]; return [[Math.min(ax1, bx1), Math.min(ay1, by1)], [Math.max(ax2, bx2), Math.max(ay2, by2)]]; }; RectangleUtils.area = function (A) { - var _a = A[0], ax1 = _a[0], ay1 = _a[1], _b = A[1], ax2 = _b[0], ay2 = _b[1]; + var _a = __read(A, 2), _b = __read(_a[0], 2), ax1 = _b[0], ay1 = _b[1], _c = __read(_a[1], 2), ax2 = _c[0], ay2 = _c[1]; var length = ax2 - ax1 + 1; var width = ay2 - ay1 + 1; return length * width; }; RectangleUtils.diagonal = function (A) { - var _a = A[0], ax1 = _a[0], ay1 = _a[1], _b = A[1], ax2 = _b[0], ay2 = _b[1]; + var _a = __read(A, 2), _b = __read(_a[0], 2), ax1 = _b[0], ay1 = _b[1], _c = __read(_a[1], 2), ax2 = _c[0], ay2 = _c[1]; var length = ax2 - ax1 + 1; var width = ay2 - ay1 + 1; return Math.sqrt(length * length + width * width); }; RectangleUtils.overlap = function (A, B) { - var _a = A[0], ax1 = _a[0], ay1 = _a[1], _b = A[1], ax2 = _b[0], ay2 = _b[1]; - var _c = B[0], bx1 = _c[0], by1 = _c[1], _d = B[1], bx2 = _d[0], by2 = _d[1]; + var _a = __read(A, 2), _b = __read(_a[0], 2), ax1 = _b[0], ay1 = _b[1], _c = __read(_a[1], 2), ax2 = _c[0], ay2 = _c[1]; + var _d = __read(B, 2), _e = __read(_d[0], 2), bx1 = _e[0], by1 = _e[1], _f = __read(_d[1], 2), bx2 = _f[0], by2 = _f[1]; var width = 0, height = 0; if (ax2 > bx2) { width = bx2 - ax1 + 1; diff --git a/tsconfig.json b/tsconfig.json index 618819b78..efc4baa25 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "target": "es5", + "target": "es2018", "module": "commonjs", "jsx": "react", "moduleResolution": "node", @@ -12,12 +12,8 @@ "allowUnusedLabels": false, "noImplicitReturns": true, "noUnusedParameters": true, - "noUnusedLocals": false, // true, + "noUnusedLocals": false, "downlevelIteration": true, - "lib": [ - "es7", - "dom" - ], "pretty": true, "typeRoots": [ "node_modules/@types" diff --git a/tslint.json b/tslint.json index d182f6648..25756f7f4 100644 --- a/tslint.json +++ b/tslint.json @@ -65,4 +65,4 @@ "check-type" ] } -} \ No newline at end of file +}