stylus-toolkit 0.1.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.
Files changed (78) hide show
  1. package/.claude/settings.local.json +20 -0
  2. package/CHANGELOG.md +30 -0
  3. package/CONTRIBUTING.md +50 -0
  4. package/LICENSE +21 -0
  5. package/README.md +132 -0
  6. package/dist/cli.d.ts +3 -0
  7. package/dist/cli.d.ts.map +1 -0
  8. package/dist/cli.js +62 -0
  9. package/dist/cli.js.map +1 -0
  10. package/dist/commands/benchmark.d.ts +3 -0
  11. package/dist/commands/benchmark.d.ts.map +1 -0
  12. package/dist/commands/benchmark.js +18 -0
  13. package/dist/commands/benchmark.js.map +1 -0
  14. package/dist/commands/config.d.ts +9 -0
  15. package/dist/commands/config.d.ts.map +1 -0
  16. package/dist/commands/config.js +63 -0
  17. package/dist/commands/config.js.map +1 -0
  18. package/dist/commands/init.d.ts +3 -0
  19. package/dist/commands/init.d.ts.map +1 -0
  20. package/dist/commands/init.js +115 -0
  21. package/dist/commands/init.js.map +1 -0
  22. package/dist/commands/profile.d.ts +3 -0
  23. package/dist/commands/profile.d.ts.map +1 -0
  24. package/dist/commands/profile.js +160 -0
  25. package/dist/commands/profile.js.map +1 -0
  26. package/dist/compiler/rust-compiler.d.ts +12 -0
  27. package/dist/compiler/rust-compiler.d.ts.map +1 -0
  28. package/dist/compiler/rust-compiler.js +141 -0
  29. package/dist/compiler/rust-compiler.js.map +1 -0
  30. package/dist/compiler/solidity-compiler.d.ts +10 -0
  31. package/dist/compiler/solidity-compiler.d.ts.map +1 -0
  32. package/dist/compiler/solidity-compiler.js +160 -0
  33. package/dist/compiler/solidity-compiler.js.map +1 -0
  34. package/dist/exporter/exporter.d.ts +13 -0
  35. package/dist/exporter/exporter.d.ts.map +1 -0
  36. package/dist/exporter/exporter.js +322 -0
  37. package/dist/exporter/exporter.js.map +1 -0
  38. package/dist/index.d.ts +11 -0
  39. package/dist/index.d.ts.map +1 -0
  40. package/dist/index.js +37 -0
  41. package/dist/index.js.map +1 -0
  42. package/dist/profiler/comparator.d.ts +10 -0
  43. package/dist/profiler/comparator.d.ts.map +1 -0
  44. package/dist/profiler/comparator.js +96 -0
  45. package/dist/profiler/comparator.js.map +1 -0
  46. package/dist/profiler/gas-profiler.d.ts +11 -0
  47. package/dist/profiler/gas-profiler.d.ts.map +1 -0
  48. package/dist/profiler/gas-profiler.js +143 -0
  49. package/dist/profiler/gas-profiler.js.map +1 -0
  50. package/dist/storage/results-store.d.ts +16 -0
  51. package/dist/storage/results-store.d.ts.map +1 -0
  52. package/dist/storage/results-store.js +107 -0
  53. package/dist/storage/results-store.js.map +1 -0
  54. package/dist/templates/generator.d.ts +11 -0
  55. package/dist/templates/generator.d.ts.map +1 -0
  56. package/dist/templates/generator.js +135 -0
  57. package/dist/templates/generator.js.map +1 -0
  58. package/dist/templates/templates.d.ts +2 -0
  59. package/dist/templates/templates.d.ts.map +1 -0
  60. package/dist/templates/templates.js +324 -0
  61. package/dist/templates/templates.js.map +1 -0
  62. package/dist/types/index.d.ts +115 -0
  63. package/dist/types/index.d.ts.map +1 -0
  64. package/dist/types/index.js +3 -0
  65. package/dist/types/index.js.map +1 -0
  66. package/dist/utils/config.d.ts +15 -0
  67. package/dist/utils/config.d.ts.map +1 -0
  68. package/dist/utils/config.js +77 -0
  69. package/dist/utils/config.js.map +1 -0
  70. package/dist/utils/file-system.d.ts +14 -0
  71. package/dist/utils/file-system.d.ts.map +1 -0
  72. package/dist/utils/file-system.js +84 -0
  73. package/dist/utils/file-system.js.map +1 -0
  74. package/dist/utils/logger.d.ts +20 -0
  75. package/dist/utils/logger.d.ts.map +1 -0
  76. package/dist/utils/logger.js +76 -0
  77. package/dist/utils/logger.js.map +1 -0
  78. package/package.json +75 -0
@@ -0,0 +1,143 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GasProfiler = void 0;
4
+ const ethers_1 = require("ethers");
5
+ const logger_1 = require("../utils/logger");
6
+ class GasProfiler {
7
+ constructor(rpcUrl, privateKey) {
8
+ this.provider = new ethers_1.ethers.JsonRpcProvider(rpcUrl);
9
+ if (privateKey) {
10
+ this.signer = new ethers_1.ethers.Wallet(privateKey, this.provider);
11
+ }
12
+ else {
13
+ this.signer = ethers_1.ethers.Wallet.createRandom().connect(this.provider);
14
+ }
15
+ }
16
+ async profileContract(compilation, testCases) {
17
+ logger_1.logger.startSpinner(`Profiling ${compilation.language} contract...`);
18
+ try {
19
+ const deploymentGas = await this.measureDeploymentGas(compilation);
20
+ logger_1.logger.updateSpinner('Measuring function gas usage...');
21
+ const functionGas = await this.measureFunctionGas(compilation, testCases);
22
+ const network = await this.provider.getNetwork();
23
+ const blockNumber = await this.provider.getBlockNumber();
24
+ logger_1.logger.succeedSpinner(`${compilation.language} profiling complete (Deployment: ${deploymentGas} gas)`);
25
+ return {
26
+ contractName: compilation.contractName,
27
+ language: compilation.language,
28
+ deploymentGas,
29
+ functionGas,
30
+ timestamp: new Date().toISOString(),
31
+ network: network.name || 'unknown',
32
+ blockNumber,
33
+ };
34
+ }
35
+ catch (error) {
36
+ logger_1.logger.failSpinner(`Failed to profile ${compilation.language} contract`);
37
+ throw error;
38
+ }
39
+ }
40
+ async measureDeploymentGas(compilation) {
41
+ try {
42
+ let factory;
43
+ if (compilation.language === 'solidity') {
44
+ factory = new ethers_1.ethers.ContractFactory(compilation.abi || [], compilation.bytecode, this.signer);
45
+ }
46
+ else {
47
+ const bytecode = '0x' + compilation.bytecode;
48
+ const tx = await this.signer.sendTransaction({
49
+ data: bytecode,
50
+ });
51
+ const receipt = await tx.wait();
52
+ if (!receipt) {
53
+ throw new Error('Transaction receipt not available');
54
+ }
55
+ return Number(receipt.gasUsed);
56
+ }
57
+ const contract = await factory.deploy();
58
+ await contract.waitForDeployment();
59
+ const deployTx = contract.deploymentTransaction();
60
+ if (!deployTx) {
61
+ throw new Error('Deployment transaction not found');
62
+ }
63
+ const receipt = await deployTx.wait();
64
+ if (!receipt) {
65
+ throw new Error('Transaction receipt not available');
66
+ }
67
+ return Number(receipt.gasUsed);
68
+ }
69
+ catch (error) {
70
+ logger_1.logger.warn(`Deployment gas measurement failed: ${error.message}`);
71
+ return 0;
72
+ }
73
+ }
74
+ async measureFunctionGas(compilation, testCases) {
75
+ const functionGasMap = new Map();
76
+ if (!compilation.abi || !testCases) {
77
+ return functionGasMap;
78
+ }
79
+ try {
80
+ let contract;
81
+ if (compilation.language === 'solidity') {
82
+ const factory = new ethers_1.ethers.ContractFactory(compilation.abi, compilation.bytecode, this.signer);
83
+ contract = await factory.deploy();
84
+ await contract.waitForDeployment();
85
+ }
86
+ else {
87
+ return functionGasMap;
88
+ }
89
+ for (const [functionName, inputs] of testCases) {
90
+ const testResults = [];
91
+ const gasUsages = [];
92
+ for (let i = 0; i < inputs.length; i++) {
93
+ try {
94
+ const tx = await contract[functionName](...inputs[i]);
95
+ const receipt = await tx.wait();
96
+ const gasUsed = Number(receipt.gasUsed);
97
+ gasUsages.push(gasUsed);
98
+ testResults.push({
99
+ name: `Test ${i + 1}`,
100
+ inputs: inputs[i],
101
+ gasUsed,
102
+ success: true,
103
+ });
104
+ }
105
+ catch (error) {
106
+ testResults.push({
107
+ name: `Test ${i + 1}`,
108
+ inputs: inputs[i],
109
+ gasUsed: 0,
110
+ success: false,
111
+ error: error.message,
112
+ });
113
+ }
114
+ }
115
+ if (gasUsages.length > 0) {
116
+ const avgGas = gasUsages.reduce((a, b) => a + b, 0) / gasUsages.length;
117
+ const minGas = Math.min(...gasUsages);
118
+ const maxGas = Math.max(...gasUsages);
119
+ functionGasMap.set(functionName, {
120
+ functionName,
121
+ gasUsed: avgGas,
122
+ executions: gasUsages.length,
123
+ avgGas,
124
+ minGas,
125
+ maxGas,
126
+ testCases: testResults,
127
+ });
128
+ }
129
+ }
130
+ }
131
+ catch (error) {
132
+ logger_1.logger.warn(`Function gas measurement failed: ${error.message}`);
133
+ }
134
+ return functionGasMap;
135
+ }
136
+ async estimateGas(contractAddress, abi, functionName, args) {
137
+ const contract = new ethers_1.ethers.Contract(contractAddress, abi, this.signer);
138
+ const gasEstimate = await contract[functionName].estimateGas(...args);
139
+ return Number(gasEstimate);
140
+ }
141
+ }
142
+ exports.GasProfiler = GasProfiler;
143
+ //# sourceMappingURL=gas-profiler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gas-profiler.js","sourceRoot":"","sources":["../../src/profiler/gas-profiler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import { ComparisonResult } from '../types';
2
+ export declare class ResultsStore {
3
+ private resultsDir;
4
+ constructor(customDir?: string);
5
+ initialize(): Promise<void>;
6
+ save(comparison: ComparisonResult): Promise<string>;
7
+ load(filename: string): Promise<ComparisonResult>;
8
+ list(): Promise<string[]>;
9
+ getLatest(contractName?: string): Promise<ComparisonResult | null>;
10
+ delete(filename: string): Promise<void>;
11
+ clear(): Promise<void>;
12
+ private serializeComparison;
13
+ private deserializeComparison;
14
+ getResultsDirectory(): string;
15
+ }
16
+ //# sourceMappingURL=results-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"results-store.d.ts","sourceRoot":"","sources":["../../src/storage/results-store.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAG5C,qBAAa,YAAY;IACvB,OAAO,CAAC,UAAU,CAAS;gBAEf,SAAS,CAAC,EAAE,MAAM;IAKxB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3B,IAAI,CAAC,UAAU,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC;IAcnD,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAWjD,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAWzB,SAAS,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAclE,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASvC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAM5B,OAAO,CAAC,mBAAmB;IAkB3B,OAAO,CAAC,qBAAqB;IAkB7B,mBAAmB,IAAI,MAAM;CAG9B"}
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ResultsStore = void 0;
7
+ const path_1 = __importDefault(require("path"));
8
+ const fs_extra_1 = __importDefault(require("fs-extra"));
9
+ const file_system_1 = require("../utils/file-system");
10
+ const logger_1 = require("../utils/logger");
11
+ class ResultsStore {
12
+ constructor(customDir) {
13
+ this.resultsDir =
14
+ customDir || path_1.default.join(file_system_1.FileSystem.getProjectRoot(), '.stylus-toolkit', 'results');
15
+ }
16
+ async initialize() {
17
+ await file_system_1.FileSystem.ensureDir(this.resultsDir);
18
+ }
19
+ async save(comparison) {
20
+ await this.initialize();
21
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
22
+ const filename = `${comparison.contractName}_${timestamp}.json`;
23
+ const filepath = path_1.default.join(this.resultsDir, filename);
24
+ await file_system_1.FileSystem.writeJson(filepath, this.serializeComparison(comparison));
25
+ logger_1.logger.success(`Results saved to ${filepath}`);
26
+ return filepath;
27
+ }
28
+ async load(filename) {
29
+ const filepath = path_1.default.join(this.resultsDir, filename);
30
+ if (!(await file_system_1.FileSystem.fileExists(filepath))) {
31
+ throw new Error(`Result file not found: ${filename}`);
32
+ }
33
+ const data = await file_system_1.FileSystem.readJson(filepath);
34
+ return this.deserializeComparison(data);
35
+ }
36
+ async list() {
37
+ await this.initialize();
38
+ try {
39
+ const files = await fs_extra_1.default.readdir(this.resultsDir);
40
+ return files.filter((f) => f.endsWith('.json')).sort().reverse();
41
+ }
42
+ catch {
43
+ return [];
44
+ }
45
+ }
46
+ async getLatest(contractName) {
47
+ const files = await this.list();
48
+ const filteredFiles = contractName
49
+ ? files.filter((f) => f.startsWith(contractName))
50
+ : files;
51
+ if (filteredFiles.length === 0) {
52
+ return null;
53
+ }
54
+ return await this.load(filteredFiles[0]);
55
+ }
56
+ async delete(filename) {
57
+ const filepath = path_1.default.join(this.resultsDir, filename);
58
+ if (await file_system_1.FileSystem.fileExists(filepath)) {
59
+ await fs_extra_1.default.remove(filepath);
60
+ logger_1.logger.success(`Deleted result: ${filename}`);
61
+ }
62
+ }
63
+ async clear() {
64
+ await fs_extra_1.default.remove(this.resultsDir);
65
+ await this.initialize();
66
+ logger_1.logger.success('All results cleared');
67
+ }
68
+ serializeComparison(comparison) {
69
+ return {
70
+ ...comparison,
71
+ rustProfile: {
72
+ ...comparison.rustProfile,
73
+ functionGas: Array.from(comparison.rustProfile.functionGas.entries()),
74
+ },
75
+ solidityProfile: {
76
+ ...comparison.solidityProfile,
77
+ functionGas: Array.from(comparison.solidityProfile.functionGas.entries()),
78
+ },
79
+ savings: {
80
+ ...comparison.savings,
81
+ functionSavings: Array.from(comparison.savings.functionSavings.entries()),
82
+ },
83
+ };
84
+ }
85
+ deserializeComparison(data) {
86
+ return {
87
+ ...data,
88
+ rustProfile: {
89
+ ...data.rustProfile,
90
+ functionGas: new Map(data.rustProfile.functionGas),
91
+ },
92
+ solidityProfile: {
93
+ ...data.solidityProfile,
94
+ functionGas: new Map(data.solidityProfile.functionGas),
95
+ },
96
+ savings: {
97
+ ...data.savings,
98
+ functionSavings: new Map(data.savings.functionSavings),
99
+ },
100
+ };
101
+ }
102
+ getResultsDirectory() {
103
+ return this.resultsDir;
104
+ }
105
+ }
106
+ exports.ResultsStore = ResultsStore;
107
+ //# sourceMappingURL=results-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"results-store.js","sourceRoot":"","sources":["../../src/storage/results-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ export declare class TemplateGenerator {
2
+ generate(projectPath: string, templateName: string, hasRust: boolean, hasSolidity: boolean): Promise<void>;
3
+ private generateRustFiles;
4
+ private generateSolidityFiles;
5
+ private generateCommonFiles;
6
+ private generateCargoToml;
7
+ private generateReadme;
8
+ private generateGitignore;
9
+ private generateEnvExample;
10
+ }
11
+ //# sourceMappingURL=generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../src/templates/generator.ts"],"names":[],"mappings":"AAIA,qBAAa,iBAAiB;IACtB,QAAQ,CACZ,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,OAAO,EAChB,WAAW,EAAE,OAAO,GACnB,OAAO,CAAC,IAAI,CAAC;YAcF,iBAAiB;YAQjB,qBAAqB;YASrB,mBAAmB;IAgBjC,OAAO,CAAC,iBAAiB;IA0BzB,OAAO,CAAC,cAAc;IAwCtB,OAAO,CAAC,iBAAiB;IAwBzB,OAAO,CAAC,kBAAkB;CAW3B"}
@@ -0,0 +1,135 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.TemplateGenerator = void 0;
7
+ const path_1 = __importDefault(require("path"));
8
+ const file_system_1 = require("../utils/file-system");
9
+ const templates_1 = require("./templates");
10
+ class TemplateGenerator {
11
+ async generate(projectPath, templateName, hasRust, hasSolidity) {
12
+ const template = templates_1.TEMPLATES[templateName] || templates_1.TEMPLATES.basic;
13
+ if (hasRust) {
14
+ await this.generateRustFiles(projectPath, template);
15
+ }
16
+ if (hasSolidity) {
17
+ await this.generateSolidityFiles(projectPath, template);
18
+ }
19
+ await this.generateCommonFiles(projectPath, templateName, hasRust, hasSolidity);
20
+ }
21
+ async generateRustFiles(projectPath, template) {
22
+ const rustContractPath = path_1.default.join(projectPath, 'contracts-rust', 'src', 'lib.rs');
23
+ await file_system_1.FileSystem.writeFile(rustContractPath, template.rust);
24
+ const cargoToml = path_1.default.join(projectPath, 'contracts-rust', 'Cargo.toml');
25
+ await file_system_1.FileSystem.writeFile(cargoToml, this.generateCargoToml(template.name));
26
+ }
27
+ async generateSolidityFiles(projectPath, template) {
28
+ const solidityContractPath = path_1.default.join(projectPath, 'contracts-solidity', `${template.name}.sol`);
29
+ await file_system_1.FileSystem.writeFile(solidityContractPath, template.solidity);
30
+ }
31
+ async generateCommonFiles(projectPath, templateName, hasRust, hasSolidity) {
32
+ const readme = this.generateReadme(templateName, hasRust, hasSolidity);
33
+ await file_system_1.FileSystem.writeFile(path_1.default.join(projectPath, 'README.md'), readme);
34
+ const gitignore = this.generateGitignore();
35
+ await file_system_1.FileSystem.writeFile(path_1.default.join(projectPath, '.gitignore'), gitignore);
36
+ const envExample = this.generateEnvExample();
37
+ await file_system_1.FileSystem.writeFile(path_1.default.join(projectPath, '.env.example'), envExample);
38
+ }
39
+ generateCargoToml(contractName) {
40
+ return `[package]
41
+ name = "${contractName.toLowerCase()}"
42
+ version = "0.1.0"
43
+ edition = "2021"
44
+
45
+ [dependencies]
46
+ stylus-sdk = "0.10.0"
47
+ alloy-primitives = "0.8.19"
48
+ alloy-sol-types = "0.8.19"
49
+
50
+ [dev-dependencies]
51
+ tokio = { version = "1.12.0", features = ["full"] }
52
+
53
+ [lib]
54
+ crate-type = ["lib", "cdylib"]
55
+
56
+ [profile.release]
57
+ codegen-units = 1
58
+ strip = true
59
+ lto = true
60
+ panic = "abort"
61
+ opt-level = "z"
62
+ `;
63
+ }
64
+ generateReadme(templateName, hasRust, hasSolidity) {
65
+ return `# Stylus Project - ${templateName}
66
+
67
+ ## Overview
68
+
69
+ This project was generated using the Stylus Toolkit CLI.
70
+
71
+ ${hasRust ? '### Rust (Stylus)\n\nLocation: \`contracts-rust/src/lib.rs\`\n' : ''}
72
+ ${hasSolidity ? '### Solidity\n\nLocation: \`contracts-solidity/\`\n' : ''}
73
+
74
+ ## Quick Start
75
+
76
+ ### Profile Gas Usage
77
+
78
+ Compare gas usage between Rust and Solidity implementations:
79
+
80
+ \`\`\`bash
81
+ stylus-toolkit profile
82
+ \`\`\`
83
+
84
+ ### Compile Contracts
85
+
86
+ ${hasRust ? '#### Rust (Stylus)\n\`\`\`bash\ncd contracts-rust\ncargo build --release --target wasm32-unknown-unknown\n\`\`\`\n' : ''}
87
+ ${hasSolidity ? '#### Solidity\n\`\`\`bash\ncd contracts-solidity\nforge build\n\`\`\`\n' : ''}
88
+
89
+ ## Documentation
90
+
91
+ - [Stylus Documentation](https://docs.arbitrum.io/stylus/stylus-gentle-introduction)
92
+ - [Stylus SDK](https://github.com/OffchainLabs/stylus-sdk-rs)
93
+
94
+ ## License
95
+
96
+ MIT
97
+ `;
98
+ }
99
+ generateGitignore() {
100
+ return `# Rust
101
+ target/
102
+ Cargo.lock
103
+
104
+ # Solidity
105
+ out/
106
+ cache/
107
+
108
+ # Environment
109
+ .env
110
+
111
+ # Results
112
+ .stylus-toolkit/results/
113
+
114
+ # Node
115
+ node_modules/
116
+
117
+ # IDE
118
+ .vscode/
119
+ .idea/
120
+ `;
121
+ }
122
+ generateEnvExample() {
123
+ return `# RPC Configuration
124
+ RPC_URL=http://localhost:8547
125
+
126
+ # Private key for deployment (DO NOT commit actual private key)
127
+ PRIVATE_KEY=
128
+
129
+ # Network
130
+ NETWORK=local
131
+ `;
132
+ }
133
+ }
134
+ exports.TemplateGenerator = TemplateGenerator;
135
+ //# sourceMappingURL=generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generator.js","sourceRoot":"","sources":["../../src/templates/generator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare const TEMPLATES: Record<string, any>;
2
+ //# sourceMappingURL=templates.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/templates/templates.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CA+TzC,CAAC"}