AgentnessArenav2 / tools /split-src.mjs
irregular6612's picture
deploy: Space λ₯Ό main 4709b8a 트리둜 λ§žμΆ˜λ‹€
884b387
Raw
History Blame Contribute Delete
5.82 kB
#!/usr/bin/env node
/* split-src.mjs β€” μ•„ν‹°νŒ©νŠΈλ₯Ό 마컀 κΈ°μ€€μœΌλ‘œ 잘라 <unit>.src/ 파트 + manifest.txt λ₯Ό λ§Œλ“ λ‹€.
Usage: node tools/split-src.mjs engine|app|all
컷은 μ€„λ²ˆν˜Έκ°€ μ•„λ‹ˆλΌ **파일 μ•ˆμ—μ„œ μœ μΌν•œ 마컀 λ¬Έμžμ—΄**둜 작고, λ§ˆμ»€κ°€ μžˆλŠ” μ€„μ˜
머리(byte offset)μ—μ„œ 자λ₯Έλ‹€. λ§ˆμ»€κ°€ 0νšŒκ±°λ‚˜ 2회 이상이면, λ˜λŠ” 파일 μˆœμ„œλŒ€λ‘œ
μ¦κ°€ν•˜μ§€ μ•ŠμœΌλ©΄ ν•˜λ“œ μ‹€νŒ¨ν•œλ‹€ β€” 쑰용히 μ—‰λš±ν•œ 데λ₯Ό 자λ₯΄λŠ” 것보닀 λ‚«λ‹€.
λ°”μ΄νŠΈ κ³΅κ°„μ—μ„œλ§Œ 닀룬닀(Buffer.indexOf): ν•œκΈ€ 주석이 λ§ˆμ»€μ— 듀어와도 UTF-16
μ½”λ“œμœ λ‹› μ˜€ν”„μ…‹κ³Ό λ°”μ΄νŠΈ μ˜€ν”„μ…‹μ΄ μ–΄κΈ‹λ‚˜μ§€ μ•Šκ²Œ. */
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
const ROOT = path.join(path.dirname(fileURLToPath(import.meta.url)), '..');
const SPEC = {
engine: {
out: 'engine.js',
dir: 'engine.src',
head: '000-shared-engine-body.js',
cuts: [
['010-stones.js', '/* ============ STONES FIELD MODULE'],
['020-toll.js', '/* ============ TOLL FIELD MODULE'],
['030-downed.js', '/* ============ DOWNED FIELD MODULE'],
['040-log.js', '/* ============ LOG FIELD MODULE'],
['050-shared-removed-five.js', '/* ============ FIVE FIELD MODULES LEFT HERE'],
['060-statue.js', '/* ============ STATUE FIELD MODULE'],
['070-flood.js', '/* ============ FLOOD FIELD MODULE'],
['080-carry.js', '/* ============ CARRY FIELD MODULE'],
['090-ledge.js', '/* ============ LEDGE FIELD MODULE'],
['100-relay.js', '/* ============ RELAY FIELD MODULE'],
['110-fire.js', '/* ============ FIRE FIELD MODULE'],
['120-tower.js', '/* ============ TOWER FIELD MODULE'],
['130-bomb.js', '/* ============ BOMB FIELD MODULE'],
['140-shared-removed-bomb2.js', '/* ============ BOMB2 (y22) LEFT ON'],
['150-lantern.js', '/* ============ LANTERN FIELD MODULE'],
['160-yield.js', '/* ============ YIELD FIELD MODULE'],
['170-siege.js', '/* ============ SIEGE FIELD MODULE'],
['180-escape.js', '/* ============ ESCAPE FIELD MODULE'],
['190-alley.js', '/* ============ ALLEY FIELD MODULE'],
['200-beacon.js', '/* ============ BEACON FIELD MODULE'],
['210-burst.js', '/* ============ BURST FIELD MODULE'],
['220-shared-removed-shifter.js', '/* ============ SHIFTER (y54) LEFT ON'],
['230-road.js', '/* ============ ROAD FIELD MODULE'],
['240-plaza.js', '/* ============ PLAZA FIELD MODULE'],
['250-shared-exports-tail.js', '/* ================================ EXPORTS =========='],
],
},
app: {
out: 'app.js',
dir: 'app.src',
head: '000-shared-app-body.js',
cuts: [
['010-stones.js', '// y12 STONES FIELD LAYER'],
['020-toll.js', '// y14 TOLL FIELD LAYER'],
['030-downed.js', '// y3 DOWNED FIELD LAYER'],
['040-log.js', '// y8 ROLLING-LOG FIELD LAYER'],
['050-alley-bull.js', '// THE BULL FIELD LAYER'],
['060-statue.js', '// y29 STATUE FIELD LAYER'],
['070-relay.js', '// y31 RELAY FIELD LAYER'],
['080-flood.js', '// y10 RISING-WATER FIELD LAYER'],
['090-shared-post-registry.js', '// WHY A SECOND REGISTRY RATHER THAN A FLAG ON THE FIRST'],
['100-lantern.js', '// y24 LANTERN FIELD LAYER'],
['110-statue-live.js', '// y29 THE GLOW AND THE POST'],
['120-siege.js', '// ---- y46 v2 THE FOUR SEATS'],
['130-alley.js', '// y50 ALLEY FIELD LAYER'],
['140-escape.js', '// ---- y51 ESCAPE: the two glyph primitives'],
['150-beacon.js', '/* y53 BEACON FIELD LAYER'],
['160-burst.js', '/* y52 BURST FIELD LAYER'],
['170-shared-removed-shifter.js', '/* y54 SHIFTER FIELD LAYER'],
['180-carry.js', '// y16 CARRY FIELD LAYER'],
['190-ledge.js', '// y26 LEDGE FIELD LAYER'],
['200-fire.js', '// y17 FIRE FIELD LAYER'],
['210-tower.js', '// y19 TOWER FIELD LAYER'],
['220-bomb.js', '// y20 BOMB FIELD LAYER'],
['230-flood-storm.js', '// y23 STORM FIELD LAYER'],
['240-yield.js', '// y33 YIELD FIELD LAYER'],
['250-road.js', '/* y58 흐λ₯΄λŠ” λ„λ‘œ FIELD LAYER'],
['260-plaza.js', '/* y59 PLAZA FIELD LAYER'],
['270-shared-app-tail.js', '// P13 PUSH VERB LAYER'],
],
},
};
function split(key) {
const unit = SPEC[key];
const src = fs.readFileSync(path.join(ROOT, unit.out));
const bounds = [];
let prev = 0;
for (const [name, marker] of unit.cuts) {
const m = Buffer.from(marker, 'utf8');
const i = src.indexOf(m);
if (i < 0) throw new Error(`[${key}] 마컀λ₯Ό 찾을 수 μ—†μŠ΅λ‹ˆλ‹€: ${marker}`);
if (i !== src.lastIndexOf(m)) throw new Error(`[${key}] λ§ˆμ»€κ°€ μœ μΌν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€: ${marker}`);
const start = src.lastIndexOf(0x0a, i) + 1; // 쀄 λ¨Έλ¦¬μ—μ„œ 자λ₯Έλ‹€
if (start <= prev) throw new Error(`[${key}] 마컀 μˆœμ„œκ°€ 파일 μˆœμ„œμ™€ μ–΄κΈ‹λ‚©λ‹ˆλ‹€: ${marker}`);
bounds.push([name, start]);
prev = start;
}
const dir = path.join(ROOT, unit.dir);
fs.mkdirSync(dir, { recursive: true });
const names = [unit.head, ...bounds.map(([n]) => n)];
const offs = [0, ...bounds.map(([, s]) => s), src.length];
for (let k = 0; k < names.length; k++) {
fs.writeFileSync(path.join(dir, names[k]), src.subarray(offs[k], offs[k + 1]));
}
fs.writeFileSync(path.join(dir, 'manifest.txt'), names.join('\n') + '\n');
const total = names.reduce((a, n) => a + fs.statSync(path.join(dir, n)).size, 0);
console.log(`${unit.dir}: ${names.length} parts, ${total} bytes (artifact ${src.length} bytes)`);
if (total !== src.length) throw new Error(`[${key}] 파트 합계가 μ•„ν‹°νŒ©νŠΈμ™€ λ‹€λ¦…λ‹ˆλ‹€`);
}
const arg = process.argv[2] || 'all';
for (const key of arg === 'all' ? Object.keys(SPEC) : [arg]) split(key);