fazer-lang 3.2.1 → 3.3.1

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/CHANGELOG.md CHANGED
@@ -2,6 +2,16 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [3.2.1] - 2026-01-25
6
+
7
+ ### Added
8
+ - **Cross-Platform**: Added `install_system.sh` for easy installation on Linux and macOS.
9
+ - **Build System**: Updated `fazer build` to support Linux/Mac targets (generates portable bash launcher).
10
+ - **Examples**: Added `VoidNet.fz`, a stylish TCP console application with ASCII art.
11
+
12
+ ### Changed
13
+ - **Documentation**: Updated `README.md` and `docs/GUIDE.md` with cross-platform installation instructions.
14
+
5
15
  ## [3.2.0] - 2026-01-24
6
16
 
7
17
  ### Added
package/README.md CHANGED
@@ -46,6 +46,23 @@ fazer scan google.com
46
46
  fazer whois microsoft.com
47
47
  ```
48
48
 
49
+ ## Cryptage / Protection de Code
50
+
51
+ Pour distribuer un script sans révéler son code source (obfuscation/cryptage) :
52
+
53
+ ```bash
54
+ fazer compile mon_script.fz
55
+ ```
56
+
57
+ Cela génère un fichier `mon_script.fzc` (Fazer Compiled/Crypted).
58
+ Ce fichier est chiffré (AES-256) mais peut être exécuté directement par n'importe quel interpréteur Fazer :
59
+
60
+ ```bash
61
+ fazer mon_script.fzc
62
+ ```
63
+
64
+ Cela permet de partager des outils "privés" tout en gardant la portabilité du fichier.
65
+
49
66
  ## Création d'Exécutable (.exe / Binaire)
50
67
 
51
68
  Transformez vos scripts Fazer en applications portables et natives :
package/docs/GUIDE.md CHANGED
@@ -28,7 +28,13 @@ Fazer est un langage de programmation moderne, simple et puissant. Il est "batte
28
28
 
29
29
  ### Installation
30
30
  1. **Téléchargez** le dossier `fazer-lang`.
31
- 2. **Exécutez** le script `install_system.ps1` (double-clic).
31
+ 2. **Installation** :
32
+ * **Windows** : Exécutez `install_system.ps1` (double-clic).
33
+ * **Linux / Mac** : Ouvrez un terminal et lancez :
34
+ ```bash
35
+ chmod +x install_system.sh
36
+ ./install_system.sh
37
+ ```
32
38
  3. C'est tout ! Ouvrez un terminal et tapez `fazer` pour vérifier.
33
39
 
34
40
  ### Votre Premier Script ("Hello World")
package/fazer.js CHANGED
@@ -2,7 +2,7 @@
2
2
  "use strict";
3
3
 
4
4
  /*
5
- Fazer v2 — interpreter "batteries included"
5
+ Fazer v3.3.1 — interpreter "batteries included"
6
6
  - Chevrotain lexer/parser → AST
7
7
  - Runtime with scopes, functions, pipes, lists/maps, property/index access
8
8
  - Stdlib: fs/path/crypto/encoding/ui
@@ -4962,6 +4962,20 @@ const ASCII_FONTS = {
4962
4962
 
4963
4963
  // [GFX] Native Game & App Engine (No HTML required)
4964
4964
  Math: Math,
4965
+
4966
+ // [STR] String Manipulation
4967
+ str_split: (s, sep) => String(s).split(sep),
4968
+ str_sub: (s, start, end) => String(s).substring(start, end),
4969
+ str_replace: (s, a, b) => String(s).split(a).join(b),
4970
+ str_trim: (s) => String(s).trim(),
4971
+ str_len: (s) => String(s).length,
4972
+ str_lower: (s) => String(s).toLowerCase(),
4973
+ str_upper: (s) => String(s).toUpperCase(),
4974
+ str_contains: (s, sub) => String(s).includes(sub),
4975
+ str_starts: (s, sub) => String(s).startsWith(sub),
4976
+ str_ends: (s, sub) => String(s).endsWith(sub),
4977
+ str_index: (s, sub) => String(s).indexOf(sub),
4978
+
4965
4979
  gfx: {
4966
4980
  _width: 800,
4967
4981
  _height: 600,
@@ -5368,8 +5382,23 @@ const ASCII_FONTS = {
5368
5382
 
5369
5383
  queue.forEach(cmd => {
5370
5384
  if (cmd.op === 'clear') {
5371
- // Parse hex color if needed, for now just black/grey
5372
- gl.clearColor(0.1, 0.1, 0.1, 1.0);
5385
+ // Parse hex color or object
5386
+ let r = 0.1, g = 0.1, b = 0.1;
5387
+ if (cmd.color) {
5388
+ if (typeof cmd.color === 'string') {
5389
+ if (cmd.color.startsWith('#')) {
5390
+ const hex = cmd.color.substring(1);
5391
+ r = parseInt(hex.substring(0,2), 16)/255;
5392
+ g = parseInt(hex.substring(2,4), 16)/255;
5393
+ b = parseInt(hex.substring(4,6), 16)/255;
5394
+ }
5395
+ } else if (typeof cmd.color === 'object') {
5396
+ r = cmd.color.r !== undefined ? cmd.color.r : 0.1;
5397
+ g = cmd.color.g !== undefined ? cmd.color.g : 0.1;
5398
+ b = cmd.color.b !== undefined ? cmd.color.b : 0.1;
5399
+ }
5400
+ }
5401
+ gl.clearColor(r, g, b, 1.0);
5373
5402
  gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
5374
5403
 
5375
5404
  // Clear Overlay
@@ -5378,6 +5407,24 @@ const ASCII_FONTS = {
5378
5407
  // Update Matrices
5379
5408
  Mat4.perspective(state.P, 45 * Math.PI / 180, canvas.width/canvas.height, 0.1, 1000.0);
5380
5409
  }
5410
+ else if (cmd.op === 'rect') {
5411
+ ctx.fillStyle = cmd.color;
5412
+ ctx.fillRect(cmd.x, cmd.y, cmd.w, cmd.h);
5413
+ }
5414
+ else if (cmd.op === 'circle') {
5415
+ ctx.beginPath();
5416
+ ctx.arc(cmd.x, cmd.y, cmd.r, 0, Math.PI * 2);
5417
+ ctx.fillStyle = cmd.color;
5418
+ ctx.fill();
5419
+ }
5420
+ else if (cmd.op === 'line') {
5421
+ ctx.beginPath();
5422
+ ctx.moveTo(cmd.x1, cmd.y1);
5423
+ ctx.lineTo(cmd.x2, cmd.y2);
5424
+ ctx.strokeStyle = cmd.color;
5425
+ ctx.lineWidth = cmd.width || 1;
5426
+ ctx.stroke();
5427
+ }
5381
5428
  else if (cmd.op === 'text') {
5382
5429
  ctx.font = (cmd.size || 20) + 'px monospace';
5383
5430
  ctx.fillStyle = cmd.color || 'white';
@@ -5536,10 +5583,7 @@ Add-Type -TypeDefinition $code -Language CCSharp
5536
5583
  },
5537
5584
 
5538
5585
  // Process Manipulation
5539
- kill: (pid) => {
5540
- try { process.kill(Number(pid)); return true; } catch(e) { return false; }
5541
- },
5542
-
5586
+
5543
5587
  // Administrator Check
5544
5588
  is_admin: () => {
5545
5589
  try {
@@ -5551,147 +5595,33 @@ Add-Type -TypeDefinition $code -Language CCSharp
5551
5595
 
5552
5596
  // [NET] Advanced Network Operations
5553
5597
  net: {
5554
- // Socket Connect / Port Scan
5555
- connect: async (host, port, timeout=2000) => {
5556
- return new Promise(resolve => {
5557
- const socket = new (require("net").Socket)();
5558
- socket.setTimeout(Number(timeout));
5559
- socket.on('connect', () => { socket.destroy(); resolve(true); });
5560
- socket.on('timeout', () => { socket.destroy(); resolve(false); });
5561
- socket.on('error', (e) => { socket.destroy(); resolve(false); });
5562
- socket.connect(Number(port), String(host));
5563
- });
5564
- },
5565
-
5566
- // Get Public IP (External)
5567
- public_ip: async () => {
5568
- try {
5569
- const res = await builtins.fetch("https://api.ipify.org");
5570
- return res.body;
5571
- } catch(e) { return "0.0.0.0"; }
5572
- },
5573
-
5574
- // DNS Lookup
5575
- dns: async (domain) => {
5576
- const dns = require("dns").promises;
5577
- try { return await dns.resolve(String(domain)); } catch(e) { return []; }
5578
- },
5579
-
5580
- // Network Interfaces
5581
- interfaces: () => require("os").networkInterfaces()
5582
- },
5583
-
5584
- // [OSINT] Open Source Intelligence Tools
5585
- osint: {
5586
- // Whois Query
5587
- whois: async (domain) => {
5588
- return new Promise(resolve => {
5589
- const client = require("net").createConnection(43, "whois.iana.org", () => {
5590
- client.write(domain + "\r\n");
5591
- });
5592
- let data = "";
5593
- client.on("data", (chunk) => data += chunk);
5594
- client.on("end", () => resolve(data));
5595
- client.on("error", (err) => resolve("Error: " + err.message));
5598
+ // TCP Listener
5599
+ listen: (port, on_connect) => {
5600
+ const net = require("net");
5601
+ const server = net.createServer(async (socket) => {
5602
+ const client = {
5603
+ ip: socket.remoteAddress,
5604
+ send: (d) => { try { socket.write(String(d)); return true; } catch(e){ return false; } },
5605
+ close: () => socket.destroy(),
5606
+ on_data: (fn) => {
5607
+ socket.on('data', async (d) => {
5608
+ if (fn && fn.__fnref__) await this._call(fn, [d.toString()], this.global);
5609
+ });
5610
+ }
5611
+ };
5612
+ if (on_connect && on_connect.__fnref__) {
5613
+ await this._call(on_connect, [client], this.global);
5614
+ }
5596
5615
  });
5616
+
5617
+ server.on('error', (e) => console.error("Net Error:", e.message));
5618
+ server.listen(Number(port));
5619
+
5620
+ return {
5621
+ close: () => server.close()
5622
+ };
5597
5623
  },
5598
-
5599
- // Google Dorking Helper (Generates URL)
5600
- dork_url: (query) => {
5601
- return "https://www.google.com/search?q=" + encodeURIComponent(String(query));
5602
- },
5603
-
5604
- // User Agent Generator
5605
- ua: () => {
5606
- const agents = [
5607
- "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
5608
- "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15",
5609
- "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36"
5610
- ];
5611
- return agents[Math.floor(Math.random() * agents.length)];
5612
- }
5613
- },
5614
-
5615
-
5616
- // ──────────────────────────────────────────────────────────────────────────
5617
- // FAZER SECURITY & INNOVATION SUITE (v3.0)
5618
- // ──────────────────────────────────────────────────────────────────────────
5619
-
5620
- // [SYS] System & DLL Manipulation
5621
- sys: {
5622
- // PowerShell Bridge (The Core)
5623
- ps: (script) => {
5624
- try {
5625
- const cmd = `powershell -NoProfile -ExecutionPolicy Bypass -Command "& { ${String(script).replace(/"/g, '\"')} }"`;
5626
- return require("child_process").execSync(cmd, { encoding: 'utf8', maxBuffer: 1024*1024*50 }).trim();
5627
- } catch(e) { return "Error: " + e.message; }
5628
- },
5629
-
5630
- ps_json: (script) => {
5631
- try {
5632
- const s = String(script).replace(/"/g, '\"');
5633
- const cmd = `powershell -NoProfile -ExecutionPolicy Bypass -Command "& { ${s} } | ConvertTo-Json -Depth 2 -Compress"`;
5634
- const out = require("child_process").execSync(cmd, { encoding: 'utf8', maxBuffer: 1024*1024*50 }).trim();
5635
- return JSON.parse(out);
5636
- } catch(e) { return null; }
5637
- },
5638
-
5639
- // DLL / Assembly Loading & Execution
5640
- dll_load: (path) => {
5641
- // Loads a DLL into the current PS session context (simulated via static calls for now)
5642
- // Since each sys.ps call is a new process, we need a way to persist or use a single session.
5643
- // For now, we provide a helper to generate the loading script snippet.
5644
- return `[System.Reflection.Assembly]::LoadFrom("${String(path).replace(/\\/g, '\\\\')}");`;
5645
- },
5646
-
5647
- // Native Memory Forensic (Read Process Memory)
5648
- mem_dump: (pid, outputFile) => {
5649
- // Uses MiniDumpWriteDump via P/Invoke in PowerShell
5650
- const ps = `
5651
- $code = @"
5652
- using System;
5653
- using System.Runtime.InteropServices;
5654
- using System.Diagnostics;
5655
- using System.IO;
5656
-
5657
- public class MiniDump {
5658
- [DllImport("dbghelp.dll", EntryPoint = "MiniDumpWriteDump", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
5659
- public static extern bool MiniDumpWriteDump(IntPtr hProcess, uint processId, SafeHandle hFile, uint dumpType, IntPtr exceptionParam, IntPtr userStreamParam, IntPtr callbackParam);
5660
-
5661
- public static void Dump(int pid, string filename) {
5662
- Process target = Process.GetProcessById(pid);
5663
- using (FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.ReadWrite, FileShare.Write)) {
5664
- MiniDumpWriteDump(target.Handle, (uint)target.Id, fs.SafeFileHandle, 2, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
5665
- }
5666
- }
5667
- }
5668
- "@
5669
- Add-Type -TypeDefinition $code -Language CCSharp
5670
- [MiniDump]::Dump(${Number(pid)}, "${String(outputFile)}")
5671
- "Done"
5672
- `;
5673
- try {
5674
- require("child_process").execSync(`powershell -NoProfile -Command "${ps.replace(/"/g, '\"')}"`);
5675
- return true;
5676
- } catch(e) { return false; }
5677
- },
5678
-
5679
- // Administrator Check
5680
- is_admin: () => {
5681
- try {
5682
- const out = require("child_process").execSync('powershell -Command "([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)"', { encoding: 'utf8' }).trim();
5683
- return out === "True";
5684
- } catch(e) { return false; }
5685
- },
5686
-
5687
- // System Info
5688
- pid: () => process.pid,
5689
- arch: () => process.arch,
5690
- platform: () => process.platform,
5691
- },
5692
5624
 
5693
- // [NET] Advanced Network Operations
5694
- net: {
5695
5625
  // Socket Connect / Port Scan
5696
5626
  connect: async (host, port, timeout=2000) => {
5697
5627
  return new Promise(resolve => {
@@ -5703,6 +5633,31 @@ Add-Type -TypeDefinition $code -Language CCSharp
5703
5633
  socket.connect(Number(port), String(host));
5704
5634
  });
5705
5635
  },
5636
+
5637
+ // Persistent TCP Client (Reverse Shell / C2)
5638
+ tcp_connect: (host, port, on_connect) => {
5639
+ const net = require("net");
5640
+ const socket = new net.Socket();
5641
+
5642
+ const client = {
5643
+ send: (d) => { try { socket.write(String(d)); return true; } catch(e){ return false; } },
5644
+ close: () => socket.destroy(),
5645
+ on_data: (fn) => {
5646
+ socket.on('data', async (d) => {
5647
+ if (fn && fn.__fnref__) await this._call(fn, [d.toString()], this.global);
5648
+ });
5649
+ }
5650
+ };
5651
+
5652
+ socket.connect(Number(port), String(host), async () => {
5653
+ if (on_connect && on_connect.__fnref__) {
5654
+ await this._call(on_connect, [client], this.global);
5655
+ }
5656
+ });
5657
+
5658
+ socket.on('error', (e) => console.error("TCP Client Error:", e.message));
5659
+ return client;
5660
+ },
5706
5661
 
5707
5662
  // Get Public IP (External)
5708
5663
  public_ip: async () => {
@@ -5753,12 +5708,17 @@ Add-Type -TypeDefinition $code -Language CCSharp
5753
5708
  }
5754
5709
  },
5755
5710
 
5711
+
5712
+
5713
+
5756
5714
  fs: {
5757
5715
  read: (path) => { try { return require('fs').readFileSync(String(path), 'utf8'); } catch(e) { return null; } },
5758
5716
  write: (path, data) => { try { require('fs').writeFileSync(String(path), String(data)); return true; } catch(e) { return false; } },
5759
5717
  append: (path, data) => { try { require('fs').appendFileSync(String(path), String(data)); return true; } catch(e) { return false; } },
5760
5718
  exists: (path) => require('fs').existsSync(String(path)),
5761
- mkdir: (path) => { try { require('fs').mkdirSync(String(path), {recursive:true}); return true; } catch(e) { return false; } }
5719
+ mkdir: (path) => { try { require('fs').mkdirSync(String(path), {recursive:true}); return true; } catch(e) { return false; } },
5720
+ list: (path) => { try { return require('fs').readdirSync(String(path)); } catch(e) { return []; } },
5721
+ delete: (path) => { try { require('fs').rmSync(String(path), {recursive:true, force:true}); return true; } catch(e) { return false; } }
5762
5722
  },
5763
5723
 
5764
5724
  // [WEBVIEW] Modern HTML/CSS UI
@@ -6010,9 +5970,9 @@ ascii_art: (text, fontName) => {
6010
5970
  await rt.run(ast);
6011
5971
 
6012
5972
  const exports = {};
6013
- console.log("Exporting vars from module...");
5973
+ // console.log("Exporting vars from module...");
6014
5974
  for (const [k, v] of rt.global.vars) {
6015
- console.log("Exporting:", k, v);
5975
+ // console.log("Exporting:", k, v);
6016
5976
  if (k === "__builtins__" || builtins[k]) continue;
6017
5977
 
6018
5978
  let value = v.value;
@@ -6451,9 +6411,24 @@ $results | ConvertTo-Json -Compress
6451
6411
  }
6452
6412
  },
6453
6413
 
6454
- server: (port, handlerName) => {
6455
- // This old implementation is deprecated/removed in favor of the async one below
6456
- throw new FazerError("This server signature is deprecated. Use server(port, router_obj).");
6414
+ http_server: (port, handler) => {
6415
+ const http = require('http');
6416
+ const server = http.createServer(async (req, res) => {
6417
+ if (handler && handler.__fnref__) {
6418
+ const result = await this._call(handler, [{
6419
+ method: req.method,
6420
+ url: req.url,
6421
+ headers: req.headers
6422
+ }], this.global);
6423
+
6424
+ res.writeHead(200, { 'Content-Type': 'text/html' });
6425
+ res.end(String(result));
6426
+ } else {
6427
+ res.end("Fazer Server Running");
6428
+ }
6429
+ });
6430
+ server.listen(Number(port));
6431
+ console.log(`HTTP Server running on port ${port}`);
6457
6432
  },
6458
6433
 
6459
6434
  sleep: (ms) => new Promise((resolve) => setTimeout(resolve, Number(ms))),
@@ -8846,6 +8821,45 @@ async function main() {
8846
8821
  console.log(require("crypto").randomUUID());
8847
8822
  },
8848
8823
 
8824
+ "compile": async (args) => {
8825
+ if (!args[0]) return console.log(`${colors.red}Usage: fazer compile <file.fz> [-o output.fzc]${colors.reset}`);
8826
+ const fs = require("fs");
8827
+ const path = require("path");
8828
+ const crypto = require("crypto");
8829
+
8830
+ const inputFile = args[0];
8831
+ if (!fs.existsSync(inputFile)) return console.error(`${colors.red}[!] File not found: ${inputFile}${colors.reset}`);
8832
+
8833
+ let outputFile = inputFile.replace(/\.fz$/i, ".fzc");
8834
+ if (args[1] === "-o" && args[2]) outputFile = args[2];
8835
+
8836
+ console.log(`${colors.cyan}[*] Compiling/Encrypting ${inputFile}...${colors.reset}`);
8837
+
8838
+ try {
8839
+ const content = fs.readFileSync(inputFile, "utf8");
8840
+ // Simple obfuscation/encryption using a hardcoded key (Security through obscurity, but sufficient for basic protection)
8841
+ // We use AES-256-CTR with a fixed key/iv derived from a salt, or just a simple key.
8842
+ // To make it portable, the interpreter must know the key. We'll use a hardcoded key in the interpreter.
8843
+ const KEY = Buffer.from("46617a65724c616e675365637265743132334b6579214023", "hex"); // "FazerLangSecret123Key!@#" in hex (24 bytes) - wait, needs 32 for AES-256 or 16 for AES-128
8844
+ // Let's use a simpler XOR-based or standard AES approach.
8845
+ // We'll use a static key for now so any Fazer interpreter can run it.
8846
+ const STATIC_KEY = crypto.createHash('sha256').update("FazerLangPublicRuntimeKey2026").digest();
8847
+ const iv = crypto.randomBytes(16);
8848
+ const cipher = crypto.createCipheriv('aes-256-cbc', STATIC_KEY, iv);
8849
+ let encrypted = cipher.update(content, 'utf8', 'hex');
8850
+ encrypted += cipher.final('hex');
8851
+
8852
+ // File Format: FZC01[IV_HEX][ENCRYPTED_HEX]
8853
+ const data = `FZC01${iv.toString('hex')}${encrypted}`;
8854
+ fs.writeFileSync(outputFile, data, "utf8");
8855
+
8856
+ console.log(`${colors.green}[+] Success! Compiled to: ${outputFile}${colors.reset}`);
8857
+ console.log(`${colors.yellow}[i] You can now distribute '${outputFile}'. It can be run with 'fazer ${outputFile}' but cannot be easily read.${colors.reset}`);
8858
+ } catch(e) {
8859
+ console.error(`${colors.red}[!] Error: ${e.message}${colors.reset}`);
8860
+ }
8861
+ },
8862
+
8849
8863
  // --- SYSTEM / UTILS ---
8850
8864
  "ls": async (args) => {
8851
8865
  const fs = require("fs");
@@ -9009,7 +9023,26 @@ async function main() {
9009
9023
  process.exit(1);
9010
9024
  }
9011
9025
 
9012
- const code = fs.readFileSync(filePath, "utf8");
9026
+ let code = fs.readFileSync(filePath, "utf8");
9027
+
9028
+ // --- DECRYPT IF FZC ---
9029
+ if (code.startsWith("FZC01")) {
9030
+ try {
9031
+ const crypto = require("crypto");
9032
+ const STATIC_KEY = crypto.createHash('sha256').update("FazerLangPublicRuntimeKey2026").digest();
9033
+ const iv = Buffer.from(code.substring(5, 37), 'hex');
9034
+ const encryptedText = code.substring(37);
9035
+ const decipher = crypto.createDecipheriv('aes-256-cbc', STATIC_KEY, iv);
9036
+ let decrypted = decipher.update(encryptedText, 'hex', 'utf8');
9037
+ decrypted += decipher.final('utf8');
9038
+ code = decrypted;
9039
+ } catch(e) {
9040
+ console.error("Error: Failed to decrypt .fzc file. It might be corrupted or version mismatch.");
9041
+ process.exit(1);
9042
+ }
9043
+ }
9044
+ // ----------------------
9045
+
9013
9046
  const lex = lexer.tokenize(code);
9014
9047
  if (lex.errors.length) {
9015
9048
  console.error("Lexer error:", lex.errors[0].message || String(lex.errors[0]));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fazer-lang",
3
- "version": "3.2.1",
3
+ "version": "3.3.1",
4
4
  "description": "Fazer — The Red Team Language. Native modules for C2 Implant, WiFi Recon, Steganography (LSB), Process Injection, Crypto, 3D Game Engine, and Automation. Secure, powerful, standalone.",
5
5
  "main": "fazer.js",
6
6
  "types": "index.d.ts",