Major changes: - New frontend (platform/web/): Vite + React 18 + TypeScript + Tailwind - 4-module navigation: 数据送标 / 模型管理 / 车队管理 / 系统管理 - Data catalog with charts (DMS/ADAS/Lane 3-tab view) - Quality review workflow (标注质检): Good/Fine/Bad scoring with auto-advance - Audit enhancements: batch operations, rejection categories, Feishu notifications - Operation audit log (操作日志) - World model simulation studio (仿真工坊) - Dataset version management with snapshots and diff - ADAS 7-class dataset integration (138K images organized + compressed) - User management with Feishu integration and pagination - CRUD/search/filter on all pages, card layout redesign - PIL-optimized image overlay rendering - Auto-snapshot on build, in_review workflow stage - Removed embedded algorithm code (now in workspace)
114 lines
2.7 KiB
JavaScript
114 lines
2.7 KiB
JavaScript
'use strict';
|
|
|
|
const fill = require('fill-range');
|
|
const stringify = require('./stringify');
|
|
const utils = require('./utils');
|
|
|
|
const append = (queue = '', stash = '', enclose = false) => {
|
|
const result = [];
|
|
|
|
queue = [].concat(queue);
|
|
stash = [].concat(stash);
|
|
|
|
if (!stash.length) return queue;
|
|
if (!queue.length) {
|
|
return enclose ? utils.flatten(stash).map(ele => `{${ele}}`) : stash;
|
|
}
|
|
|
|
for (const item of queue) {
|
|
if (Array.isArray(item)) {
|
|
for (const value of item) {
|
|
result.push(append(value, stash, enclose));
|
|
}
|
|
} else {
|
|
for (let ele of stash) {
|
|
if (enclose === true && typeof ele === 'string') ele = `{${ele}}`;
|
|
result.push(Array.isArray(ele) ? append(item, ele, enclose) : item + ele);
|
|
}
|
|
}
|
|
}
|
|
return utils.flatten(result);
|
|
};
|
|
|
|
const expand = (ast, options = {}) => {
|
|
const rangeLimit = options.rangeLimit === undefined ? 1000 : options.rangeLimit;
|
|
|
|
const walk = (node, parent = {}) => {
|
|
node.queue = [];
|
|
|
|
let p = parent;
|
|
let q = parent.queue;
|
|
|
|
while (p.type !== 'brace' && p.type !== 'root' && p.parent) {
|
|
p = p.parent;
|
|
q = p.queue;
|
|
}
|
|
|
|
if (node.invalid || node.dollar) {
|
|
q.push(append(q.pop(), stringify(node, options)));
|
|
return;
|
|
}
|
|
|
|
if (node.type === 'brace' && node.invalid !== true && node.nodes.length === 2) {
|
|
q.push(append(q.pop(), ['{}']));
|
|
return;
|
|
}
|
|
|
|
if (node.nodes && node.ranges > 0) {
|
|
const args = utils.reduce(node.nodes);
|
|
|
|
if (utils.exceedsLimit(...args, options.step, rangeLimit)) {
|
|
throw new RangeError('expanded array length exceeds range limit. Use options.rangeLimit to increase or disable the limit.');
|
|
}
|
|
|
|
let range = fill(...args, options);
|
|
if (range.length === 0) {
|
|
range = stringify(node, options);
|
|
}
|
|
|
|
q.push(append(q.pop(), range));
|
|
node.nodes = [];
|
|
return;
|
|
}
|
|
|
|
const enclose = utils.encloseBrace(node);
|
|
let queue = node.queue;
|
|
let block = node;
|
|
|
|
while (block.type !== 'brace' && block.type !== 'root' && block.parent) {
|
|
block = block.parent;
|
|
queue = block.queue;
|
|
}
|
|
|
|
for (let i = 0; i < node.nodes.length; i++) {
|
|
const child = node.nodes[i];
|
|
|
|
if (child.type === 'comma' && node.type === 'brace') {
|
|
if (i === 1) queue.push('');
|
|
queue.push('');
|
|
continue;
|
|
}
|
|
|
|
if (child.type === 'close') {
|
|
q.push(append(q.pop(), queue, enclose));
|
|
continue;
|
|
}
|
|
|
|
if (child.value && child.type !== 'open') {
|
|
queue.push(append(queue.pop(), child.value));
|
|
continue;
|
|
}
|
|
|
|
if (child.nodes) {
|
|
walk(child, node);
|
|
}
|
|
}
|
|
|
|
return queue;
|
|
};
|
|
|
|
return utils.flatten(walk(ast));
|
|
};
|
|
|
|
module.exports = expand;
|