Sign In

@rotifer/playground

Package Overview
Dependencies
Maintainers
1
Versions
22
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@rotifer/playground - npm Package Compare versions

Comparing version
0.7.8
to
0.7.9
+3
dist/commands/vg.d.ts
import { Command } from "commander";
export declare const vgCommand: Command;
//# sourceMappingURL=vg.d.ts.map
{"version":3,"file":"vg.d.ts","sourceRoot":"","sources":["../../src/commands/vg.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA4BpC,eAAO,MAAM,SAAS,SA4DlB,CAAC"}
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.vgCommand = void 0;
const commander_1 = require("commander");
const node_path_1 = require("node:path");
const chalk_1 = __importDefault(require("chalk"));
const index_js_1 = require("../scanner/index.js");
const display = __importStar(require("../utils/display.js"));
const GRADE_COLORS = {
A: chalk_1.default.green,
B: chalk_1.default.greenBright,
C: chalk_1.default.yellow,
D: chalk_1.default.red,
"?": chalk_1.default.gray,
};
const SEVERITY_COLORS = {
CRITICAL: chalk_1.default.red.bold,
HIGH: chalk_1.default.yellow,
MEDIUM: chalk_1.default.dim,
};
function printFinding(f) {
const sev = SEVERITY_COLORS[f.severity]?.(f.severity) ?? f.severity;
const loc = chalk_1.default.dim(`${f.file}:${f.line}`);
console.log(` ${sev} [${f.rule}] ${loc}`);
console.log(` ${chalk_1.default.dim(f.snippet)}`);
}
exports.vgCommand = new commander_1.Command("vg")
.description("V(g) security scan — static analysis for Skill/Gene code safety")
.argument("[path]", "path to Skill or Gene directory", ".")
.option("--id <skill_id>", "skill/gene identifier for the report")
.option("--json", "output raw JSON report")
.option("--all", "scan all code files, not just src/")
.action((pathArg, opts) => {
const dir = (0, node_path_1.resolve)(pathArg);
const result = (0, index_js_1.scan)(dir, opts.id, { scanAll: opts.all });
if (opts.json) {
console.log(JSON.stringify(result, null, 2));
return;
}
display.header("V(g) Security Scan");
if (result.grade === "?") {
display.info(`No src/ directory found — grade: ${chalk_1.default.gray("?")}`);
display.info("Pure-prompt Skills without code receive grade \"?\".");
return;
}
const gradeColor = GRADE_COLORS[result.grade] ?? chalk_1.default.white;
display.keyValue("Skill", result.skill_id);
display.keyValue("Files scanned", String(result.stats.files_scanned));
display.keyValue("Lines of code", String(result.stats.lines_of_code));
display.keyValue("Grade", gradeColor(result.grade));
if (result.findings.length === 0) {
console.log();
display.success("No security findings — grade A");
return;
}
console.log();
const criticals = result.findings.filter((f) => f.severity === "CRITICAL");
const highs = result.findings.filter((f) => f.severity === "HIGH");
const mediums = result.findings.filter((f) => f.severity === "MEDIUM");
if (criticals.length > 0) {
console.log(chalk_1.default.red.bold(` CRITICAL (${criticals.length}):`));
criticals.forEach(printFinding);
}
if (highs.length > 0) {
console.log(chalk_1.default.yellow(` HIGH (${highs.length}):`));
highs.forEach(printFinding);
}
if (mediums.length > 0) {
console.log(chalk_1.default.dim(` MEDIUM (${mediums.length}):`));
mediums.forEach(printFinding);
}
console.log();
console.log(chalk_1.default.dim(" Disclaimer: Static analysis only. Not a substitute for"));
console.log(chalk_1.default.dim(" manual review or runtime sandboxing. See rotifer.dev/badge"));
});
//# sourceMappingURL=vg.js.map
{"version":3,"file":"vg.js","sourceRoot":"","sources":["../../src/commands/vg.ts"],"names":[],"mappings":"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"}
export { scan, scanFile, computeGrade } from "./scanner.js";
export type { ScanOptions } from "./scanner.js";
export { SCAN_RULES } from "./rules.js";
export type { ScanResult, Finding, Grade, Severity, ScanRule } from "./types.js";
//# sourceMappingURL=index.d.ts.map
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/scanner/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5D,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,YAAY,EAAE,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC"}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SCAN_RULES = exports.computeGrade = exports.scanFile = exports.scan = void 0;
var scanner_js_1 = require("./scanner.js");
Object.defineProperty(exports, "scan", { enumerable: true, get: function () { return scanner_js_1.scan; } });
Object.defineProperty(exports, "scanFile", { enumerable: true, get: function () { return scanner_js_1.scanFile; } });
Object.defineProperty(exports, "computeGrade", { enumerable: true, get: function () { return scanner_js_1.computeGrade; } });
var rules_js_1 = require("./rules.js");
Object.defineProperty(exports, "SCAN_RULES", { enumerable: true, get: function () { return rules_js_1.SCAN_RULES; } });
//# sourceMappingURL=index.js.map
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/scanner/index.ts"],"names":[],"mappings":";;;AAAA,2CAA4D;AAAnD,kGAAA,IAAI,OAAA;AAAE,sGAAA,QAAQ,OAAA;AAAE,0GAAA,YAAY,OAAA;AAErC,uCAAwC;AAA/B,sGAAA,UAAU,OAAA"}
import type { ScanRule } from "./types.js";
export declare const SCAN_RULES: ScanRule[];
//# sourceMappingURL=rules.d.ts.map
{"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../../src/scanner/rules.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,eAAO,MAAM,UAAU,EAAE,QAAQ,EAyFhC,CAAC"}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SCAN_RULES = void 0;
exports.SCAN_RULES = [
{
id: "S-01",
description: "Dynamic code execution",
severity: "CRITICAL",
patterns: [
/\beval\s*\(/,
/\bFunction\s*\(/,
/new\s+Function\s*\(/,
],
},
{
id: "S-02",
description: "System command execution",
severity: "CRITICAL",
patterns: [
/require\s*\(\s*['"]child_process['"]\s*\)/,
/from\s+['"]child_process['"]/,
/\bexec\s*\(/,
/\bexecSync\s*\(/,
/\bspawn\s*\(/,
/\bspawnSync\s*\(/,
],
},
{
id: "S-03",
description: "Code obfuscation (base64 decode + execute)",
severity: "CRITICAL",
patterns: [
/\batob\s*\([^)]*\)\s*.*\beval\b/,
/\beval\s*\(\s*atob\b/,
/Buffer\.from\s*\([^)]*,\s*['"]base64['"]\s*\).*\beval\b/,
/\bdecodeURIComponent\s*\(\s*escape\s*\(\s*atob\b/,
],
},
{
id: "S-04",
description: "Suspicious external communication",
severity: "HIGH",
patterns: [
/\bfetch\s*\(/,
/\bhttp\.request\s*\(/,
/\bhttps\.request\s*\(/,
/new\s+XMLHttpRequest\s*\(/,
/\baxios\s*[.(]/,
],
},
{
id: "S-05",
description: "Environment variable access",
severity: "HIGH",
patterns: [
/\bprocess\.env\b/,
/\bDeno\.env\b/,
/\bos\.environ\b/,
/\bimport\.meta\.env\b/,
],
},
{
id: "S-06",
description: "Persistent outbound connection",
severity: "HIGH",
patterns: [
/new\s+WebSocket\s*\(/,
/\bnet\.Socket\s*\(/,
/new\s+net\.Socket\s*\(/,
/\bnet\.createConnection\s*\(/,
/\btls\.connect\s*\(/,
],
},
{
id: "S-07",
description: "File system operations",
severity: "MEDIUM",
patterns: [
/\bfs\.readFile\b/,
/\bfs\.readFileSync\b/,
/\bfs\.writeFile\b/,
/\bfs\.writeFileSync\b/,
/\bfs\.unlink\b/,
/\bfs\.unlinkSync\b/,
/\bfs\.rmSync\b/,
/\bfs\.rm\b/,
/\bfs\.mkdir\b/,
/\bfs\.mkdirSync\b/,
/\breadFileSync\s*\(/,
/\bwriteFileSync\s*\(/,
],
},
];
//# sourceMappingURL=rules.js.map
{"version":3,"file":"rules.js","sourceRoot":"","sources":["../../src/scanner/rules.ts"],"names":[],"mappings":";;;AAEa,QAAA,UAAU,GAAe;IACpC;QACE,EAAE,EAAE,MAAM;QACV,WAAW,EAAE,wBAAwB;QACrC,QAAQ,EAAE,UAAU;QACpB,QAAQ,EAAE;YACR,aAAa;YACb,iBAAiB;YACjB,qBAAqB;SACtB;KACF;IACD;QACE,EAAE,EAAE,MAAM;QACV,WAAW,EAAE,0BAA0B;QACvC,QAAQ,EAAE,UAAU;QACpB,QAAQ,EAAE;YACR,2CAA2C;YAC3C,8BAA8B;YAC9B,aAAa;YACb,iBAAiB;YACjB,cAAc;YACd,kBAAkB;SACnB;KACF;IACD;QACE,EAAE,EAAE,MAAM;QACV,WAAW,EAAE,4CAA4C;QACzD,QAAQ,EAAE,UAAU;QACpB,QAAQ,EAAE;YACR,iCAAiC;YACjC,sBAAsB;YACtB,yDAAyD;YACzD,kDAAkD;SACnD;KACF;IACD;QACE,EAAE,EAAE,MAAM;QACV,WAAW,EAAE,mCAAmC;QAChD,QAAQ,EAAE,MAAM;QAChB,QAAQ,EAAE;YACR,cAAc;YACd,sBAAsB;YACtB,uBAAuB;YACvB,2BAA2B;YAC3B,gBAAgB;SACjB;KACF;IACD;QACE,EAAE,EAAE,MAAM;QACV,WAAW,EAAE,6BAA6B;QAC1C,QAAQ,EAAE,MAAM;QAChB,QAAQ,EAAE;YACR,kBAAkB;YAClB,eAAe;YACf,iBAAiB;YACjB,uBAAuB;SACxB;KACF;IACD;QACE,EAAE,EAAE,MAAM;QACV,WAAW,EAAE,gCAAgC;QAC7C,QAAQ,EAAE,MAAM;QAChB,QAAQ,EAAE;YACR,sBAAsB;YACtB,oBAAoB;YACpB,wBAAwB;YACxB,8BAA8B;YAC9B,qBAAqB;SACtB;KACF;IACD;QACE,EAAE,EAAE,MAAM;QACV,WAAW,EAAE,wBAAwB;QACrC,QAAQ,EAAE,QAAQ;QAClB,QAAQ,EAAE;YACR,kBAAkB;YAClB,sBAAsB;YACtB,mBAAmB;YACnB,uBAAuB;YACvB,gBAAgB;YAChB,oBAAoB;YACpB,gBAAgB;YAChB,YAAY;YACZ,eAAe;YACf,mBAAmB;YACnB,qBAAqB;YACrB,sBAAsB;SACvB;KACF;CACF,CAAC"}
import type { Finding, Grade, ScanResult } from "./types.js";
export declare function scanFile(filePath: string, rootDir: string): Finding[];
export declare function computeGrade(findings: Finding[]): Grade;
export interface ScanOptions {
scanAll?: boolean;
}
export declare function scan(dir: string, skillId?: string, options?: ScanOptions): ScanResult;
//# sourceMappingURL=scanner.d.ts.map
{"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../../src/scanner/scanner.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AA0B7D,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,EAAE,CA2BrE;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,KAAK,CAQvD;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,wBAAgB,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,UAAU,CAkCrF"}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.scanFile = scanFile;
exports.computeGrade = computeGrade;
exports.scan = scan;
const node_fs_1 = require("node:fs");
const node_path_1 = require("node:path");
const rules_js_1 = require("./rules.js");
const CODE_EXTENSIONS = new Set([".ts", ".js", ".mts", ".mjs", ".cjs", ".tsx", ".jsx", ".sh", ".py"]);
function collectCodeFiles(dir) {
const files = [];
const walk = (d) => {
for (const entry of (0, node_fs_1.readdirSync)(d)) {
if (entry === "node_modules" || entry === ".git" || entry === "dist")
continue;
const full = (0, node_path_1.join)(d, entry);
const st = (0, node_fs_1.statSync)(full);
if (st.isDirectory()) {
walk(full);
}
else if (CODE_EXTENSIONS.has((0, node_path_1.extname)(entry))) {
files.push(full);
}
}
};
walk(dir);
return files;
}
function hasSrcDirectory(dir) {
return (0, node_fs_1.existsSync)((0, node_path_1.join)(dir, "src"));
}
function scanFile(filePath, rootDir) {
const content = (0, node_fs_1.readFileSync)(filePath, "utf-8");
const lines = content.split("\n");
const relPath = (0, node_path_1.relative)(rootDir, filePath);
const findings = [];
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
if (line.trimStart().startsWith("//") || line.trimStart().startsWith("*"))
continue;
for (const rule of rules_js_1.SCAN_RULES) {
for (const pattern of rule.patterns) {
if (pattern.test(line)) {
findings.push({
rule: rule.id,
severity: rule.severity,
file: relPath,
line: i + 1,
snippet: line.trim().slice(0, 120),
});
break;
}
}
}
}
return findings;
}
function computeGrade(findings) {
const criticals = findings.filter((f) => f.severity === "CRITICAL").length;
const highs = findings.filter((f) => f.severity === "HIGH").length;
if (criticals >= 1)
return "D";
if (highs > 2)
return "C";
if (highs > 0)
return "B";
return "A";
}
function scan(dir, skillId, options) {
const scanAll = options?.scanAll ?? false;
if (!scanAll && !hasSrcDirectory(dir)) {
return {
skill_id: skillId ?? dir,
scanned_at: new Date().toISOString(),
grade: "?",
findings: [],
stats: { files_scanned: 0, lines_of_code: 0 },
};
}
const scanDir = scanAll ? dir : (0, node_path_1.join)(dir, "src");
const files = collectCodeFiles(scanDir);
const allFindings = [];
let totalLines = 0;
for (const file of files) {
const content = (0, node_fs_1.readFileSync)(file, "utf-8");
totalLines += content.split("\n").length;
allFindings.push(...scanFile(file, dir));
}
return {
skill_id: skillId ?? dir,
scanned_at: new Date().toISOString(),
grade: computeGrade(allFindings),
findings: allFindings,
stats: {
files_scanned: files.length,
lines_of_code: totalLines,
},
};
}
//# sourceMappingURL=scanner.js.map
{"version":3,"file":"scanner.js","sourceRoot":"","sources":["../../src/scanner/scanner.ts"],"names":[],"mappings":"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"}
export type Severity = "CRITICAL" | "HIGH" | "MEDIUM";
export type Grade = "A" | "B" | "C" | "D" | "?";
export interface ScanRule {
id: string;
description: string;
severity: Severity;
patterns: RegExp[];
}
export interface Finding {
rule: string;
severity: Severity;
file: string;
line: number;
snippet: string;
note?: string;
}
export interface ScanResult {
skill_id: string;
scanned_at: string;
grade: Grade;
findings: Finding[];
stats: {
files_scanned: number;
lines_of_code: number;
};
}
//# sourceMappingURL=types.d.ts.map
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/scanner/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,CAAC;AACtD,MAAM,MAAM,KAAK,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAEhD,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,QAAQ,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,QAAQ,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,KAAK,EAAE;QACL,aAAa,EAAE,MAAM,CAAC;QACtB,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;CACH"}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=types.js.map
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/scanner/types.ts"],"names":[],"mappings":""}
+11
-0

@@ -8,2 +8,13 @@ # Changelog

## [0.7.9] - 2026-03-20
### Added
- **V(g) security scanner** — static analysis engine with 7 rules (S-01 to S-07) detecting dynamic code execution, system commands, obfuscation, external communication, env access, persistent connections, and filesystem operations
- **CLI: `rotifer vg [path]`** — run V(g) security scan on any Skill or Gene directory with `--json`, `--all`, `--id` options
- **Security grade mapping** — A/B/C/D/? grades based on finding severity (CRITICAL/HIGH/MEDIUM)
- Scanner supports `.ts`, `.js`, `.mts`, `.mjs`, `.cjs`, `.tsx`, `.jsx`, `.sh`, `.py` file extensions
- Comment-line skipping in scan results to reduce false positives
- Unit tests: scanner rules (S-01 to S-07 pattern matching) and scanner core (grade computation, file collection, edge cases)
## [0.7.8] - 2026-02-17

@@ -10,0 +21,0 @@

+2
-0

@@ -32,2 +32,3 @@ #!/usr/bin/env node

const network_js_1 = require("./commands/network.js");
const vg_js_1 = require("./commands/vg.js");
const pkg = JSON.parse((0, node_fs_1.readFileSync)((0, node_path_1.join)(__dirname, "..", "package.json"), "utf-8"));

@@ -66,3 +67,4 @@ const program = new commander_1.Command();

program.addCommand(network_js_1.networkCommand);
program.addCommand(vg_js_1.vgCommand);
program.parse();
//# sourceMappingURL=index.js.map
+1
-1

@@ -1,1 +0,1 @@

{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAEA,yCAAoC;AACpC,qCAAuC;AACvC,yCAAiC;AACjC,gDAAiD;AACjD,gDAAiD;AACjD,gDAAiD;AACjD,gDAAiD;AACjD,sDAAuD;AACvD,gEAAgE;AAChE,4DAA4D;AAC5D,8DAA8D;AAC9D,gEAAgE;AAChE,4DAA4D;AAC5D,0DAA0D;AAC1D,kDAAmD;AACnD,oDAAqD;AACrD,sDAAuD;AACvD,oDAAqD;AACrD,sDAAuD;AACvD,4DAA6D;AAC7D,gDAAiD;AACjD,gDAAiD;AACjD,8CAA+C;AAC/C,wDAAyD;AACzD,oDAAqD;AACrD,kDAAmD;AACnD,sDAAuD;AACvD,sDAAuD;AAEvD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAA,sBAAY,EAAC,IAAA,gBAAI,EAAC,SAAS,EAAE,IAAI,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;AAErF,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,SAAS,CAAC;KACf,WAAW,CACV,uEAAuE,CACxE;KACA,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AAExB,OAAO,CAAC,UAAU,CAAC,qBAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,qBAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,qBAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,qBAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,2BAAc,CAAC,CAAC;AAEnC,OAAO,CAAC,UAAU,CAAC,uBAAY,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,yBAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,2BAAc,CAAC,CAAC;AACnC,OAAO,CAAC,UAAU,CAAC,yBAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,2BAAc,CAAC,CAAC;AACnC,OAAO,CAAC,UAAU,CAAC,iCAAiB,CAAC,CAAC;AACtC,OAAO,CAAC,UAAU,CAAC,qBAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,qBAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,mBAAU,CAAC,CAAC;AAC/B,OAAO,CAAC,UAAU,CAAC,6BAAe,CAAC,CAAC;AACpC,OAAO,CAAC,UAAU,CAAC,yBAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,uBAAY,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,2BAAc,CAAC,CAAC;AAEnC,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,4BAA4B,CAAC,CAAC;AACjF,KAAK,CAAC,UAAU,CAAC,oCAAkB,CAAC,CAAC;AACrC,KAAK,CAAC,UAAU,CAAC,gCAAgB,CAAC,CAAC;AACnC,KAAK,CAAC,UAAU,CAAC,kCAAiB,CAAC,CAAC;AAEpC,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,0BAA0B,CAAC,CAAC;AAC/E,KAAK,CAAC,UAAU,CAAC,oCAAkB,CAAC,CAAC;AACrC,KAAK,CAAC,UAAU,CAAC,gCAAgB,CAAC,CAAC;AACnC,KAAK,CAAC,UAAU,CAAC,8BAAe,CAAC,CAAC;AAElC,OAAO,CAAC,UAAU,CAAC,2BAAc,CAAC,CAAC;AAEnC,OAAO,CAAC,KAAK,EAAE,CAAC"}
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAEA,yCAAoC;AACpC,qCAAuC;AACvC,yCAAiC;AACjC,gDAAiD;AACjD,gDAAiD;AACjD,gDAAiD;AACjD,gDAAiD;AACjD,sDAAuD;AACvD,gEAAgE;AAChE,4DAA4D;AAC5D,8DAA8D;AAC9D,gEAAgE;AAChE,4DAA4D;AAC5D,0DAA0D;AAC1D,kDAAmD;AACnD,oDAAqD;AACrD,sDAAuD;AACvD,oDAAqD;AACrD,sDAAuD;AACvD,4DAA6D;AAC7D,gDAAiD;AACjD,gDAAiD;AACjD,8CAA+C;AAC/C,wDAAyD;AACzD,oDAAqD;AACrD,kDAAmD;AACnD,sDAAuD;AACvD,sDAAuD;AACvD,4CAA6C;AAE7C,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAA,sBAAY,EAAC,IAAA,gBAAI,EAAC,SAAS,EAAE,IAAI,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;AAErF,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,SAAS,CAAC;KACf,WAAW,CACV,uEAAuE,CACxE;KACA,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AAExB,OAAO,CAAC,UAAU,CAAC,qBAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,qBAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,qBAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,qBAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,2BAAc,CAAC,CAAC;AAEnC,OAAO,CAAC,UAAU,CAAC,uBAAY,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,yBAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,2BAAc,CAAC,CAAC;AACnC,OAAO,CAAC,UAAU,CAAC,yBAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,2BAAc,CAAC,CAAC;AACnC,OAAO,CAAC,UAAU,CAAC,iCAAiB,CAAC,CAAC;AACtC,OAAO,CAAC,UAAU,CAAC,qBAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,qBAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,mBAAU,CAAC,CAAC;AAC/B,OAAO,CAAC,UAAU,CAAC,6BAAe,CAAC,CAAC;AACpC,OAAO,CAAC,UAAU,CAAC,yBAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,uBAAY,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,2BAAc,CAAC,CAAC;AAEnC,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,4BAA4B,CAAC,CAAC;AACjF,KAAK,CAAC,UAAU,CAAC,oCAAkB,CAAC,CAAC;AACrC,KAAK,CAAC,UAAU,CAAC,gCAAgB,CAAC,CAAC;AACnC,KAAK,CAAC,UAAU,CAAC,kCAAiB,CAAC,CAAC;AAEpC,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,0BAA0B,CAAC,CAAC;AAC/E,KAAK,CAAC,UAAU,CAAC,oCAAkB,CAAC,CAAC;AACrC,KAAK,CAAC,UAAU,CAAC,gCAAgB,CAAC,CAAC;AACnC,KAAK,CAAC,UAAU,CAAC,8BAAe,CAAC,CAAC;AAElC,OAAO,CAAC,UAAU,CAAC,2BAAc,CAAC,CAAC;AACnC,OAAO,CAAC,UAAU,CAAC,iBAAS,CAAC,CAAC;AAE9B,OAAO,CAAC,KAAK,EAAE,CAAC"}
{
"name": "@rotifer/playground",
"version": "0.7.8",
"version": "0.7.9",
"description": "Rotifer Protocol Playground — local development environment for gene development, Arena competition, and protocol simulation",

@@ -5,0 +5,0 @@ "license": "Apache-2.0",