naider 1.17.0 → 1.17.2

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.
Binary file
package/assets/nx.ico ADDED
Binary file
@@ -0,0 +1,208 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { writeFileSync } from 'fs';
4
+ import { resolve, dirname } from 'path';
5
+ import { fileURLToPath } from 'url';
6
+
7
+ const __dirname = dirname(fileURLToPath(import.meta.url));
8
+
9
+ function createICO(sizes, renderFn) {
10
+ const images = sizes.map(s => createBMPImage(s, renderFn));
11
+ const headerSize = 6 + images.length * 16;
12
+ let offset = headerSize;
13
+
14
+ const header = Buffer.alloc(6);
15
+ header.writeUInt16LE(0, 0);
16
+ header.writeUInt16LE(1, 2);
17
+ header.writeUInt16LE(images.length, 4);
18
+
19
+ const entries = [];
20
+ for (const img of images) {
21
+ const entry = Buffer.alloc(16);
22
+ entry.writeUInt8(img.size >= 256 ? 0 : img.size, 0);
23
+ entry.writeUInt8(img.size >= 256 ? 0 : img.size, 1);
24
+ entry.writeUInt8(0, 2);
25
+ entry.writeUInt8(0, 3);
26
+ entry.writeUInt16LE(1, 4);
27
+ entry.writeUInt16LE(32, 6);
28
+ entry.writeUInt32LE(img.data.length, 8);
29
+ entry.writeUInt32LE(offset, 12);
30
+ offset += img.data.length;
31
+ entries.push(entry);
32
+ }
33
+
34
+ return Buffer.concat([header, ...entries, ...images.map(i => i.data)]);
35
+ }
36
+
37
+ function createBMPImage(size, renderFn) {
38
+ const pixels = new Uint8Array(size * size * 4);
39
+ renderFn(pixels, size);
40
+
41
+ const rowSize = size * 4;
42
+ const andRowSize = Math.ceil(size / 32) * 4;
43
+ const bmpInfoSize = 40;
44
+ const pixelDataSize = rowSize * size;
45
+ const andMaskSize = andRowSize * size;
46
+ const totalSize = bmpInfoSize + pixelDataSize + andMaskSize;
47
+
48
+ const buf = Buffer.alloc(totalSize);
49
+
50
+ buf.writeUInt32LE(40, 0);
51
+ buf.writeInt32LE(size, 4);
52
+ buf.writeInt32LE(size * 2, 8);
53
+ buf.writeUInt16LE(1, 12);
54
+ buf.writeUInt16LE(32, 14);
55
+ buf.writeUInt32LE(0, 16);
56
+ buf.writeUInt32LE(pixelDataSize + andMaskSize, 20);
57
+ buf.writeInt32LE(0, 24);
58
+ buf.writeInt32LE(0, 28);
59
+ buf.writeUInt32LE(0, 32);
60
+ buf.writeUInt32LE(0, 36);
61
+
62
+ for (let y = 0; y < size; y++) {
63
+ const srcRow = (size - 1 - y) * size * 4;
64
+ const dstRow = bmpInfoSize + y * rowSize;
65
+ for (let x = 0; x < size; x++) {
66
+ const si = srcRow + x * 4;
67
+ const di = dstRow + x * 4;
68
+ buf[di + 0] = pixels[si + 2];
69
+ buf[di + 1] = pixels[si + 1];
70
+ buf[di + 2] = pixels[si + 0];
71
+ buf[di + 3] = pixels[si + 3];
72
+ }
73
+ }
74
+
75
+ const andOffset = bmpInfoSize + pixelDataSize;
76
+ for (let y = 0; y < size; y++) {
77
+ const srcRow = (size - 1 - y) * size * 4;
78
+ for (let x = 0; x < size; x++) {
79
+ const alpha = pixels[srcRow + x * 4 + 3];
80
+ if (alpha < 128) {
81
+ const byteIdx = andOffset + y * andRowSize + Math.floor(x / 8);
82
+ buf[byteIdx] |= (0x80 >> (x % 8));
83
+ }
84
+ }
85
+ }
86
+
87
+ return { size, data: buf };
88
+ }
89
+
90
+ function setPixel(pixels, size, x, y, r, g, b, a = 255) {
91
+ if (x < 0 || x >= size || y < 0 || y >= size) return;
92
+ const i = (y * size + x) * 4;
93
+ if (a < 255 && pixels[i + 3] > 0) {
94
+ const sa = a / 255;
95
+ const da = 1 - sa;
96
+ pixels[i + 0] = Math.round(r * sa + pixels[i + 0] * da);
97
+ pixels[i + 1] = Math.round(g * sa + pixels[i + 1] * da);
98
+ pixels[i + 2] = Math.round(b * sa + pixels[i + 2] * da);
99
+ pixels[i + 3] = 255;
100
+ } else {
101
+ pixels[i + 0] = r;
102
+ pixels[i + 1] = g;
103
+ pixels[i + 2] = b;
104
+ pixels[i + 3] = a;
105
+ }
106
+ }
107
+
108
+ function fillRect(pixels, size, x0, y0, w, h, r, g, b, a = 255) {
109
+ for (let y = y0; y < y0 + h; y++)
110
+ for (let x = x0; x < x0 + w; x++)
111
+ setPixel(pixels, size, x, y, r, g, b, a);
112
+ }
113
+
114
+ function fillRoundRect(pixels, size, x0, y0, w, h, radius, r, g, b, a = 255) {
115
+ for (let y = y0; y < y0 + h; y++) {
116
+ for (let x = x0; x < x0 + w; x++) {
117
+ let inside = true;
118
+ const corners = [
119
+ [x0 + radius, y0 + radius],
120
+ [x0 + w - radius - 1, y0 + radius],
121
+ [x0 + radius, y0 + h - radius - 1],
122
+ [x0 + w - radius - 1, y0 + h - radius - 1],
123
+ ];
124
+ for (const [cx, cy] of corners) {
125
+ const inCornerX = (x < x0 + radius && cx === corners[0][0]) || (x > x0 + w - radius - 1 && cx === corners[1][0]);
126
+ const inCornerY = (y < y0 + radius && cy === corners[0][1]) || (y > y0 + h - radius - 1 && cy === corners[2][1]);
127
+ if (inCornerX && inCornerY) {
128
+ const dx = x - cx;
129
+ const dy = y - cy;
130
+ if (dx * dx + dy * dy > radius * radius) {
131
+ inside = false;
132
+ break;
133
+ }
134
+ }
135
+ }
136
+ if (inside) setPixel(pixels, size, x, y, r, g, b, a);
137
+ }
138
+ }
139
+ }
140
+
141
+ const GLYPH_N = [
142
+ [1,0,0,0,1],
143
+ [1,1,0,0,1],
144
+ [1,0,1,0,1],
145
+ [1,0,0,1,1],
146
+ [1,0,0,0,1],
147
+ ];
148
+
149
+ const GLYPH_X = [
150
+ [1,0,0,0,1],
151
+ [0,1,0,1,0],
152
+ [0,0,1,0,0],
153
+ [0,1,0,1,0],
154
+ [1,0,0,0,1],
155
+ ];
156
+
157
+ function drawGlyph(pixels, size, glyph, ox, oy, scale, r, g, b) {
158
+ for (let gy = 0; gy < glyph.length; gy++) {
159
+ for (let gx = 0; gx < glyph[gy].length; gx++) {
160
+ if (glyph[gy][gx]) {
161
+ fillRect(pixels, size, ox + gx * scale, oy + gy * scale, scale, scale, r, g, b);
162
+ }
163
+ }
164
+ }
165
+ }
166
+
167
+ function renderNaideIcon(pixels, size) {
168
+ const s = size;
169
+ const r = Math.max(2, Math.round(s * 0.15));
170
+ fillRoundRect(pixels, s, 0, 0, s, s, r, 30, 110, 230);
171
+ fillRoundRect(pixels, s, 1, 1, s - 2, s - 2, r, 40, 130, 255);
172
+
173
+ const glyphScale = Math.max(1, Math.round(s / 10));
174
+ const gw = 5 * glyphScale;
175
+ const gh = 5 * glyphScale;
176
+ const ox = Math.round((s - gw) / 2);
177
+ const oy = Math.round((s - gh) / 2);
178
+ drawGlyph(pixels, s, GLYPH_N, ox, oy, glyphScale, 255, 255, 255);
179
+ }
180
+
181
+ function renderNxIcon(pixels, size) {
182
+ const s = size;
183
+ const r = Math.max(2, Math.round(s * 0.15));
184
+ fillRoundRect(pixels, s, 0, 0, s, s, r, 20, 170, 80);
185
+ fillRoundRect(pixels, s, 1, 1, s - 2, s - 2, r, 30, 200, 100);
186
+
187
+ const glyphScale = Math.max(1, Math.round(s / 10));
188
+ const gw = 5 * glyphScale;
189
+ const gh = 5 * glyphScale;
190
+ const ox = Math.round((s - gw) / 2);
191
+ const oy = Math.round((s - gh) / 2);
192
+ drawGlyph(pixels, s, GLYPH_X, ox, oy, glyphScale, 255, 255, 255);
193
+ }
194
+
195
+ const naideIco = createICO([16, 32, 48, 64], renderNaideIcon);
196
+ const nxIco = createICO([16, 32, 48, 64], renderNxIcon);
197
+
198
+ const naideOut = resolve(__dirname, '..', 'assets', 'naide.ico');
199
+ const nxOut = resolve(__dirname, '..', 'assets', 'nx.ico');
200
+
201
+ import { mkdirSync } from 'fs';
202
+ mkdirSync(resolve(__dirname, '..', 'assets'), { recursive: true });
203
+
204
+ writeFileSync(naideOut, naideIco);
205
+ writeFileSync(nxOut, nxIco);
206
+
207
+ console.log(`Generated: ${naideOut}`);
208
+ console.log(`Generated: ${nxOut}`);
@@ -0,0 +1,135 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { execSync } from 'child_process';
4
+ import { existsSync, writeFileSync, mkdirSync, readFileSync } from 'fs';
5
+ import { resolve, dirname, join } from 'path';
6
+ import { fileURLToPath } from 'url';
7
+
8
+ const __filename = fileURLToPath(import.meta.url);
9
+ const __dirname = dirname(__filename);
10
+
11
+ const platform = process.platform;
12
+ const naideBin = resolve(__dirname, 'naide.js');
13
+
14
+ function run(cmd, opts = {}) {
15
+ try {
16
+ execSync(cmd, { stdio: 'pipe', ...opts });
17
+ return true;
18
+ } catch {
19
+ return false;
20
+ }
21
+ }
22
+
23
+ function registerWindows() {
24
+ const nodePath = process.execPath;
25
+ const npmGlobal = resolve(dirname(nodePath), 'node_modules', 'naider', 'bin', 'naide.js');
26
+ const binPath = existsSync(npmGlobal) ? npmGlobal : naideBin;
27
+
28
+ const nodeEsc = nodePath.replace(/\\/g, '\\\\');
29
+ const binEsc = binPath.replace(/\\/g, '\\\\');
30
+ const cmd = `"${nodePath}" "${binPath}" "%1" %*`;
31
+
32
+ const regAdd = (key, value) => run(`reg add "${key}" /ve /d "${value}" /f`);
33
+
34
+ regAdd('HKCU\\Software\\Classes\\.naide', 'NAIDEFile');
35
+ regAdd('HKCU\\Software\\Classes\\.nx', 'NAIDEXFile');
36
+ regAdd('HKCU\\Software\\Classes\\NAIDEFile', 'NAIDE Source File');
37
+ regAdd('HKCU\\Software\\Classes\\NAIDEXFile', 'NAIDE-X Source File');
38
+ regAdd('HKCU\\Software\\Classes\\NAIDEFile\\shell\\open\\command', cmd);
39
+ regAdd('HKCU\\Software\\Classes\\NAIDEXFile\\shell\\open\\command', cmd);
40
+
41
+ const assetsDir = resolve(__dirname, '..', 'assets');
42
+ const naideIco = resolve(assetsDir, 'naide.ico').replace(/\\/g, '\\\\');
43
+ const nxIco = resolve(assetsDir, 'nx.ico').replace(/\\/g, '\\\\');
44
+ run(`reg add "HKCU\\Software\\Classes\\NAIDEFile\\DefaultIcon" /ve /d "${naideIco}" /f`);
45
+ run(`reg add "HKCU\\Software\\Classes\\NAIDEXFile\\DefaultIcon" /ve /d "${nxIco}" /f`);
46
+
47
+ console.log(' .naide and .nx file associations registered (Windows)');
48
+ }
49
+
50
+ function registerMacOS() {
51
+ const plistDir = resolve(process.env.HOME, 'Library', 'LaunchAgents');
52
+ if (!existsSync(plistDir)) mkdirSync(plistDir, { recursive: true });
53
+
54
+ const handlerApp = resolve(process.env.HOME, '.naide', 'NAIDE.app');
55
+ const contentsDir = join(handlerApp, 'Contents');
56
+ const macosDir = join(contentsDir, 'MacOS');
57
+
58
+ mkdirSync(macosDir, { recursive: true });
59
+
60
+ writeFileSync(join(contentsDir, 'Info.plist'), `<?xml version="1.0" encoding="UTF-8"?>
61
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
62
+ <plist version="1.0">
63
+ <dict>
64
+ <key>CFBundleName</key><string>NAIDE</string>
65
+ <key>CFBundleIdentifier</key><string>com.naide.runner</string>
66
+ <key>CFBundleVersion</key><string>1.0</string>
67
+ <key>CFBundleExecutable</key><string>naide-run</string>
68
+ <key>CFBundleDocumentTypes</key>
69
+ <array>
70
+ <dict>
71
+ <key>CFBundleTypeExtensions</key><array><string>naide</string><string>nx</string></array>
72
+ <key>CFBundleTypeName</key><string>NAIDE Source</string>
73
+ <key>CFBundleTypeRole</key><string>Editor</string>
74
+ </dict>
75
+ </array>
76
+ </dict>
77
+ </plist>`);
78
+
79
+ writeFileSync(join(macosDir, 'naide-run'), `#!/bin/bash\nexec node "${naideBin}" "$@"\n`);
80
+ run(`chmod +x "${join(macosDir, 'naide-run')}"`);
81
+
82
+ run(`/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -f "${handlerApp}"`);
83
+
84
+ console.log(' .naide and .nx file associations registered (macOS)');
85
+ }
86
+
87
+ function registerLinux() {
88
+ const mimeDir = resolve(process.env.HOME, '.local', 'share', 'mime', 'packages');
89
+ const appDir = resolve(process.env.HOME, '.local', 'share', 'applications');
90
+ mkdirSync(mimeDir, { recursive: true });
91
+ mkdirSync(appDir, { recursive: true });
92
+
93
+ writeFileSync(join(mimeDir, 'naide.xml'), `<?xml version="1.0" encoding="UTF-8"?>
94
+ <mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
95
+ <mime-type type="text/x-naide">
96
+ <comment>NAIDE Source File</comment>
97
+ <glob pattern="*.naide"/>
98
+ </mime-type>
99
+ <mime-type type="text/x-naidex">
100
+ <comment>NAIDE-X Source File</comment>
101
+ <glob pattern="*.nx"/>
102
+ </mime-type>
103
+ </mime-info>`);
104
+
105
+ writeFileSync(join(appDir, 'naide.desktop'), `[Desktop Entry]
106
+ Type=Application
107
+ Name=NAIDE
108
+ Exec=node "${naideBin}" %f
109
+ MimeType=text/x-naide;text/x-naidex;
110
+ Terminal=true
111
+ Categories=Development;
112
+ `);
113
+
114
+ run('update-mime-database ~/.local/share/mime');
115
+ run('xdg-mime default naide.desktop text/x-naide');
116
+ run('xdg-mime default naide.desktop text/x-naidex');
117
+
118
+ console.log(' .naide and .nx file associations registered (Linux)');
119
+ }
120
+
121
+ console.log('NAIDE: Registering file extensions...');
122
+
123
+ try {
124
+ if (platform === 'win32') {
125
+ registerWindows();
126
+ } else if (platform === 'darwin') {
127
+ registerMacOS();
128
+ } else {
129
+ registerLinux();
130
+ }
131
+ } catch (e) {
132
+ console.log(` Skipped file association (${e.message}). You can still run: naide <file.naide>`);
133
+ }
134
+
135
+ console.log('NAIDE: Installation complete! Run "naide --help" to get started.');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "naider",
3
- "version": "1.17.0",
3
+ "version": "1.17.2",
4
4
  "description": "NAIDE - Simpler than Python, compiles to 15 targets. AI-specialized language with 35+ built-in functions, syntax sugar (unless/until/repeat/swap/is/isnt), and 47 features. Targets: Node.js, Python, TypeScript, C, C++, Java, Go, Rust, PHP, Ruby, Kotlin, Swift, Dart, C#, Bun.",
5
5
  "main": "src/index.js",
6
6
  "exports": {
@@ -14,6 +14,7 @@
14
14
  "files": [
15
15
  "bin/",
16
16
  "src/",
17
+ "assets/",
17
18
  "lsp/",
18
19
  "examples/",
19
20
  "vscode-naide/",
@@ -25,7 +26,8 @@
25
26
  "scripts": {
26
27
  "test": "node --test test/test.js",
27
28
  "example": "node bin/naide.js examples/hello.naide",
28
- "example:x": "node bin/naide.js examples/hello.nx"
29
+ "example:x": "node bin/naide.js examples/hello.nx",
30
+ "postinstall": "node bin/postinstall.js"
29
31
  },
30
32
  "keywords": [
31
33
  "ai",