@dupliter/dupliter 0.0.1 → 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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ashlan Chidester
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,73 @@
1
+ # @dupliter/dupliter 🪐
2
+
3
+ **Retro BBS-style terminal simulator for the Dupliter gravitational-temporal anchor hypothesis.**
4
+
5
+ Computes the relativistic/classical kinetic-energy ratio and a pedagogical *Dupliter Stability Index* (DSI).
6
+
7
+ ```
8
+ ____ _ _ _ _ _ _ _ _ ___ _ _ _____
9
+ | _ \| | | || | (_) | \| | | |/ _ \| \ | ||_ _|
10
+ | | | | |_| || | _| | .` | | | | | | \| | | |
11
+ | |_| | _ || |___| | | |\ |_| | |_| | |\ | | |
12
+ |____/|_| |_||_____|_|_|_| \_(_) |\___/|_| \_| |_|
13
+ ```
14
+
15
+ Also available on PyPI: [`pip install dupliter`](https://pypi.org/project/dupliter/)
16
+
17
+ ## Install
18
+
19
+ ```bash
20
+ npm install -g @dupliter/dupliter
21
+ ```
22
+
23
+ ## Run
24
+
25
+ ```bash
26
+ dupliter
27
+ ```
28
+
29
+ Or without installing globally:
30
+
31
+ ```bash
32
+ npx @dupliter/dupliter
33
+ ```
34
+
35
+ ## JS API
36
+
37
+ ```js
38
+ import { relativisticToClassicalRatio, dupliterStabilityIndex, verdict } from '@dupliter/dupliter';
39
+
40
+ const ratio = relativisticToClassicalRatio(0.5); // β = 0.5c
41
+ const dsi = dupliterStabilityIndex(ratio, 2.0, 3.0);
42
+ const { level, message } = verdict(dsi);
43
+
44
+ console.log(`Ratio : ${ratio.toFixed(4)}`);
45
+ console.log(`DSI : ${dsi.toFixed(2)} [${level}] — ${message}`);
46
+ ```
47
+
48
+ ## Parameters
49
+
50
+ | Parameter | Description |
51
+ |---|---|
52
+ | **β (v/c)** | Fractional velocity as a fraction of light speed (0 – 0.9999) |
53
+ | **Dark-matter potential** | Dimensionless toy factor representing local DM density |
54
+ | **Anchor strength** | Dimensionless toy factor for gravitational anchor magnitude |
55
+
56
+ ## Equation
57
+
58
+ ```
59
+ ratio = 2 * (1/√(1−β²) − 1) / β²
60
+ ```
61
+
62
+ | DSI range | Verdict |
63
+ |---|---|
64
+ | ≥ 60 | High — plausible Dupliter regime |
65
+ | 30–59 | Moderate — marginal potential |
66
+ | 1–29 | Low — unstable |
67
+ | 0 | None |
68
+
69
+ > **Note:** DSI is an exploratory, educational metric — not a peer-reviewed physical quantity.
70
+
71
+ ## License
72
+
73
+ MIT © Ashlan Chidester
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * dupliter CLI — launches the BBS terminal.
4
+ * Installed as `dupliter` command via package.json bin field.
5
+ */
6
+
7
+ import { main } from '../src/bbs.js';
8
+
9
+ main().catch((err) => {
10
+ if (err.code === 'ERR_USE_AFTER_CLOSE') process.exit(0); // readline closed cleanly
11
+ console.error(err);
12
+ process.exit(1);
13
+ });
package/package.json CHANGED
@@ -1,8 +1,40 @@
1
1
  {
2
2
  "name": "@dupliter/dupliter",
3
- "version": "0.0.1",
4
- "description": "Conceptual placeholder for Dupliter",
5
- "main": "index.js",
3
+ "version": "0.1.0",
4
+ "description": "Retro BBS-style terminal simulator for the Dupliter gravitational-temporal anchor hypothesis",
6
5
  "author": "Ashlan Chidester",
7
- "license": "MIT"
6
+ "license": "MIT",
7
+ "type": "module",
8
+ "main": "./src/index.js",
9
+ "exports": {
10
+ ".": "./src/index.js",
11
+ "./core": "./src/core.js"
12
+ },
13
+ "bin": {
14
+ "dupliter": "./bin/dupliter.js"
15
+ },
16
+ "keywords": [
17
+ "physics",
18
+ "relativity",
19
+ "terminal",
20
+ "bbs",
21
+ "simulation",
22
+ "educational",
23
+ "dupliter",
24
+ "cli"
25
+ ],
26
+ "engines": {
27
+ "node": ">=16"
28
+ },
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "https://github.com/dupliter/dupliter"
32
+ },
33
+ "homepage": "https://www.npmjs.com/package/@dupliter/dupliter",
34
+ "files": [
35
+ "src/",
36
+ "bin/",
37
+ "README.md",
38
+ "LICENSE"
39
+ ]
8
40
  }
package/src/bbs.js ADDED
@@ -0,0 +1,164 @@
1
+ /**
2
+ * dupliter/bbs.js
3
+ * Retro BBS-style terminal front-end for the Dupliter hypothesis simulator.
4
+ */
5
+
6
+ import * as readline from 'readline';
7
+ import { relativisticToClassicalRatio, dupliterStabilityIndex, verdict } from './core.js';
8
+
9
+ // ---------------------------------------------------------------------------
10
+ // ANSI helpers
11
+ // ---------------------------------------------------------------------------
12
+ const CSI = '\x1b[';
13
+ const RESET = CSI + '0m';
14
+ const BOLD = CSI + '1m';
15
+ const fg = (n) => `${CSI}38;5;${n}m`;
16
+
17
+ function clear() { process.stdout.write(CSI + '2J' + CSI + 'H'); }
18
+
19
+ function slowPrint(text, delay = 6) {
20
+ return new Promise((resolve) => {
21
+ let i = 0;
22
+ const tick = () => {
23
+ if (i < text.length) {
24
+ process.stdout.write(text[i++]);
25
+ setTimeout(tick, delay);
26
+ } else {
27
+ process.stdout.write('\n');
28
+ resolve();
29
+ }
30
+ };
31
+ tick();
32
+ });
33
+ }
34
+
35
+ function divider() {
36
+ const cols = process.stdout.columns || 80;
37
+ console.log(fg(238) + '─'.repeat(cols) + RESET);
38
+ }
39
+
40
+ function headline(text) {
41
+ const cols = process.stdout.columns || 80;
42
+ const pad = Math.max(0, Math.floor((cols - text.length) / 2));
43
+ console.log(fg(81) + BOLD + ' '.repeat(pad) + text + RESET);
44
+ }
45
+
46
+ // ---------------------------------------------------------------------------
47
+ // Art & copy
48
+ // ---------------------------------------------------------------------------
49
+ const JUPITER = `
50
+ .-''-.
51
+ .-' .---. \`-.
52
+ / .' \`. \\
53
+ / / .-"-.-. \\ \\
54
+ ; ; / .-. \\; ;
55
+ | | | / \\ || |
56
+ ; ; | | .-. | ;' ;
57
+ \\ \\ \\ \`-' / / /
58
+ \`. \`.\`\`\`.' .' .'
59
+ \`-._\`---'_.-'
60
+ \`---'
61
+ `;
62
+
63
+ const BANNER = [
64
+ `${fg(220)}${BOLD} ____ _ _ _ _ _ _ _ _ ___ _ _ _____ ${RESET}`,
65
+ `${fg(220)}${BOLD} | _ \\| | | || | (_) | \\| | | |/ _ \\| \\ | ||_ _|${RESET}`,
66
+ `${fg(220)}${BOLD} | | | | |_| || | _| | .\` | | | | | | \\| | | | ${RESET}`,
67
+ `${fg(220)}${BOLD} | |_| | _ || |___| | | |\\ |_| | |_| | |\\ | | | ${RESET}`,
68
+ `${fg(220)}${BOLD} |____/|_| |_||_____|_|_|_| \\_(_) |\\___/|_| \\_| |_| ${RESET}`,
69
+ ];
70
+
71
+ const INTRO =
72
+ 'Connecting to DUPliter Node... BBS handshake engaged.\n' +
73
+ 'Transmitting the Dupliter hypothesis — a gravitational temporal anchor.\n' +
74
+ 'This simulator computes the relativistic/classical KE ratio and a\n' +
75
+ 'pedagogical Dupliter Stability Index (DSI).\n\n' +
76
+ 'Note: DSI is a comparative, educational metric. Play, learn,\n' +
77
+ 'and refine models responsibly.\n';
78
+
79
+ const VERDICT_COLOURS = {
80
+ High: (m) => fg(82) + BOLD + m + RESET,
81
+ Moderate: (m) => fg(226) + m + RESET,
82
+ Low: (m) => fg(208) + m + RESET,
83
+ None: (m) => fg(196) + m + RESET,
84
+ };
85
+
86
+ // ---------------------------------------------------------------------------
87
+ // Input helpers
88
+ // ---------------------------------------------------------------------------
89
+ function promptFloat(rl, question, defaultVal, minVal, maxVal) {
90
+ return new Promise((resolve) => {
91
+ const ask = () => {
92
+ rl.question(fg(250) + question + RESET + ' ', (raw) => {
93
+ const trimmed = raw.trim();
94
+ if (trimmed === '') { resolve(defaultVal); return; }
95
+ const val = parseFloat(trimmed);
96
+ if (isNaN(val)) {
97
+ console.log(fg(208) + 'Please enter a valid number.' + RESET);
98
+ ask(); return;
99
+ }
100
+ if (minVal !== undefined && val < minVal) {
101
+ console.log(fg(196) + `Value too small (minimum ${minVal}).` + RESET);
102
+ ask(); return;
103
+ }
104
+ if (maxVal !== undefined && val > maxVal) {
105
+ console.log(fg(196) + `Value too large (maximum ${maxVal}).` + RESET);
106
+ ask(); return;
107
+ }
108
+ resolve(val);
109
+ });
110
+ };
111
+ ask();
112
+ });
113
+ }
114
+
115
+ // ---------------------------------------------------------------------------
116
+ // Main
117
+ // ---------------------------------------------------------------------------
118
+ export async function main() {
119
+ clear();
120
+ BANNER.forEach((l) => console.log(l));
121
+ console.log(fg(244) + JUPITER + RESET);
122
+ await slowPrint(INTRO, 4);
123
+ headline('DUPliter INTERACTIVE TERMINAL v0.1.0');
124
+ console.log();
125
+
126
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
127
+
128
+ const loop = async () => {
129
+ console.log(fg(153) + BOLD + 'Enter parameters (press Enter to accept defaults):' + RESET);
130
+
131
+ const beta = await promptFloat(rl, 'Fractional velocity β = v/c, range 0..0.9999 [default 0.1]:', 0.1, 0, 0.9999);
132
+ const dm = await promptFloat(rl, 'Dark-matter potential factor (0..1000000) [default 1.0]:', 1.0, 0, 1e6);
133
+ const anchor = await promptFloat(rl, 'Gravitational anchor strength (0..1000000) [default 1.0]:', 1.0, 0, 1e6);
134
+ console.log();
135
+
136
+ const ratio = relativisticToClassicalRatio(beta);
137
+ const dsi = dupliterStabilityIndex(ratio, dm, anchor);
138
+ const { level, message } = verdict(dsi);
139
+ const coloured = (VERDICT_COLOURS[level] || ((m) => m))(message);
140
+
141
+ divider();
142
+ console.log(fg(39) + BOLD + 'Computed metrics:' + RESET);
143
+ console.log(` β (v/c) : ${fg(153)}${beta.toPrecision(6)}${RESET}`);
144
+ console.log(` Relativistic / Classical KE ratio: ${fg(153)}${ratio.toPrecision(6)}${RESET}`);
145
+ console.log(` Dupliter Stability Index (DSI) : ${fg(153)}${dsi.toFixed(4)}${RESET} [${level}]`);
146
+ console.log(` Assessment : ${coloured}`);
147
+ console.log();
148
+ console.log(fg(244) + ' Equation: 2*(1/√(1−β²) − 1) / β² where β = v/c' + RESET);
149
+ divider();
150
+ console.log();
151
+
152
+ rl.question(fg(250) + 'Run another simulation? (Y/n): ' + RESET, async (ans) => {
153
+ if (ans.trim().toLowerCase() === 'n' || ans.trim().toLowerCase() === 'no') {
154
+ console.log(fg(245) + 'Disconnecting from DUPliter Node. Keep hypothesizing.' + RESET);
155
+ rl.close();
156
+ } else {
157
+ console.log();
158
+ await loop();
159
+ }
160
+ });
161
+ };
162
+
163
+ await loop();
164
+ }
package/src/core.js ADDED
@@ -0,0 +1,60 @@
1
+ /**
2
+ * dupliter/core.js
3
+ * Pure-math functions for the Dupliter hypothesis simulator.
4
+ * No I/O or terminal dependencies — safe to import anywhere.
5
+ */
6
+
7
+ /**
8
+ * Compute the ratio of relativistic KE to classical KE.
9
+ *
10
+ * Formula: 2 * (1/√(1−β²) − 1) / β²
11
+ * where β = v/c (fraction of light speed).
12
+ *
13
+ * @param {number} beta - v/c, must be in range [0, 1)
14
+ * @returns {number} ratio (Infinity if beta >= 1, 0 if beta <= 0)
15
+ */
16
+ export function relativisticToClassicalRatio(beta) {
17
+ if (beta <= 0) return 0;
18
+ if (beta >= 1) return Infinity;
19
+ const gamma = 1 / Math.sqrt(1 - beta * beta);
20
+ return (2 * (gamma - 1)) / (beta * beta);
21
+ }
22
+
23
+ /**
24
+ * Heuristic Dupliter Stability Index (DSI).
25
+ *
26
+ * Combines the relativistic/classical KE ratio with toy environmental
27
+ * parameters into a 0–100-ish comparative score.
28
+ *
29
+ * Educational/exploratory metric — not a peer-reviewed physical quantity.
30
+ *
31
+ * @param {number} ratio - output of relativisticToClassicalRatio()
32
+ * @param {number} dmFactor - dark-matter potential (dimensionless)
33
+ * @param {number} anchorStrength - gravitational anchor strength (dimensionless)
34
+ * @param {number} [noise=0.01] - random noise fraction
35
+ * @returns {number} DSI score >= 0
36
+ */
37
+ export function dupliterStabilityIndex(ratio, dmFactor, anchorStrength, noise = 0.01) {
38
+ const r = Math.max(ratio, 1e-12);
39
+ const logR = Math.log10(r + 1);
40
+ const base =
41
+ logR * 0.6 +
42
+ Math.log10(dmFactor + 1) * 0.25 +
43
+ Math.log10(anchorStrength + 1) * 0.15;
44
+ let dsi = (base / Math.log10(1e6 + 1)) * 100;
45
+ dsi *= 1 + (Math.random() * 2 - 1) * noise;
46
+ return Math.max(dsi, 0);
47
+ }
48
+
49
+ /**
50
+ * Return a verdict for a given DSI score.
51
+ *
52
+ * @param {number} dsi
53
+ * @returns {{ level: string, message: string }}
54
+ */
55
+ export function verdict(dsi) {
56
+ if (dsi >= 60) return { level: 'High', message: 'Plausible Dupliter regime — strong anchor.' };
57
+ if (dsi >= 30) return { level: 'Moderate', message: 'Marginal potential — further refinement needed.' };
58
+ if (dsi > 0) return { level: 'Low', message: 'Unstable — insufficient parameters.' };
59
+ return { level: 'None', message: 'No Dupliter potential detected.' };
60
+ }
package/src/index.js ADDED
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @dupliter/dupliter
3
+ * Public API entry point.
4
+ */
5
+
6
+ export { relativisticToClassicalRatio, dupliterStabilityIndex, verdict } from './core.js';
7
+ export { main } from './bbs.js';
package/index.js DELETED
@@ -1,5 +0,0 @@
1
- // Dupliter: conceptual anchor
2
- module.exports = {
3
- name: "dupliter",
4
- description: "A conceptual placeholder for temporal anchoring theory"
5
- };