figma-local 1.5.0 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/plugin/manifest.json +1 -0
- package/src/index.js +356 -0
package/package.json
CHANGED
package/plugin/manifest.json
CHANGED
package/src/index.js
CHANGED
|
@@ -8537,6 +8537,7 @@ program
|
|
|
8537
8537
|
.option('--tokens', 'Show only the design tokens (colors, spacing, etc.) used in the frame')
|
|
8538
8538
|
.option('--selection', 'Read whatever is currently selected in Figma')
|
|
8539
8539
|
.option('--link <url>', 'Read a specific node from a Figma selection link (e.g. copied via "Copy link to selection")')
|
|
8540
|
+
.option('--page', 'Read the entire current page — all frames with full structure, tokens, and specs')
|
|
8540
8541
|
.option('--stage <n>', 'Run a specific stage: 1 (list frames), 2 (structure), 3 (tokens)')
|
|
8541
8542
|
.addHelpText('after', `
|
|
8542
8543
|
Examples:
|
|
@@ -8545,6 +8546,7 @@ Examples:
|
|
|
8545
8546
|
fig read "Login Screen" --tokens Show only the design tokens used by Login Screen
|
|
8546
8547
|
fig read --selection Read the node you currently have selected in Figma
|
|
8547
8548
|
fig read --link "https://..." Read a node from a Figma selection link
|
|
8549
|
+
fig read --page Read the entire page with all frames, structure, and tokens
|
|
8548
8550
|
fig read --json Output raw JSON (useful for piping to other tools)
|
|
8549
8551
|
`)
|
|
8550
8552
|
.action(async (frameName, options) => {
|
|
@@ -8620,6 +8622,136 @@ Examples:
|
|
|
8620
8622
|
return;
|
|
8621
8623
|
}
|
|
8622
8624
|
|
|
8625
|
+
// --page: read the entire current page with all frames
|
|
8626
|
+
if (options.page) {
|
|
8627
|
+
spinner.text = 'Reading entire page...';
|
|
8628
|
+
const pageCode = `(function() {
|
|
8629
|
+
const page = figma.currentPage;
|
|
8630
|
+
function walk(n, depth) {
|
|
8631
|
+
if (depth > 20) return { type: n.type, name: n.name };
|
|
8632
|
+
var obj = { type: n.type, name: n.name, id: n.id };
|
|
8633
|
+
if (n.width) obj.w = Math.round(n.width);
|
|
8634
|
+
if (n.height) obj.h = Math.round(n.height);
|
|
8635
|
+
if (n.x !== undefined) obj.x = Math.round(n.x);
|
|
8636
|
+
if (n.y !== undefined) obj.y = Math.round(n.y);
|
|
8637
|
+
if (n.type === 'TEXT') obj.text = n.characters;
|
|
8638
|
+
if (n.fills && n.fills.length) {
|
|
8639
|
+
obj.fills = n.fills.map(function(f) {
|
|
8640
|
+
if (f.type === 'SOLID') return { type: 'SOLID', r: Math.round(f.color.r*255), g: Math.round(f.color.g*255), b: Math.round(f.color.b*255), a: f.opacity !== undefined ? f.opacity : 1 };
|
|
8641
|
+
return { type: f.type };
|
|
8642
|
+
});
|
|
8643
|
+
}
|
|
8644
|
+
if (n.strokes && n.strokes.length) {
|
|
8645
|
+
obj.strokes = n.strokes.map(function(s) {
|
|
8646
|
+
if (s.type === 'SOLID') return { type: 'SOLID', r: Math.round(s.color.r*255), g: Math.round(s.color.g*255), b: Math.round(s.color.b*255) };
|
|
8647
|
+
return { type: s.type };
|
|
8648
|
+
});
|
|
8649
|
+
if (n.strokeWeight) obj.strokeWeight = n.strokeWeight;
|
|
8650
|
+
}
|
|
8651
|
+
if (n.cornerRadius) obj.radius = n.cornerRadius;
|
|
8652
|
+
if (n.opacity !== undefined && n.opacity < 1) obj.opacity = n.opacity;
|
|
8653
|
+
if (n.layoutMode) {
|
|
8654
|
+
obj.layout = { mode: n.layoutMode };
|
|
8655
|
+
if (n.itemSpacing) obj.layout.gap = n.itemSpacing;
|
|
8656
|
+
if (n.paddingTop || n.paddingRight || n.paddingBottom || n.paddingLeft) {
|
|
8657
|
+
obj.layout.padding = { top: n.paddingTop || 0, right: n.paddingRight || 0, bottom: n.paddingBottom || 0, left: n.paddingLeft || 0 };
|
|
8658
|
+
}
|
|
8659
|
+
if (n.primaryAxisAlignItems) obj.layout.mainAlign = n.primaryAxisAlignItems;
|
|
8660
|
+
if (n.counterAxisAlignItems) obj.layout.crossAlign = n.counterAxisAlignItems;
|
|
8661
|
+
}
|
|
8662
|
+
if (n.type === 'TEXT') {
|
|
8663
|
+
obj.typography = {};
|
|
8664
|
+
try { obj.typography.family = n.fontName.family; } catch(e) {}
|
|
8665
|
+
try { obj.typography.style = n.fontName.style; } catch(e) {}
|
|
8666
|
+
try { obj.typography.size = n.fontSize; } catch(e) {}
|
|
8667
|
+
try { obj.typography.weight = n.fontWeight; } catch(e) {}
|
|
8668
|
+
try {
|
|
8669
|
+
if (n.lineHeight && n.lineHeight.value) obj.typography.lineHeight = n.lineHeight.unit === 'PERCENT' ? n.lineHeight.value + '%' : n.lineHeight.value;
|
|
8670
|
+
} catch(e) {}
|
|
8671
|
+
try { if (n.letterSpacing && n.letterSpacing.value) obj.typography.letterSpacing = n.letterSpacing.value; } catch(e) {}
|
|
8672
|
+
}
|
|
8673
|
+
if (n.effects && n.effects.length) {
|
|
8674
|
+
obj.effects = n.effects.map(function(e) {
|
|
8675
|
+
var eff = { type: e.type };
|
|
8676
|
+
if (e.radius) eff.radius = e.radius;
|
|
8677
|
+
if (e.offset) eff.offset = { x: e.offset.x, y: e.offset.y };
|
|
8678
|
+
if (e.color) eff.color = { r: Math.round(e.color.r*255), g: Math.round(e.color.g*255), b: Math.round(e.color.b*255), a: e.color.a };
|
|
8679
|
+
return eff;
|
|
8680
|
+
});
|
|
8681
|
+
}
|
|
8682
|
+
// Variable bindings
|
|
8683
|
+
try {
|
|
8684
|
+
var vars = {};
|
|
8685
|
+
var bindings = n.boundVariables;
|
|
8686
|
+
if (bindings) {
|
|
8687
|
+
Object.keys(bindings).forEach(function(prop) {
|
|
8688
|
+
try {
|
|
8689
|
+
var binding = bindings[prop];
|
|
8690
|
+
if (Array.isArray(binding)) binding = binding[0];
|
|
8691
|
+
if (binding && binding.id) {
|
|
8692
|
+
var v = figma.variables.getVariableById(binding.id);
|
|
8693
|
+
if (v) {
|
|
8694
|
+
var info = { name: v.name };
|
|
8695
|
+
try {
|
|
8696
|
+
var collection = figma.variables.getVariableCollectionById(v.variableCollectionId);
|
|
8697
|
+
if (collection && collection.modes && collection.modes.length > 0) {
|
|
8698
|
+
info.values = {};
|
|
8699
|
+
collection.modes.forEach(function(mode) {
|
|
8700
|
+
try {
|
|
8701
|
+
var mVal = v.valuesByMode[mode.modeId];
|
|
8702
|
+
if (mVal && mVal.type === 'VARIABLE_ALIAS') {
|
|
8703
|
+
try {
|
|
8704
|
+
var aliased = figma.variables.getVariableById(mVal.id);
|
|
8705
|
+
info.values[mode.name] = aliased ? aliased.name : 'alias';
|
|
8706
|
+
} catch(e3) { info.values[mode.name] = 'alias'; }
|
|
8707
|
+
} else {
|
|
8708
|
+
info.values[mode.name] = mVal;
|
|
8709
|
+
}
|
|
8710
|
+
} catch(e4) {}
|
|
8711
|
+
});
|
|
8712
|
+
}
|
|
8713
|
+
} catch(e5) {}
|
|
8714
|
+
vars[prop] = info;
|
|
8715
|
+
}
|
|
8716
|
+
}
|
|
8717
|
+
} catch(e) {}
|
|
8718
|
+
});
|
|
8719
|
+
}
|
|
8720
|
+
if (Object.keys(vars).length > 0) obj.variables = vars;
|
|
8721
|
+
} catch(e) {}
|
|
8722
|
+
// Component info
|
|
8723
|
+
if (n.type === 'COMPONENT') obj.isComponent = true;
|
|
8724
|
+
if (n.type === 'INSTANCE') {
|
|
8725
|
+
obj.isInstance = true;
|
|
8726
|
+
try { obj.componentName = n.mainComponent ? n.mainComponent.name : undefined; } catch(e) {}
|
|
8727
|
+
}
|
|
8728
|
+
if (n.children) obj.children = n.children.map(function(c) { return walk(c, depth + 1); });
|
|
8729
|
+
return obj;
|
|
8730
|
+
}
|
|
8731
|
+
var frames = [];
|
|
8732
|
+
for (var i = 0; i < page.children.length; i++) {
|
|
8733
|
+
frames.push(walk(page.children[i], 0));
|
|
8734
|
+
}
|
|
8735
|
+
return { page: page.name, frameCount: frames.length, frames: frames };
|
|
8736
|
+
})()`;
|
|
8737
|
+
const result = await daemonExec('eval', { code: pageCode });
|
|
8738
|
+
if (result.error) {
|
|
8739
|
+
spinner.fail(result.error);
|
|
8740
|
+
process.exit(1);
|
|
8741
|
+
}
|
|
8742
|
+
spinner.succeed(`Read page "${result.page}" — ${result.frameCount} top-level frames`);
|
|
8743
|
+
if (options.json) {
|
|
8744
|
+
console.log(JSON.stringify(result, null, 2));
|
|
8745
|
+
} else {
|
|
8746
|
+
// Pretty print each frame
|
|
8747
|
+
for (const frame of result.frames) {
|
|
8748
|
+
console.log(chalk.cyan(`\n━━━ ${frame.name} [${frame.type}] ${frame.w || ''}x${frame.h || ''} ━━━`));
|
|
8749
|
+
console.log(formatSelectionResult({ node: frame }));
|
|
8750
|
+
}
|
|
8751
|
+
}
|
|
8752
|
+
return;
|
|
8753
|
+
}
|
|
8754
|
+
|
|
8623
8755
|
// Stage 1: metadata — always run, cheapest call
|
|
8624
8756
|
spinner.text = 'Scanning canvas...';
|
|
8625
8757
|
const metadata = await daemonExec('eval', { code: STAGE1_METADATA });
|
|
@@ -10441,4 +10573,228 @@ program
|
|
|
10441
10573
|
}
|
|
10442
10574
|
});
|
|
10443
10575
|
|
|
10576
|
+
// ============ LIBRARY — access team library components & variables ============
|
|
10577
|
+
|
|
10578
|
+
program
|
|
10579
|
+
.command('library <action>')
|
|
10580
|
+
.description('Access team library components and variables from other Figma files')
|
|
10581
|
+
.option('--key <key>', 'Component key for importing')
|
|
10582
|
+
.option('--name <name>', 'Filter by name (partial match)')
|
|
10583
|
+
.option('--json', 'Output raw JSON')
|
|
10584
|
+
.addHelpText('after', `
|
|
10585
|
+
Actions:
|
|
10586
|
+
collections List all available library variable collections
|
|
10587
|
+
variables List variables from a library collection (use --name to filter)
|
|
10588
|
+
components List available library components (use --name to filter)
|
|
10589
|
+
import Import a component by key (use --key)
|
|
10590
|
+
|
|
10591
|
+
Examples:
|
|
10592
|
+
fig library collections List all library variable collections
|
|
10593
|
+
fig library variables List all library variables
|
|
10594
|
+
fig library variables --name "color" List variables matching "color"
|
|
10595
|
+
fig library components List available library components
|
|
10596
|
+
fig library components --name "button" Find button components
|
|
10597
|
+
fig library import --key "abc123..." Import a component by its key
|
|
10598
|
+
fig library import --key "abc123..." --name "MyButton" Import and rename
|
|
10599
|
+
`)
|
|
10600
|
+
.action(async (action, options) => {
|
|
10601
|
+
checkConnection();
|
|
10602
|
+
const spinner = ora('Accessing library...').start();
|
|
10603
|
+
|
|
10604
|
+
try {
|
|
10605
|
+
if (action === 'collections') {
|
|
10606
|
+
spinner.text = 'Fetching library variable collections...';
|
|
10607
|
+
const code = `(async function() {
|
|
10608
|
+
try {
|
|
10609
|
+
var cols = await figma.teamLibrary.getAvailableLibraryVariableCollectionsAsync();
|
|
10610
|
+
return cols.map(function(c) {
|
|
10611
|
+
return { name: c.name, key: c.key, libraryName: c.libraryName };
|
|
10612
|
+
});
|
|
10613
|
+
} catch(e) {
|
|
10614
|
+
return { error: e.message || 'Failed to fetch library collections. Make sure teamlibrary permission is enabled.' };
|
|
10615
|
+
}
|
|
10616
|
+
})()`;
|
|
10617
|
+
const result = await daemonExec('eval', { code });
|
|
10618
|
+
if (result.error) {
|
|
10619
|
+
spinner.fail(result.error);
|
|
10620
|
+
process.exit(1);
|
|
10621
|
+
}
|
|
10622
|
+
spinner.succeed(`Found ${result.length} library variable collection${result.length !== 1 ? 's' : ''}`);
|
|
10623
|
+
if (options.json) {
|
|
10624
|
+
console.log(JSON.stringify(result, null, 2));
|
|
10625
|
+
} else {
|
|
10626
|
+
if (result.length === 0) {
|
|
10627
|
+
console.log(chalk.yellow('No library variable collections found. Make sure you have libraries enabled in this file.'));
|
|
10628
|
+
}
|
|
10629
|
+
for (const col of result) {
|
|
10630
|
+
console.log(` ${chalk.cyan(col.name)} ${chalk.gray('from')} ${chalk.white(col.libraryName)}`);
|
|
10631
|
+
console.log(` ${chalk.gray('key:')} ${col.key}`);
|
|
10632
|
+
}
|
|
10633
|
+
}
|
|
10634
|
+
} else if (action === 'variables') {
|
|
10635
|
+
spinner.text = 'Fetching library variables...';
|
|
10636
|
+
const nameFilter = options.name ? options.name.toLowerCase() : '';
|
|
10637
|
+
const code = `(async function() {
|
|
10638
|
+
try {
|
|
10639
|
+
var cols = await figma.teamLibrary.getAvailableLibraryVariableCollectionsAsync();
|
|
10640
|
+
var allVars = [];
|
|
10641
|
+
for (var i = 0; i < cols.length; i++) {
|
|
10642
|
+
try {
|
|
10643
|
+
var vars = await figma.teamLibrary.getVariablesInLibraryCollectionAsync(cols[i].key);
|
|
10644
|
+
for (var j = 0; j < vars.length; j++) {
|
|
10645
|
+
allVars.push({
|
|
10646
|
+
name: vars[j].name,
|
|
10647
|
+
key: vars[j].key,
|
|
10648
|
+
resolvedType: vars[j].resolvedType,
|
|
10649
|
+
collection: cols[i].name,
|
|
10650
|
+
library: cols[i].libraryName
|
|
10651
|
+
});
|
|
10652
|
+
}
|
|
10653
|
+
} catch(e2) {}
|
|
10654
|
+
}
|
|
10655
|
+
${nameFilter ? `allVars = allVars.filter(function(v) { return v.name.toLowerCase().indexOf('${nameFilter}') !== -1; });` : ''}
|
|
10656
|
+
return allVars;
|
|
10657
|
+
} catch(e) {
|
|
10658
|
+
return { error: e.message || 'Failed to fetch library variables.' };
|
|
10659
|
+
}
|
|
10660
|
+
})()`;
|
|
10661
|
+
const result = await daemonExec('eval', { code });
|
|
10662
|
+
if (result.error) {
|
|
10663
|
+
spinner.fail(result.error);
|
|
10664
|
+
process.exit(1);
|
|
10665
|
+
}
|
|
10666
|
+
spinner.succeed(`Found ${result.length} library variable${result.length !== 1 ? 's' : ''}`);
|
|
10667
|
+
if (options.json) {
|
|
10668
|
+
console.log(JSON.stringify(result, null, 2));
|
|
10669
|
+
} else {
|
|
10670
|
+
if (result.length === 0) {
|
|
10671
|
+
console.log(chalk.yellow('No variables found.' + (nameFilter ? ` Try a different search term.` : '')));
|
|
10672
|
+
}
|
|
10673
|
+
let currentCollection = '';
|
|
10674
|
+
for (const v of result) {
|
|
10675
|
+
const collLabel = `${v.collection} (${v.library})`;
|
|
10676
|
+
if (collLabel !== currentCollection) {
|
|
10677
|
+
currentCollection = collLabel;
|
|
10678
|
+
console.log(chalk.cyan(`\n ${collLabel}`));
|
|
10679
|
+
}
|
|
10680
|
+
console.log(` ${chalk.white(v.name)} ${chalk.gray(`[${v.resolvedType}]`)} ${chalk.gray('key:')} ${v.key}`);
|
|
10681
|
+
}
|
|
10682
|
+
}
|
|
10683
|
+
} else if (action === 'components') {
|
|
10684
|
+
spinner.text = 'Fetching library components...';
|
|
10685
|
+
const nameFilter = options.name ? options.name.toLowerCase() : '';
|
|
10686
|
+
const code = `(async function() {
|
|
10687
|
+
try {
|
|
10688
|
+
var collections = await figma.teamLibrary.getAvailableLibraryVariableCollectionsAsync();
|
|
10689
|
+
var libraryNames = collections.map(function(c) { return c.libraryName; });
|
|
10690
|
+
} catch(e) { var libraryNames = []; }
|
|
10691
|
+
try {
|
|
10692
|
+
// Get components from the assets panel search
|
|
10693
|
+
var components = [];
|
|
10694
|
+
// Try to find components by listing component sets and instances on the current page
|
|
10695
|
+
function findComponents(node) {
|
|
10696
|
+
if (node.type === 'INSTANCE' && node.mainComponent) {
|
|
10697
|
+
try {
|
|
10698
|
+
var mc = node.mainComponent;
|
|
10699
|
+
var parent = mc.parent;
|
|
10700
|
+
components.push({
|
|
10701
|
+
name: mc.name,
|
|
10702
|
+
key: mc.key,
|
|
10703
|
+
componentSetName: parent && parent.type === 'COMPONENT_SET' ? parent.name : null,
|
|
10704
|
+
description: mc.description || '',
|
|
10705
|
+
remote: mc.remote
|
|
10706
|
+
});
|
|
10707
|
+
} catch(e) {}
|
|
10708
|
+
}
|
|
10709
|
+
if ('children' in node) {
|
|
10710
|
+
for (var i = 0; i < node.children.length; i++) {
|
|
10711
|
+
findComponents(node.children[i]);
|
|
10712
|
+
}
|
|
10713
|
+
}
|
|
10714
|
+
}
|
|
10715
|
+
findComponents(figma.currentPage);
|
|
10716
|
+
// Deduplicate by key
|
|
10717
|
+
var seen = {};
|
|
10718
|
+
var unique = [];
|
|
10719
|
+
for (var i = 0; i < components.length; i++) {
|
|
10720
|
+
if (!seen[components[i].key]) {
|
|
10721
|
+
seen[components[i].key] = true;
|
|
10722
|
+
unique.push(components[i]);
|
|
10723
|
+
}
|
|
10724
|
+
}
|
|
10725
|
+
${nameFilter ? `unique = unique.filter(function(c) { return c.name.toLowerCase().indexOf('${nameFilter}') !== -1 || (c.componentSetName && c.componentSetName.toLowerCase().indexOf('${nameFilter}') !== -1); });` : ''}
|
|
10726
|
+
return { components: unique, note: unique.length === 0 ? 'No library components found on this page. Drag some components from the Assets panel first, or use fig library import --key <key> if you have the component key.' : null };
|
|
10727
|
+
} catch(e) {
|
|
10728
|
+
return { error: e.message || 'Failed to fetch library components.' };
|
|
10729
|
+
}
|
|
10730
|
+
})()`;
|
|
10731
|
+
const result = await daemonExec('eval', { code });
|
|
10732
|
+
if (result.error) {
|
|
10733
|
+
spinner.fail(result.error);
|
|
10734
|
+
process.exit(1);
|
|
10735
|
+
}
|
|
10736
|
+
const comps = result.components || [];
|
|
10737
|
+
spinner.succeed(`Found ${comps.length} component${comps.length !== 1 ? 's' : ''} on this page`);
|
|
10738
|
+
if (options.json) {
|
|
10739
|
+
console.log(JSON.stringify(result, null, 2));
|
|
10740
|
+
} else {
|
|
10741
|
+
if (result.note) {
|
|
10742
|
+
console.log(chalk.yellow(` ${result.note}`));
|
|
10743
|
+
}
|
|
10744
|
+
for (const c of comps) {
|
|
10745
|
+
const setLabel = c.componentSetName ? chalk.gray(` (set: ${c.componentSetName})`) : '';
|
|
10746
|
+
const remoteLabel = c.remote ? chalk.blue(' [library]') : chalk.gray(' [local]');
|
|
10747
|
+
console.log(` ${chalk.white(c.name)}${setLabel}${remoteLabel}`);
|
|
10748
|
+
console.log(` ${chalk.gray('key:')} ${c.key}`);
|
|
10749
|
+
if (c.description) console.log(` ${chalk.gray('desc:')} ${c.description}`);
|
|
10750
|
+
}
|
|
10751
|
+
}
|
|
10752
|
+
} else if (action === 'import') {
|
|
10753
|
+
if (!options.key) {
|
|
10754
|
+
spinner.fail('--key is required. Get the key from: fig library components, or fig library variables');
|
|
10755
|
+
process.exit(1);
|
|
10756
|
+
}
|
|
10757
|
+
spinner.text = `Importing component ${options.key}...`;
|
|
10758
|
+
const importName = options.name || '';
|
|
10759
|
+
const code = `(async function() {
|
|
10760
|
+
try {
|
|
10761
|
+
var component = await figma.importComponentByKeyAsync('${options.key}');
|
|
10762
|
+
if (!component) return { error: 'Component not found for key: ${options.key}' };
|
|
10763
|
+
// Create an instance
|
|
10764
|
+
var instance = component.createInstance();
|
|
10765
|
+
// Place it in the center of the viewport
|
|
10766
|
+
var vp = figma.viewport.center;
|
|
10767
|
+
instance.x = Math.round(vp.x);
|
|
10768
|
+
instance.y = Math.round(vp.y);
|
|
10769
|
+
${importName ? `instance.name = '${importName}';` : ''}
|
|
10770
|
+
figma.currentPage.selection = [instance];
|
|
10771
|
+
return {
|
|
10772
|
+
name: instance.name,
|
|
10773
|
+
id: instance.id,
|
|
10774
|
+
componentName: component.name,
|
|
10775
|
+
w: Math.round(instance.width),
|
|
10776
|
+
h: Math.round(instance.height)
|
|
10777
|
+
};
|
|
10778
|
+
} catch(e) {
|
|
10779
|
+
return { error: e.message || 'Failed to import component. Check the key is valid.' };
|
|
10780
|
+
}
|
|
10781
|
+
})()`;
|
|
10782
|
+
const result = await daemonExec('eval', { code });
|
|
10783
|
+
if (result.error) {
|
|
10784
|
+
spinner.fail(result.error);
|
|
10785
|
+
process.exit(1);
|
|
10786
|
+
}
|
|
10787
|
+
spinner.succeed(`Imported "${result.componentName}" as ${result.name} (${result.w}x${result.h})`);
|
|
10788
|
+
console.log(` ${chalk.gray('id:')} ${result.id}`);
|
|
10789
|
+
console.log(chalk.gray(' Component is now selected on the canvas.'));
|
|
10790
|
+
} else {
|
|
10791
|
+
spinner.fail(`Unknown action: ${action}. Use: collections, variables, components, import`);
|
|
10792
|
+
process.exit(1);
|
|
10793
|
+
}
|
|
10794
|
+
} catch (e) {
|
|
10795
|
+
spinner.fail(`Library access failed: ${e.message}`);
|
|
10796
|
+
process.exit(1);
|
|
10797
|
+
}
|
|
10798
|
+
});
|
|
10799
|
+
|
|
10444
10800
|
program.parse();
|