@codady/utils 0.0.39 → 0.0.40

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 (36) hide show
  1. package/CHANGELOG.md +21 -2
  2. package/dist/utils.cjs.js +110 -7
  3. package/dist/utils.cjs.min.js +3 -3
  4. package/dist/utils.esm.js +110 -7
  5. package/dist/utils.esm.min.js +3 -3
  6. package/dist/utils.umd.js +110 -7
  7. package/dist/utils.umd.min.js +3 -3
  8. package/dist.zip +0 -0
  9. package/examples/ajax-download.html +94 -0
  10. package/examples/ajax-hook.html +2 -2
  11. package/examples/ajax-signal.html +91 -0
  12. package/examples/ajax-timeout.html +85 -0
  13. package/examples/stringToEncodings-collision-test-registry.html +117 -0
  14. package/examples/stringToEncodings-collision-test.html +71 -0
  15. package/examples/stringToEncodings.html +138 -0
  16. package/examples/unicodeToEncodings.html +195 -0
  17. package/modules.js +5 -1
  18. package/modules.ts +5 -1
  19. package/package.json +1 -1
  20. package/src/ajax.js +23 -6
  21. package/src/ajax.ts +30 -10
  22. package/src/stringToEncodings.js +56 -0
  23. package/src/stringToEncodings.ts +110 -0
  24. package/src/unicodeToEncodings.js +51 -0
  25. package/src/unicodeToEncodings.ts +55 -0
  26. package/src/arrayMutableMethods - /345/211/257/346/234/254.js" +0 -5
  27. package/src/capitalize - /345/211/257/346/234/254.js" +0 -19
  28. package/src/comma - /345/211/257/346/234/254.js" +0 -2
  29. package/src/deepCloneToJSON - /345/211/257/346/234/254.js" +0 -47
  30. package/src/deepMergeMaps - /345/211/257/346/234/254.js" +0 -78
  31. package/src/escapeHTML - /345/211/257/346/234/254.js" +0 -29
  32. package/src/getDataType - /345/211/257/346/234/254.js" +0 -38
  33. package/src/isEmpty - /345/211/257/346/234/254.js" +0 -45
  34. package/src/mapMutableMethods - /345/211/257/346/234/254.js" +0 -5
  35. package/src/setMutableMethods - /345/211/257/346/234/254.js" +0 -5
  36. package/src/wrapMap - /345/211/257/346/234/254.js" +0 -119
@@ -0,0 +1,91 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>AJAX AbortSignal Demo</title>
6
+ <style>
7
+ .box { border: 1px solid #ddd; padding: 20px; border-radius: 8px; margin-bottom: 20px; }
8
+ .req-item { margin: 5px 0; font-family: monospace; }
9
+ .status { font-weight: bold; }
10
+ .status-cancel { color: #faad14; }
11
+ .status-success { color: #52c41a; }
12
+ </style>
13
+ </head>
14
+ <body>
15
+ <h2>Demo 7: Control via AbortSignal</h2>
16
+
17
+ <div class="box">
18
+ <button id="btnGroupStart">Start Group Requests (3 Requests)</button>
19
+ <button id="btnCancelAll" style="color: red;" disabled>Cancel All via Signal</button>
20
+
21
+ <div id="results">
22
+ <div class="req-item">Request 1: <span id="s1" class="status">-</span></div>
23
+ <div class="req-item">Request 2: <span id="s2" class="status">-</span></div>
24
+ <div class="req-item">Request 3: <span id="s3" class="status">-</span></div>
25
+ </div>
26
+ </div>
27
+
28
+ <script src="../dist/utils.umd.js"></script>
29
+ <script>
30
+ const btnStart = document.getElementById('btnGroupStart');
31
+ const btnCancel = document.getElementById('btnCancelAll');
32
+
33
+ // 外部维护控制器
34
+ let controller = null;
35
+
36
+ btnStart.onclick = () => {
37
+ // 1. 创建新的控制器
38
+ controller = new AbortController();
39
+ const signal = controller.signal;
40
+
41
+ // UI 状态重置
42
+ [1, 2, 3].forEach(i => {
43
+ const el = document.getElementById('s' + i);
44
+ el.innerText = 'Pending...';
45
+ el.className = 'status';
46
+ });
47
+ btnStart.disabled = true;
48
+ btnCancel.disabled = false;
49
+
50
+ // 2. 同时发起 3 个请求,共享同一个 signal
51
+ [1, 2, 3].forEach(i => {
52
+ utils.ajax({
53
+ // 使用 delay 模拟长时间请求,方便我们有时间点取消
54
+ url: `https://httpbin.org/delay/${i + 2}`,
55
+ method: 'GET',
56
+ signal: signal, // <--- 关键参数:传入外部信号
57
+ onAbort: (data) => {
58
+ const el = document.getElementById('s' + i);
59
+ el.innerText = 'Canceled';
60
+ el.classList.add('status-cancel');
61
+ console.log('abort')
62
+ },
63
+ onSuccess: (data) => {
64
+ const el = document.getElementById('s' + i);
65
+ el.innerText = 'Success';
66
+ el.classList.add('status-success');
67
+ console.log('success')
68
+ },
69
+ onFinish: (data) => {
70
+ // 如果所有请求都结束了,重置按钮
71
+ if (i === 3) {
72
+ btnStart.disabled = false;
73
+ btnCancel.disabled = true;
74
+ }
75
+ console.log('finish')
76
+ }
77
+ });
78
+ });
79
+ };
80
+
81
+ // 3. 外部一键取消
82
+ btnCancel.onclick = () => {
83
+ if (controller) {
84
+ // 只要这一个指令,所有绑定了该 signal 的 ajax 请求都会立即停止
85
+ controller.abort();
86
+ console.log('Signal sent: All associated requests aborted.');
87
+ }
88
+ };
89
+ </script>
90
+ </body>
91
+ </html>
@@ -0,0 +1,85 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <body>
4
+ <h2>Demo 5: Timeout & Manual Abort</h2>
5
+
6
+ <div class="control-panel">
7
+ <p>Target: <code>/delay/10</code> (Server waits 10s before responding)</p>
8
+ <button id="btnTimeout">Start (3s Timeout)</button>
9
+
10
+ <button id="btnStartManual">Start (Manual Cancel)</button>
11
+ <button id="btnAbort" disabled style="color: red;">Abort Now!</button>
12
+ </div>
13
+
14
+ <h4>Execution Logs:</h4>
15
+ <ul id="logs"></ul>
16
+
17
+ <script src="../dist/utils.umd.js"></script>
18
+ <script >
19
+
20
+ const logs = document.getElementById('logs');
21
+ const btnAbort = document.getElementById('btnAbort');
22
+ let currentXHR = null;
23
+
24
+ const addLog = (msg, color = '') => {
25
+ const time = new Date().toLocaleTimeString().split(' ')[0];
26
+ const li = document.createElement('li');
27
+ li.innerHTML = `<span class="log-time">[${time}]</span> <span style="color:${color}">${msg}</span>`;
28
+ logs.appendChild(li);
29
+ logs.scrollTop = logs.scrollHeight;
30
+ };
31
+
32
+ // --- 场景 1: 自动超时 ---
33
+ document.getElementById('btnTimeout').onclick = () => {
34
+ addLog('Request started: Expecting timeout in 3s...', '#569cd6');
35
+
36
+ utils.ajax({
37
+ url: 'https://httpbin.org/delay/10',
38
+ method: 'GET',
39
+ timeout: 3000, // 3秒超时
40
+ onTimeout: (res) => {
41
+ addLog('HOOK: onTimeout triggered!', '#faad14');
42
+ },
43
+ onFailure: (res) => {
44
+ if (res.type === 'timeout') {
45
+ addLog('RESULT: Promise caught timeout error.', '#ff4d4f');
46
+ }
47
+ },
48
+ onFinish: () => addLog('Lifecycle: Finished.')
49
+ });
50
+ };
51
+
52
+ // --- 场景 2: 手动中止 ---
53
+ document.getElementById('btnStartManual').onclick = () => {
54
+ addLog('Request started: Use "Abort" button to cancel.', '#569cd6');
55
+ btnAbort.disabled = false;
56
+
57
+ utils.ajax({
58
+ url: 'https://httpbin.org/delay/10',
59
+ method: 'GET',
60
+ onCreated: (res) => {
61
+ // 获取内部的 abort 方法
62
+ currentXHR = res;
63
+ addLog('Lifecycle: Created (Abort function captured)');
64
+ },
65
+ onAbort: () => {
66
+ addLog('HOOK: onAbort triggered!', '#faad14');
67
+ },
68
+ onSuccess: () => addLog('Success! (If you see this, you were too slow to click abort)'),
69
+ onFinish: () => {
70
+ addLog('Lifecycle: Finished.');
71
+ btnAbort.disabled = true;
72
+ }
73
+ });
74
+ };
75
+
76
+ document.getElementById('btnAbort').onclick = () => {
77
+ if (currentXHR) {
78
+ currentXHR.abort(); // 调用封装好的 abort 方法
79
+ addLog('Action: .abort() called manually.', '#ff4d4f');
80
+ currentXHR = null;
81
+ }
82
+ };
83
+ </script>
84
+ </body>
85
+ </html>
@@ -0,0 +1,117 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <title>Unicode Collision Tester (Hash vs Registry)</title>
6
+ <style>
7
+ body { font-family: system-ui, sans-serif; padding: 20px; }
8
+ input, button { padding: 6px 10px; font-size: 14px; }
9
+ pre { background: #f7f7f7; padding: 10px; max-height: 260px; overflow: auto; }
10
+ .stat { margin-top: 12px; font-weight: bold; }
11
+ .grid { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-top: 16px; }
12
+ h3 { margin-bottom: 6px; }
13
+ </style>
14
+ </head>
15
+ <body>
16
+
17
+ <h2>Unicode Collision Tester — Hash vs Registry</h2>
18
+
19
+ <label>Test Count:</label>
20
+ <input id="count" type="number" value="20000" min="1" step="1000" />
21
+ <button onclick="runTest()">Run Test</button>
22
+
23
+ <div class="grid">
24
+ <div>
25
+ <h3>Hash-only Mode (No Registry)</h3>
26
+ <div class="stat" id="statsHash"></div>
27
+ <pre id="logHash"></pre>
28
+ </div>
29
+
30
+ <div>
31
+ <h3>Registry Mode (Zero Collision)</h3>
32
+ <div class="stat" id="statsRegistry"></div>
33
+ <pre id="logRegistry"></pre>
34
+ </div>
35
+ </div>
36
+
37
+ <script src="../dist/utils.umd.js"></script>
38
+
39
+ <script>
40
+
41
+ // =======================================
42
+ // Collision Tester
43
+ // =======================================
44
+
45
+ function runTest() {
46
+ const count = Number(document.getElementById("count").value);
47
+
48
+ const usedHash = new Map(); // codePoint -> name
49
+ const collisionsHash = [];
50
+
51
+ const registry = new Map();
52
+ const usedRegistry = new Map();
53
+ const collisionsRegistry = [];
54
+
55
+ console.time("Hash Mode");
56
+ for (let i = 0; i < count; i++) {
57
+ const name = `icon-${i.toString().padStart(6, "0")}`;
58
+ const result = utils.stringToEncodings(name);
59
+
60
+ if (usedHash.has(result.codePoint)) {
61
+ collisionsHash.push({
62
+ name,
63
+ collidesWith: usedHash.get(result.codePoint),
64
+ unicode: result.unicode
65
+ });
66
+ } else {
67
+ usedHash.set(result.codePoint, name);
68
+ }
69
+ }
70
+ console.timeEnd("Hash Mode");
71
+
72
+ console.time("Registry Mode");
73
+ for (let i = 0; i < count; i++) {
74
+ const name = `icon-${i.toString().padStart(6, "0")}`;
75
+ const result = utils.stringToEncodings(name, { registryMap: registry });
76
+
77
+ if (usedRegistry.has(result.codePoint)) {
78
+ collisionsRegistry.push({
79
+ name,
80
+ collidesWith: usedRegistry.get(result.codePoint),
81
+ unicode: result.unicode
82
+ });
83
+ } else {
84
+ usedRegistry.set(result.codePoint, name);
85
+ }
86
+ }
87
+ console.timeEnd("Registry Mode");
88
+
89
+ const rateHash = (collisionsHash.length / count * 100).toFixed(4);
90
+ const rateRegistry = (collisionsRegistry.length / count * 100).toFixed(4);
91
+
92
+ document.getElementById("statsHash").textContent =
93
+ `Total: ${count} | Unique Unicode: ${usedHash.size} | Collisions: ${collisionsHash.length} | Collision Rate: ${rateHash}%`;
94
+
95
+ document.getElementById("statsRegistry").textContent =
96
+ `Total: ${count} | Unique Unicode: ${usedRegistry.size} | Collisions: ${collisionsRegistry.length} | Collision Rate: ${rateRegistry}%`;
97
+
98
+ document.getElementById("logHash").textContent =
99
+ collisionsHash.length
100
+ ? collisionsHash.slice(0, 100).map(c =>
101
+ `${c.name} ↔ ${c.collidesWith} → ${c.unicode}`
102
+ ).join("\n")
103
+ : "No collisions 🎉";
104
+
105
+ document.getElementById("logRegistry").textContent =
106
+ collisionsRegistry.length
107
+ ? collisionsRegistry.slice(0, 20).map(c =>
108
+ `${c.name} ↔ ${c.collidesWith} → ${c.unicode}`
109
+ ).join("\n")
110
+ : "Zero collisions ✅ (Expected)";
111
+
112
+ console.log(registry)
113
+ }
114
+ </script>
115
+
116
+ </body>
117
+ </html>
@@ -0,0 +1,71 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <title>Unicode Collision Tester (utils.stringToEncodings)</title>
6
+ <style>
7
+ body { font-family: system-ui, sans-serif; padding: 20px; }
8
+ input, button { padding: 6px 10px; font-size: 14px; }
9
+ pre { background: #f7f7f7; padding: 10px; max-height: 300px; overflow: auto; }
10
+ .stat { margin-top: 12px; font-weight: bold; }
11
+ </style>
12
+ </head>
13
+ <body>
14
+
15
+ <h2>Unicode Collision Tester (PUA Plane 15–16)</h2>
16
+
17
+ <label>Test Count:</label>
18
+ <input id="count" type="number" value="10000" min="1" step="1000" />
19
+ <button onclick="runTest()">Run Test</button>
20
+
21
+ <div class="stat" id="stats"></div>
22
+ <pre id="log"></pre>
23
+
24
+ <script src="../dist/utils.umd.js"></script>
25
+
26
+ <script>
27
+
28
+ // ==============================
29
+ // Collision Tester
30
+ // ==============================
31
+
32
+ function runTest() {
33
+ const count = Number(document.getElementById("count").value);
34
+ const used = new Map(); // codePoint -> name
35
+ const collisions = [];
36
+
37
+ console.time("Test Time");
38
+
39
+ for (let i = 0; i < count; i++) {
40
+ const name = `icon-${i.toString().padStart(6, "0")}`;
41
+ const result = utils.stringToEncodings(name);
42
+
43
+ if (used.has(result.codePoint)) {
44
+ collisions.push({
45
+ name,
46
+ collidesWith: used.get(result.codePoint),
47
+ unicode: result.unicode
48
+ });
49
+ } else {
50
+ used.set(result.codePoint, name);
51
+ }
52
+ }
53
+
54
+ console.timeEnd("Test Time");
55
+
56
+ const collisionRate = (collisions.length / count * 100).toFixed(4);
57
+
58
+ document.getElementById("stats").textContent =
59
+ `Total: ${count} | Unique Unicode: ${used.size} | Collisions: ${collisions.length} | Collision Rate: ${collisionRate}%`;
60
+
61
+ const log = document.getElementById("log");
62
+ log.textContent = collisions.length
63
+ ? collisions.slice(0, 100).map(c =>
64
+ `${c.name} ↔ ${c.collidesWith} → ${c.unicode}`
65
+ ).join("\n")
66
+ : "No collisions detected 🎉";
67
+ }
68
+ </script>
69
+
70
+ </body>
71
+ </html>
@@ -0,0 +1,138 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <title>utils.stringToEncodings Demo (Hash + Registry Mode)</title>
6
+ <style>
7
+ body {
8
+ font-family: system-ui, -apple-system, Segoe UI, Roboto, Ubuntu, Cantarell;
9
+ background: #0f172a;
10
+ color: #e5e7eb;
11
+ padding: 24px;
12
+ }
13
+ input, textarea {
14
+ width: 100%;
15
+ padding: 10px;
16
+ margin-top: 6px;
17
+ border-radius: 8px;
18
+ border: 1px solid #334155;
19
+ background: #020617;
20
+ color: white;
21
+ }
22
+ button {
23
+ padding: 10px 16px;
24
+ border-radius: 8px;
25
+ border: none;
26
+ background: #38bdf8;
27
+ color: black;
28
+ font-weight: 600;
29
+ cursor: pointer;
30
+ margin-top: 12px;
31
+ }
32
+ table {
33
+ width: 100%;
34
+ border-collapse: collapse;
35
+ margin-top: 16px;
36
+ }
37
+ th, td {
38
+ text-align: left;
39
+ padding: 10px;
40
+ border-bottom: 1px solid #334155;
41
+ font-family: monospace;
42
+ }
43
+ .badge {
44
+ padding: 2px 8px;
45
+ border-radius: 6px;
46
+ font-size: 12px;
47
+ }
48
+ .ok { background: #22c55e; color: black; }
49
+ .warn { background: #f59e0b; color: black; }
50
+ </style>
51
+ </head>
52
+ <body>
53
+
54
+ <h2>utils.stringToEncodings Demo</h2>
55
+
56
+ <label>Input String</label>
57
+ <input id="input" value="arrowUpSolid" />
58
+
59
+ <label style="margin-top:12px;">
60
+ <input type="checkbox" id="useRegistry" checked />
61
+ Enable Registry Mode (Zero Collision)
62
+ </label>
63
+
64
+ <label style="margin-top:12px;">Batch Input (one per line)</label>
65
+ <textarea id="batch" rows="6">arrowUpSolid
66
+ arrowDownSolid
67
+ homeOutline
68
+ settingsGear
69
+ userCircle</textarea>
70
+
71
+ <button onclick="run()">Generate</button>
72
+
73
+ <p id="stats"></p>
74
+
75
+ <table id="output">
76
+ <thead>
77
+ <tr>
78
+ <th>Name</th>
79
+ <th>Unicode</th>
80
+ <th>Hex</th>
81
+ <th>HTML Dec</th>
82
+ <th>HTML Hex</th>
83
+ <th>Hash</th>
84
+ <th>Collision</th>
85
+ </tr>
86
+ </thead>
87
+ <tbody></tbody>
88
+ </table>
89
+
90
+ <script src="../dist/utils.umd.js"></script>
91
+
92
+ <script>
93
+ // ------------------------------
94
+ // Registry (persistent in session)
95
+ // ------------------------------
96
+ const registry = new Map();
97
+
98
+ // ------------------------------
99
+ // UI Handler
100
+ // ------------------------------
101
+ function run() {
102
+ const input = document.getElementById("input").value.trim();
103
+ const batchLines = document.getElementById("batch").value.split("\n").map(s => s.trim()).filter(Boolean);
104
+ const useRegistry = document.getElementById("useRegistry").checked;
105
+
106
+ const list = [input, ...batchLines].filter(Boolean);
107
+
108
+ const tbody = document.querySelector("#output tbody");
109
+ tbody.innerHTML = "";
110
+
111
+ list.forEach(name => {
112
+ const result = utils.stringToEncodings(name, useRegistry ? { registryMap: registry } : {});
113
+ const tr = document.createElement("tr");
114
+
115
+ tr.innerHTML = `
116
+ <td>${name}</td>
117
+ <td>${result.unicode}</td>
118
+ <td>${result.hex}</td>
119
+ <td><code>${utils.escapeHTML(result.htmlDec)}</code></td>
120
+ <td><code>${utils.escapeHTML(result.htmlHex)}</code></td>
121
+ <td title="${result.hash}">${result.hash.slice(0,20)}...</td>
122
+ <td>
123
+ <span class="badge ${result.collision ? "warn" : "ok"}">
124
+ ${result.collision ? "Collision" : "OK"}
125
+ </span>
126
+ </td>
127
+ `;
128
+
129
+ tbody.appendChild(tr);
130
+ });
131
+
132
+ document.getElementById("stats").textContent =
133
+ `Registry Size: ${registry.size} entries`;
134
+ }
135
+ </script>
136
+
137
+ </body>
138
+ </html>
@@ -0,0 +1,195 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8" />
6
+ <title>Unicode Encoding Parser Demo</title>
7
+ <style>
8
+ body {
9
+ font-family: system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
10
+ background: #0f172a;
11
+ color: #e5e7eb;
12
+ padding: 24px;
13
+ }
14
+
15
+ h1 {
16
+ font-size: 20px;
17
+ margin-bottom: 12px;
18
+ }
19
+
20
+ .examples {
21
+ display: flex;
22
+ flex-wrap: wrap;
23
+ gap: 8px;
24
+ margin-bottom: 12px;
25
+ }
26
+
27
+ button {
28
+ background: #020617;
29
+ border: 1px solid #334155;
30
+ color: #e5e7eb;
31
+ padding: 6px 10px;
32
+ border-radius: 8px;
33
+ cursor: pointer;
34
+ font-size: 14px;
35
+ }
36
+
37
+ button:hover {
38
+ border-color: #38bdf8;
39
+ color: #38bdf8;
40
+ }
41
+
42
+ input {
43
+ width: 100%;
44
+ padding: 10px;
45
+ font-size: 16px;
46
+ border-radius: 8px;
47
+ border: 1px solid #334155;
48
+ background: #020617;
49
+ color: #fff;
50
+ outline: none;
51
+ margin-bottom: 10px;
52
+ }
53
+
54
+ input:focus {
55
+ border-color: #38bdf8;
56
+ }
57
+
58
+ .hint {
59
+ font-size: 13px;
60
+ color: #94a3b8;
61
+ margin-bottom: 10px;
62
+ }
63
+
64
+ table {
65
+ width: 100%;
66
+ margin-top: 12px;
67
+ border-collapse: collapse;
68
+ background: #020617;
69
+ border-radius: 12px;
70
+ overflow: hidden;
71
+ }
72
+
73
+ th,
74
+ td {
75
+ padding: 10px 12px;
76
+ border-bottom: 1px solid #1e293b;
77
+ text-align: left;
78
+ }
79
+
80
+ th {
81
+ width: 200px;
82
+ color: #93c5fd;
83
+ }
84
+
85
+ code {
86
+ background: #020617;
87
+ padding: 2px 6px;
88
+ border-radius: 6px;
89
+ color: #fbbf24;
90
+ }
91
+
92
+ .preview {
93
+ font-size: 48px;
94
+ margin-top: 12px;
95
+ }
96
+
97
+ .error {
98
+ color: #f87171;
99
+ margin-top: 8px;
100
+ }
101
+ </style>
102
+ </head>
103
+
104
+ <body>
105
+
106
+ <h1>Unicode → Encoding Parser Demo</h1>
107
+
108
+ <div class="examples">
109
+ <button onclick="setExample('U+1F600')">😀 Emoji (U+1F600)</button>
110
+ <button onclick="setExample('U+E001')">PUA Example (U+E001)</button>
111
+ <button onclick="setExample('F123')">Hex Example (F123)</button>
112
+ <button onclick="setExample('61731')">Decimal Example (61731)</button>
113
+ <button onclick="setExample('0x1F680')">Rocket (0x1F680)</button>
114
+ <button onclick="setExample('❤️')">Heart Emoji</button>
115
+ </div>
116
+
117
+ <input id="input" placeholder="Enter Unicode: U+F123 | F123 | 0xF123 | 61731 | 😀" />
118
+
119
+ <div class="hint">
120
+ Supported formats: <code>U+F123</code>, <code>F123</code>, <code>0xF123</code>, <code>61731</code>, <code>😀</code>
121
+ </div>
122
+
123
+ <div id="error" class="error"></div>
124
+
125
+ <table id="output" style="display:none;">
126
+ <tr>
127
+ <th>Unicode</th>
128
+ <td><code id="unicode"></code></td>
129
+ </tr>
130
+ <tr>
131
+ <th>Hex</th>
132
+ <td><code id="hex"></code></td>
133
+ </tr>
134
+ <tr>
135
+ <th>Code Point (Dec)</th>
136
+ <td><code id="codePoint"></code></td>
137
+ </tr>
138
+ <tr>
139
+ <th>HTML Decimal</th>
140
+ <td><code id="htmlDec"></code></td>
141
+ </tr>
142
+ <tr>
143
+ <th>HTML Hex</th>
144
+ <td><code id="htmlHex"></code></td>
145
+ </tr>
146
+ </table>
147
+
148
+ <div class="preview" id="preview"></div>
149
+ <script src="../dist/utils.umd.js"></script>
150
+
151
+ <script>
152
+ function setExample(value) {
153
+ const input = document.getElementById("input");
154
+ input.value = value;
155
+ input.dispatchEvent(new Event("input"));
156
+ }
157
+
158
+ const input = document.getElementById("input");
159
+ const error = document.getElementById("error");
160
+ const output = document.getElementById("output");
161
+
162
+ input.addEventListener("input", () => {
163
+ const value = input.value.trim();
164
+
165
+ if (!value) {
166
+ output.style.display = "none";
167
+ error.textContent = "";
168
+ document.getElementById("preview").textContent = "";
169
+ return;
170
+ }
171
+
172
+ try {
173
+ const result = utils.unicodeToEncodings(value);
174
+
175
+ document.getElementById("unicode").textContent = result.unicode;
176
+ document.getElementById("hex").textContent = result.hex;
177
+ document.getElementById("codePoint").textContent = result.codePoint;
178
+ document.getElementById("htmlDec").textContent = result.htmlDec;
179
+ document.getElementById("htmlHex").textContent = result.htmlHex;
180
+ document.getElementById("preview").textContent = result.char;
181
+
182
+ output.style.display = "table";
183
+ error.textContent = "";
184
+ }
185
+ catch (e) {
186
+ output.style.display = "none";
187
+ document.getElementById("preview").textContent = "";
188
+ error.textContent = e.message;
189
+ }
190
+ });
191
+ </script>
192
+
193
+ </body>
194
+
195
+ </html>