Spaces:
Running
Running
File size: 6,069 Bytes
9bd422a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 | /**
* Formatters - Data formatting utilities
* Provides functions for formatting file names, tensor shapes, file sizes,
* data types, and tensor info for display in the UI.
* Requirements: 2.5, 5.6, 7.3
*/
const Formatters = (function () {
// βββ File Name Formatting βββββββββββββββββββββββββββββββββββββββββββββββββ
/**
* Format a file path into a human-readable display name.
* Strips directory separators and returns only the base file name.
* e.g. "models/jsl/model.onnx" β "model.onnx"
* @param {string} filePath
* @returns {string}
*/
function formatFileName(filePath) {
if (!filePath) return 'Unknown';
const base = filePath.replace(/\\/g, '/').split('/').pop() || filePath;
return base;
}
/**
* Format a model name for display: strip extension and replace
* underscores/hyphens with spaces, then title-case.
* e.g. "my_model.onnx" β "My Model"
* @param {string} filePath
* @returns {string}
*/
function formatModelName(filePath) {
if (!filePath) return 'Unknown';
const base = formatFileName(filePath);
const noExt = base.replace(/\.onnx$/i, '');
return noExt
.replace(/[_-]+/g, ' ')
.replace(/\b\w/g, c => c.toUpperCase());
}
// βββ Tensor Shape Formatting ββββββββββββββββββββββββββββββββββββββββββββββ
/**
* Format a tensor shape array into a readable string.
* Dynamic dimensions (null, -1, 0, or string) are shown as "?".
* e.g. [1, 3, 224, 224] β "[1, 3, 224, 224]"
* e.g. [-1, 3, 224, 224] β "[?, 3, 224, 224]"
* @param {Array<number|string|null>} shape
* @returns {string}
*/
function formatShape(shape) {
if (!Array.isArray(shape) || shape.length === 0) return '[]';
const dims = shape.map(d => {
if (d === null || d === undefined) return '?';
if (typeof d === 'string') return d || '?';
if (typeof d === 'number' && (d < 0 || d === 0)) return '?';
return String(d);
});
return '[' + dims.join(', ') + ']';
}
// βββ File Size Formatting βββββββββββββββββββββββββββββββββββββββββββββββββ
/**
* Format a byte count into a human-readable size string.
* e.g. 1024 β "1.00 KB", 1048576 β "1.00 MB"
* @param {number} bytes
* @param {number} [decimals=2]
* @returns {string}
*/
function formatBytes(bytes, decimals = 2) {
if (bytes == null || isNaN(bytes)) return 'Unknown';
if (bytes === 0) return '0 B';
const k = 1024;
const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
const i = Math.floor(Math.log(Math.abs(bytes)) / Math.log(k));
const idx = Math.min(i, sizes.length - 1);
const value = bytes / Math.pow(k, idx);
return value.toFixed(decimals) + ' ' + sizes[idx];
}
// βββ Data Type Formatting βββββββββββββββββββββββββββββββββββββββββββββββββ
/**
* ONNX data type code β human-readable name mapping.
*/
const DATA_TYPE_MAP = {
0: 'UNDEFINED',
1: 'FLOAT',
2: 'UINT8',
3: 'INT8',
4: 'UINT16',
5: 'INT16',
6: 'INT32',
7: 'INT64',
8: 'STRING',
9: 'BOOL',
10: 'FLOAT16',
11: 'DOUBLE',
12: 'UINT32',
13: 'UINT64',
14: 'COMPLEX64',
15: 'COMPLEX128',
16: 'BFLOAT16',
};
/**
* Format an ONNX data type code or string into a readable label.
* Accepts numeric codes (1β16) or string names.
* @param {number|string} code
* @returns {string}
*/
function formatDataType(code) {
if (code == null) return 'Unknown';
if (typeof code === 'number') {
return DATA_TYPE_MAP[code] || `Type(${code})`;
}
// Already a string β normalise to upper-case
const upper = String(code).toUpperCase();
// Check if it matches a known name
const known = Object.values(DATA_TYPE_MAP);
return known.includes(upper) ? upper : code;
}
// βββ Tensor Info Formatting βββββββββββββββββββββββββββββββββββββββββββββββ
/**
* Format a TensorInfo object into a concise one-line description.
* e.g. "input_0: FLOAT [1, 3, 224, 224]"
* @param {{ name: string, shape: Array, dataType: number|string }} tensor
* @returns {string}
*/
function formatTensorInfo(tensor) {
if (!tensor) return 'Unknown';
const name = tensor.name || 'unnamed';
const dtype = formatDataType(tensor.dataType);
const shape = formatShape(tensor.shape);
return `${name}: ${dtype} ${shape}`;
}
/**
* Format element count for an initializer.
* @param {Array<number>} shape
* @returns {number}
*/
function calcElementCount(shape) {
if (!Array.isArray(shape) || shape.length === 0) return 0;
return shape.reduce((acc, d) => acc * (d > 0 ? d : 1), 1);
}
// βββ Number Formatting ββββββββββββββββββββββββββββββββββββββββββββββββββββ
/**
* Format a large integer with locale-aware thousands separators.
* @param {number} n
* @returns {string}
*/
function formatNumber(n) {
if (n == null || isNaN(n)) return '0';
return n.toLocaleString();
}
// βββ Public API βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
return {
formatFileName,
formatModelName,
formatShape,
formatBytes,
formatDataType,
formatTensorInfo,
calcElementCount,
formatNumber,
DATA_TYPE_MAP,
};
})();
// Export for global access in vanilla JS context
window.Formatters = Formatters;
|