Buckets:
tahamajs/Other_Lessons / AP /TA_1 /AP-ECE-UT.github.io /node_modules /cli-table3 /src /layout-manager.js
| const { warn, debug } = require('./debug'); | |
| const Cell = require('./cell'); | |
| const { ColSpanCell, RowSpanCell } = Cell; | |
| (function () { | |
| function next(alloc, col) { | |
| if (alloc[col] > 0) { | |
| return next(alloc, col + 1); | |
| } | |
| return col; | |
| } | |
| function layoutTable(table) { | |
| let alloc = {}; | |
| table.forEach(function (row, rowIndex) { | |
| let col = 0; | |
| row.forEach(function (cell) { | |
| cell.y = rowIndex; | |
| // Avoid erroneous call to next() on first row | |
| cell.x = rowIndex ? next(alloc, col) : col; | |
| const rowSpan = cell.rowSpan || 1; | |
| const colSpan = cell.colSpan || 1; | |
| if (rowSpan > 1) { | |
| for (let cs = 0; cs < colSpan; cs++) { | |
| alloc[cell.x + cs] = rowSpan; | |
| } | |
| } | |
| col = cell.x + colSpan; | |
| }); | |
| Object.keys(alloc).forEach((idx) => { | |
| alloc[idx]--; | |
| if (alloc[idx] < 1) delete alloc[idx]; | |
| }); | |
| }); | |
| } | |
| function maxWidth(table) { | |
| let mw = 0; | |
| table.forEach(function (row) { | |
| row.forEach(function (cell) { | |
| mw = Math.max(mw, cell.x + (cell.colSpan || 1)); | |
| }); | |
| }); | |
| return mw; | |
| } | |
| function maxHeight(table) { | |
| return table.length; | |
| } | |
| function cellsConflict(cell1, cell2) { | |
| let yMin1 = cell1.y; | |
| let yMax1 = cell1.y - 1 + (cell1.rowSpan || 1); | |
| let yMin2 = cell2.y; | |
| let yMax2 = cell2.y - 1 + (cell2.rowSpan || 1); | |
| let yConflict = !(yMin1 > yMax2 || yMin2 > yMax1); | |
| let xMin1 = cell1.x; | |
| let xMax1 = cell1.x - 1 + (cell1.colSpan || 1); | |
| let xMin2 = cell2.x; | |
| let xMax2 = cell2.x - 1 + (cell2.colSpan || 1); | |
| let xConflict = !(xMin1 > xMax2 || xMin2 > xMax1); | |
| return yConflict && xConflict; | |
| } | |
| function conflictExists(rows, x, y) { | |
| let i_max = Math.min(rows.length - 1, y); | |
| let cell = { x: x, y: y }; | |
| for (let i = 0; i <= i_max; i++) { | |
| let row = rows[i]; | |
| for (let j = 0; j < row.length; j++) { | |
| if (cellsConflict(cell, row[j])) { | |
| return true; | |
| } | |
| } | |
| } | |
| return false; | |
| } | |
| function allBlank(rows, y, xMin, xMax) { | |
| for (let x = xMin; x < xMax; x++) { | |
| if (conflictExists(rows, x, y)) { | |
| return false; | |
| } | |
| } | |
| return true; | |
| } | |
| function addRowSpanCells(table) { | |
| table.forEach(function (row, rowIndex) { | |
| row.forEach(function (cell) { | |
| for (let i = 1; i < cell.rowSpan; i++) { | |
| let rowSpanCell = new RowSpanCell(cell); | |
| rowSpanCell.x = cell.x; | |
| rowSpanCell.y = cell.y + i; | |
| rowSpanCell.colSpan = cell.colSpan; | |
| insertCell(rowSpanCell, table[rowIndex + i]); | |
| } | |
| }); | |
| }); | |
| } | |
| function addColSpanCells(cellRows) { | |
| for (let rowIndex = cellRows.length - 1; rowIndex >= 0; rowIndex--) { | |
| let cellColumns = cellRows[rowIndex]; | |
| for (let columnIndex = 0; columnIndex < cellColumns.length; columnIndex++) { | |
| let cell = cellColumns[columnIndex]; | |
| for (let k = 1; k < cell.colSpan; k++) { | |
| let colSpanCell = new ColSpanCell(); | |
| colSpanCell.x = cell.x + k; | |
| colSpanCell.y = cell.y; | |
| cellColumns.splice(columnIndex + 1, 0, colSpanCell); | |
| } | |
| } | |
| } | |
| } | |
| function insertCell(cell, row) { | |
| let x = 0; | |
| while (x < row.length && row[x].x < cell.x) { | |
| x++; | |
| } | |
| row.splice(x, 0, cell); | |
| } | |
| function fillInTable(table) { | |
| let h_max = maxHeight(table); | |
| let w_max = maxWidth(table); | |
| debug(`Max rows: ${h_max}; Max cols: ${w_max}`); | |
| for (let y = 0; y < h_max; y++) { | |
| for (let x = 0; x < w_max; x++) { | |
| if (!conflictExists(table, x, y)) { | |
| let opts = { x: x, y: y, colSpan: 1, rowSpan: 1 }; | |
| x++; | |
| while (x < w_max && !conflictExists(table, x, y)) { | |
| opts.colSpan++; | |
| x++; | |
| } | |
| let y2 = y + 1; | |
| while (y2 < h_max && allBlank(table, y2, opts.x, opts.x + opts.colSpan)) { | |
| opts.rowSpan++; | |
| y2++; | |
| } | |
| let cell = new Cell(opts); | |
| cell.x = opts.x; | |
| cell.y = opts.y; | |
| warn(`Missing cell at ${cell.y}-${cell.x}.`); | |
| insertCell(cell, table[y]); | |
| } | |
| } | |
| } | |
| } | |
| function generateCells(rows) { | |
| return rows.map(function (row) { | |
| if (!Array.isArray(row)) { | |
| let key = Object.keys(row)[0]; | |
| row = row[key]; | |
| if (Array.isArray(row)) { | |
| row = row.slice(); | |
| row.unshift(key); | |
| } else { | |
| row = [key, row]; | |
| } | |
| } | |
| return row.map(function (cell) { | |
| return new Cell(cell); | |
| }); | |
| }); | |
| } | |
| function makeTableLayout(rows) { | |
| let cellRows = generateCells(rows); | |
| layoutTable(cellRows); | |
| fillInTable(cellRows); | |
| addRowSpanCells(cellRows); | |
| addColSpanCells(cellRows); | |
| return cellRows; | |
| } | |
| module.exports = { | |
| makeTableLayout: makeTableLayout, | |
| layoutTable: layoutTable, | |
| addRowSpanCells: addRowSpanCells, | |
| maxWidth: maxWidth, | |
| fillInTable: fillInTable, | |
| computeWidths: makeComputeWidths('colSpan', 'desiredWidth', 'x', 1), | |
| computeHeights: makeComputeWidths('rowSpan', 'desiredHeight', 'y', 1), | |
| }; | |
| })(); | |
| function makeComputeWidths(colSpan, desiredWidth, x, forcedMin) { | |
| return function (vals, table) { | |
| let result = []; | |
| let spanners = []; | |
| let auto = {}; | |
| table.forEach(function (row) { | |
| row.forEach(function (cell) { | |
| if ((cell[colSpan] || 1) > 1) { | |
| spanners.push(cell); | |
| } else { | |
| result[cell[x]] = Math.max(result[cell[x]] || 0, cell[desiredWidth] || 0, forcedMin); | |
| } | |
| }); | |
| }); | |
| vals.forEach(function (val, index) { | |
| if (typeof val === 'number') { | |
| result[index] = val; | |
| } | |
| }); | |
| //spanners.forEach(function(cell){ | |
| for (let k = spanners.length - 1; k >= 0; k--) { | |
| let cell = spanners[k]; | |
| let span = cell[colSpan]; | |
| let col = cell[x]; | |
| let existingWidth = result[col]; | |
| let editableCols = typeof vals[col] === 'number' ? 0 : 1; | |
| if (typeof existingWidth === 'number') { | |
| for (let i = 1; i < span; i++) { | |
| existingWidth += 1 + result[col + i]; | |
| if (typeof vals[col + i] !== 'number') { | |
| editableCols++; | |
| } | |
| } | |
| } else { | |
| existingWidth = desiredWidth === 'desiredWidth' ? cell.desiredWidth - 1 : 1; | |
| if (!auto[col] || auto[col] < existingWidth) { | |
| auto[col] = existingWidth; | |
| } | |
| } | |
| if (cell[desiredWidth] > existingWidth) { | |
| let i = 0; | |
| while (editableCols > 0 && cell[desiredWidth] > existingWidth) { | |
| if (typeof vals[col + i] !== 'number') { | |
| let dif = Math.round((cell[desiredWidth] - existingWidth) / editableCols); | |
| existingWidth += dif; | |
| result[col + i] += dif; | |
| editableCols--; | |
| } | |
| i++; | |
| } | |
| } | |
| } | |
| Object.assign(vals, result, auto); | |
| for (let j = 0; j < vals.length; j++) { | |
| vals[j] = Math.max(forcedMin, vals[j] || 0); | |
| } | |
| }; | |
| } | |
Xet Storage Details
- Size:
- 7.05 kB
- Xet hash:
- b68eabc17aaef41149b0f5dd727191db48c79f719973ad4aa82744075385da34
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.