@atmaticai/agent-tools-core 1.0.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/README.md +742 -0
- package/dist/archive/index.d.mts +1 -0
- package/dist/archive/index.d.ts +1 -0
- package/dist/archive/index.js +90 -0
- package/dist/archive/index.js.map +1 -0
- package/dist/archive/index.mjs +80 -0
- package/dist/archive/index.mjs.map +1 -0
- package/dist/color/index.d.mts +1 -0
- package/dist/color/index.d.ts +1 -0
- package/dist/color/index.js +347 -0
- package/dist/color/index.js.map +1 -0
- package/dist/color/index.mjs +336 -0
- package/dist/color/index.mjs.map +1 -0
- package/dist/crypto/index.d.mts +1 -0
- package/dist/crypto/index.d.ts +1 -0
- package/dist/crypto/index.js +116 -0
- package/dist/crypto/index.js.map +1 -0
- package/dist/crypto/index.mjs +108 -0
- package/dist/crypto/index.mjs.map +1 -0
- package/dist/csv/index.d.mts +1 -0
- package/dist/csv/index.d.ts +1 -0
- package/dist/csv/index.js +371 -0
- package/dist/csv/index.js.map +1 -0
- package/dist/csv/index.mjs +348 -0
- package/dist/csv/index.mjs.map +1 -0
- package/dist/datetime/index.d.mts +1 -0
- package/dist/datetime/index.d.ts +1 -0
- package/dist/datetime/index.js +234 -0
- package/dist/datetime/index.js.map +1 -0
- package/dist/datetime/index.mjs +224 -0
- package/dist/datetime/index.mjs.map +1 -0
- package/dist/diff/index.d.mts +2 -0
- package/dist/diff/index.d.ts +2 -0
- package/dist/diff/index.js +84 -0
- package/dist/diff/index.js.map +1 -0
- package/dist/diff/index.mjs +78 -0
- package/dist/diff/index.mjs.map +1 -0
- package/dist/excel/index.d.mts +1 -0
- package/dist/excel/index.d.ts +1 -0
- package/dist/excel/index.js +163 -0
- package/dist/excel/index.js.map +1 -0
- package/dist/excel/index.mjs +153 -0
- package/dist/excel/index.mjs.map +1 -0
- package/dist/image/index.d.mts +1 -0
- package/dist/image/index.d.ts +1 -0
- package/dist/image/index.js +123 -0
- package/dist/image/index.js.map +1 -0
- package/dist/image/index.mjs +107 -0
- package/dist/image/index.mjs.map +1 -0
- package/dist/index--vbnYfdE.d.mts +142 -0
- package/dist/index--vbnYfdE.d.ts +142 -0
- package/dist/index-7FZQloN-.d.mts +62 -0
- package/dist/index-7FZQloN-.d.ts +62 -0
- package/dist/index-7XgaTVH5.d.mts +93 -0
- package/dist/index-7XgaTVH5.d.ts +93 -0
- package/dist/index-7bvFmh45.d.mts +87 -0
- package/dist/index-7bvFmh45.d.ts +87 -0
- package/dist/index-BDZcIVCU.d.mts +53 -0
- package/dist/index-BDZcIVCU.d.ts +53 -0
- package/dist/index-BN00EnUU.d.mts +55 -0
- package/dist/index-BN00EnUU.d.ts +55 -0
- package/dist/index-CQ1EukC4.d.mts +59 -0
- package/dist/index-CQ1EukC4.d.ts +59 -0
- package/dist/index-CgRVnFOt.d.mts +91 -0
- package/dist/index-CgRVnFOt.d.ts +91 -0
- package/dist/index-DjBDZzuj.d.mts +54 -0
- package/dist/index-DjBDZzuj.d.ts +54 -0
- package/dist/index-FFrvmr-n.d.mts +50 -0
- package/dist/index-FFrvmr-n.d.ts +50 -0
- package/dist/index-QWC8yIgW.d.mts +106 -0
- package/dist/index-QWC8yIgW.d.ts +106 -0
- package/dist/index-RVqNunxE.d.mts +193 -0
- package/dist/index-RVqNunxE.d.ts +193 -0
- package/dist/index-fJD8SORm.d.mts +61 -0
- package/dist/index-fJD8SORm.d.ts +61 -0
- package/dist/index-pPy_XDQU.d.mts +56 -0
- package/dist/index-pPy_XDQU.d.ts +56 -0
- package/dist/index-rwh9hdD9.d.mts +68 -0
- package/dist/index-rwh9hdD9.d.ts +68 -0
- package/dist/index-uXdkAfea.d.mts +93 -0
- package/dist/index-uXdkAfea.d.ts +93 -0
- package/dist/index.d.mts +17 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +3744 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +3694 -0
- package/dist/index.mjs.map +1 -0
- package/dist/json/index.d.mts +1 -0
- package/dist/json/index.d.ts +1 -0
- package/dist/json/index.js +599 -0
- package/dist/json/index.js.map +1 -0
- package/dist/json/index.mjs +552 -0
- package/dist/json/index.mjs.map +1 -0
- package/dist/markdown/index.d.mts +1 -0
- package/dist/markdown/index.d.ts +1 -0
- package/dist/markdown/index.js +151 -0
- package/dist/markdown/index.js.map +1 -0
- package/dist/markdown/index.mjs +139 -0
- package/dist/markdown/index.mjs.map +1 -0
- package/dist/math/index.d.mts +1 -0
- package/dist/math/index.d.ts +1 -0
- package/dist/math/index.js +247 -0
- package/dist/math/index.js.map +1 -0
- package/dist/math/index.mjs +240 -0
- package/dist/math/index.mjs.map +1 -0
- package/dist/pdf/index.d.mts +1 -0
- package/dist/pdf/index.d.ts +1 -0
- package/dist/pdf/index.js +546 -0
- package/dist/pdf/index.js.map +1 -0
- package/dist/pdf/index.mjs +518 -0
- package/dist/pdf/index.mjs.map +1 -0
- package/dist/regex/index.d.mts +1 -0
- package/dist/regex/index.d.ts +1 -0
- package/dist/regex/index.js +93 -0
- package/dist/regex/index.js.map +1 -0
- package/dist/regex/index.mjs +88 -0
- package/dist/regex/index.mjs.map +1 -0
- package/dist/settings/index.d.mts +41 -0
- package/dist/settings/index.d.ts +41 -0
- package/dist/settings/index.js +146 -0
- package/dist/settings/index.js.map +1 -0
- package/dist/settings/index.mjs +139 -0
- package/dist/settings/index.mjs.map +1 -0
- package/dist/sql/index.d.mts +1 -0
- package/dist/sql/index.d.ts +1 -0
- package/dist/sql/index.js +146 -0
- package/dist/sql/index.js.map +1 -0
- package/dist/sql/index.mjs +139 -0
- package/dist/sql/index.mjs.map +1 -0
- package/dist/text/index.d.mts +1 -0
- package/dist/text/index.d.ts +1 -0
- package/dist/text/index.js +250 -0
- package/dist/text/index.js.map +1 -0
- package/dist/text/index.mjs +242 -0
- package/dist/text/index.mjs.map +1 -0
- package/dist/xml/index.d.mts +1 -0
- package/dist/xml/index.d.ts +1 -0
- package/dist/xml/index.js +188 -0
- package/dist/xml/index.js.map +1 -0
- package/dist/xml/index.mjs +180 -0
- package/dist/xml/index.mjs.map +1 -0
- package/package.json +150 -0
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var marked = require('marked');
|
|
4
|
+
var TurndownService = require('turndown');
|
|
5
|
+
|
|
6
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
7
|
+
|
|
8
|
+
var TurndownService__default = /*#__PURE__*/_interopDefault(TurndownService);
|
|
9
|
+
|
|
10
|
+
// src/markdown/convert.ts
|
|
11
|
+
function convert(input, options) {
|
|
12
|
+
const { from, to } = options;
|
|
13
|
+
if (from === to) return input;
|
|
14
|
+
if (from === "markdown" && to === "html") {
|
|
15
|
+
return markdownToHtml(input, options.gfm);
|
|
16
|
+
}
|
|
17
|
+
if (from === "html" && to === "markdown") {
|
|
18
|
+
return htmlToMarkdown(input);
|
|
19
|
+
}
|
|
20
|
+
if (from === "markdown" && to === "text") {
|
|
21
|
+
return markdownToText(input);
|
|
22
|
+
}
|
|
23
|
+
if (from === "html" && to === "text") {
|
|
24
|
+
return htmlToText(input);
|
|
25
|
+
}
|
|
26
|
+
if (from === "text" && to === "markdown") {
|
|
27
|
+
return input;
|
|
28
|
+
}
|
|
29
|
+
if (from === "text" && to === "html") {
|
|
30
|
+
return `<p>${input.split("\n\n").join("</p><p>")}</p>`;
|
|
31
|
+
}
|
|
32
|
+
throw new Error(`Unsupported conversion: ${from} -> ${to}`);
|
|
33
|
+
}
|
|
34
|
+
function markdownToHtml(input, gfm = true) {
|
|
35
|
+
marked.marked.setOptions({ gfm });
|
|
36
|
+
return marked.marked.parse(input);
|
|
37
|
+
}
|
|
38
|
+
function htmlToMarkdown(input) {
|
|
39
|
+
const turndown = new TurndownService__default.default({
|
|
40
|
+
headingStyle: "atx",
|
|
41
|
+
codeBlockStyle: "fenced",
|
|
42
|
+
bulletListMarker: "-"
|
|
43
|
+
});
|
|
44
|
+
return turndown.turndown(input);
|
|
45
|
+
}
|
|
46
|
+
function markdownToText(input) {
|
|
47
|
+
const html = markdownToHtml(input);
|
|
48
|
+
return htmlToText(html);
|
|
49
|
+
}
|
|
50
|
+
function htmlToText(input) {
|
|
51
|
+
return input.replace(/<script[^>]*>[\s\S]*?<\/script>/gi, "").replace(/<style[^>]*>[\s\S]*?<\/style>/gi, "").replace(/<[^>]+>/g, "").replace(/ /g, " ").replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, '"').replace(/'/g, "'").replace(/\n{3,}/g, "\n\n").trim();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// src/markdown/toc.ts
|
|
55
|
+
function generateToc(input) {
|
|
56
|
+
const headingRegex = /^(#{1,6})\s+(.+)$/gm;
|
|
57
|
+
const entries = [];
|
|
58
|
+
let match;
|
|
59
|
+
while ((match = headingRegex.exec(input)) !== null) {
|
|
60
|
+
const level = match[1].length;
|
|
61
|
+
const text = match[2].trim();
|
|
62
|
+
const slug = text.toLowerCase().replace(/[^\w\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-");
|
|
63
|
+
entries.push({ level, text, slug });
|
|
64
|
+
}
|
|
65
|
+
return entries;
|
|
66
|
+
}
|
|
67
|
+
function renderToc(entries) {
|
|
68
|
+
if (entries.length === 0) return "";
|
|
69
|
+
const minLevel = Math.min(...entries.map((e) => e.level));
|
|
70
|
+
return entries.map((entry) => {
|
|
71
|
+
const indent = " ".repeat(entry.level - minLevel);
|
|
72
|
+
return `${indent}- [${entry.text}](#${entry.slug})`;
|
|
73
|
+
}).join("\n");
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// src/markdown/extract.ts
|
|
77
|
+
function extractLinks(input) {
|
|
78
|
+
const links = [];
|
|
79
|
+
const lines = input.split("\n");
|
|
80
|
+
const linkRegex = /\[([^\]]*)\]\(([^)]+)\)/g;
|
|
81
|
+
for (let i = 0; i < lines.length; i++) {
|
|
82
|
+
let match;
|
|
83
|
+
while ((match = linkRegex.exec(lines[i])) !== null) {
|
|
84
|
+
links.push({
|
|
85
|
+
text: match[1],
|
|
86
|
+
href: match[2],
|
|
87
|
+
line: i + 1
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return links;
|
|
92
|
+
}
|
|
93
|
+
function extractFrontmatter(input) {
|
|
94
|
+
const match = input.match(/^---\s*\n([\s\S]*?)\n---\s*\n/);
|
|
95
|
+
if (!match) return null;
|
|
96
|
+
const frontmatter = {};
|
|
97
|
+
const lines = match[1].split("\n");
|
|
98
|
+
for (const line of lines) {
|
|
99
|
+
const colonIndex = line.indexOf(":");
|
|
100
|
+
if (colonIndex === -1) continue;
|
|
101
|
+
const key = line.substring(0, colonIndex).trim();
|
|
102
|
+
let value = line.substring(colonIndex + 1).trim();
|
|
103
|
+
if (value === "true") value = true;
|
|
104
|
+
else if (value === "false") value = false;
|
|
105
|
+
else if (!isNaN(Number(value)) && value !== "") value = Number(value);
|
|
106
|
+
else if (typeof value === "string" && value.startsWith("[") && value.endsWith("]")) {
|
|
107
|
+
value = value.slice(1, -1).split(",").map((s) => s.trim().replace(/^['"]|['"]$/g, ""));
|
|
108
|
+
}
|
|
109
|
+
frontmatter[key] = value;
|
|
110
|
+
}
|
|
111
|
+
return frontmatter;
|
|
112
|
+
}
|
|
113
|
+
function stripFrontmatter(input) {
|
|
114
|
+
return input.replace(/^---\s*\n[\s\S]*?\n---\s*\n/, "");
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// src/markdown/stats.ts
|
|
118
|
+
function getStats(input) {
|
|
119
|
+
const lines = input.split("\n");
|
|
120
|
+
const text = input.replace(/```[\s\S]*?```/g, "").replace(/`[^`]+`/g, "");
|
|
121
|
+
const headings = (text.match(/^#{1,6}\s+.+$/gm) || []).length;
|
|
122
|
+
const links = (input.match(/\[([^\]]*)\]\(([^)]+)\)/g) || []).length;
|
|
123
|
+
const images = (input.match(/!\[([^\]]*)\]\(([^)]+)\)/g) || []).length;
|
|
124
|
+
const codeBlocks = (input.match(/```/g) || []).length / 2;
|
|
125
|
+
const lists = (text.match(/^[\s]*[-*+]\s+|^[\s]*\d+\.\s+/gm) || []).length;
|
|
126
|
+
const plainText = text.replace(/#{1,6}\s+/g, "").replace(/\[([^\]]*)\]\([^)]+\)/g, "$1").replace(/[*_~`]/g, "").trim();
|
|
127
|
+
const words = plainText.split(/\s+/).filter((w) => w.length > 0).length;
|
|
128
|
+
const paragraphs = input.split(/\n\s*\n/).filter((p) => p.trim().length > 0).length;
|
|
129
|
+
return {
|
|
130
|
+
words,
|
|
131
|
+
characters: input.length,
|
|
132
|
+
lines: lines.length,
|
|
133
|
+
paragraphs,
|
|
134
|
+
headings,
|
|
135
|
+
links,
|
|
136
|
+
images,
|
|
137
|
+
codeBlocks: Math.floor(codeBlocks),
|
|
138
|
+
lists,
|
|
139
|
+
sizeBytes: Buffer.byteLength(input, "utf8")
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
exports.convert = convert;
|
|
144
|
+
exports.extractFrontmatter = extractFrontmatter;
|
|
145
|
+
exports.extractLinks = extractLinks;
|
|
146
|
+
exports.generateToc = generateToc;
|
|
147
|
+
exports.getStats = getStats;
|
|
148
|
+
exports.renderToc = renderToc;
|
|
149
|
+
exports.stripFrontmatter = stripFrontmatter;
|
|
150
|
+
//# sourceMappingURL=index.js.map
|
|
151
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/markdown/convert.ts","../../src/markdown/toc.ts","../../src/markdown/extract.ts","../../src/markdown/stats.ts"],"names":["marked","TurndownService"],"mappings":"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","file":"index.js","sourcesContent":["import { marked } from 'marked';\nimport TurndownService from 'turndown';\nimport type { MarkdownConvertOptions } from './types';\n\nexport function convert(\n input: string,\n options: MarkdownConvertOptions\n): string {\n const { from, to } = options;\n\n if (from === to) return input;\n\n if (from === 'markdown' && to === 'html') {\n return markdownToHtml(input, options.gfm);\n }\n\n if (from === 'html' && to === 'markdown') {\n return htmlToMarkdown(input);\n }\n\n if (from === 'markdown' && to === 'text') {\n return markdownToText(input);\n }\n\n if (from === 'html' && to === 'text') {\n return htmlToText(input);\n }\n\n if (from === 'text' && to === 'markdown') {\n return input;\n }\n\n if (from === 'text' && to === 'html') {\n return `<p>${input.split('\\n\\n').join('</p><p>')}</p>`;\n }\n\n throw new Error(`Unsupported conversion: ${from} -> ${to}`);\n}\n\nfunction markdownToHtml(input: string, gfm = true): string {\n marked.setOptions({ gfm });\n return marked.parse(input) as string;\n}\n\nfunction htmlToMarkdown(input: string): string {\n const turndown = new TurndownService({\n headingStyle: 'atx',\n codeBlockStyle: 'fenced',\n bulletListMarker: '-',\n });\n return turndown.turndown(input);\n}\n\nfunction markdownToText(input: string): string {\n const html = markdownToHtml(input);\n return htmlToText(html);\n}\n\nfunction htmlToText(input: string): string {\n return input\n .replace(/<script[^>]*>[\\s\\S]*?<\\/script>/gi, '')\n .replace(/<style[^>]*>[\\s\\S]*?<\\/style>/gi, '')\n .replace(/<[^>]+>/g, '')\n .replace(/ /g, ' ')\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/"/g, '\"')\n .replace(/'/g, \"'\")\n .replace(/\\n{3,}/g, '\\n\\n')\n .trim();\n}\n","import type { MarkdownTocEntry } from './types';\n\nexport function generateToc(input: string): MarkdownTocEntry[] {\n const headingRegex = /^(#{1,6})\\s+(.+)$/gm;\n const entries: MarkdownTocEntry[] = [];\n let match;\n\n while ((match = headingRegex.exec(input)) !== null) {\n const level = match[1].length;\n const text = match[2].trim();\n const slug = text\n .toLowerCase()\n .replace(/[^\\w\\s-]/g, '')\n .replace(/\\s+/g, '-')\n .replace(/-+/g, '-');\n\n entries.push({ level, text, slug });\n }\n\n return entries;\n}\n\nexport function renderToc(entries: MarkdownTocEntry[]): string {\n if (entries.length === 0) return '';\n\n const minLevel = Math.min(...entries.map((e) => e.level));\n\n return entries\n .map((entry) => {\n const indent = ' '.repeat(entry.level - minLevel);\n return `${indent}- [${entry.text}](#${entry.slug})`;\n })\n .join('\\n');\n}\n","import type { MarkdownLinkInfo, MarkdownFrontmatter } from './types';\n\nexport function extractLinks(input: string): MarkdownLinkInfo[] {\n const links: MarkdownLinkInfo[] = [];\n const lines = input.split('\\n');\n const linkRegex = /\\[([^\\]]*)\\]\\(([^)]+)\\)/g;\n\n for (let i = 0; i < lines.length; i++) {\n let match;\n while ((match = linkRegex.exec(lines[i])) !== null) {\n links.push({\n text: match[1],\n href: match[2],\n line: i + 1,\n });\n }\n }\n\n return links;\n}\n\nexport function extractFrontmatter(input: string): MarkdownFrontmatter | null {\n const match = input.match(/^---\\s*\\n([\\s\\S]*?)\\n---\\s*\\n/);\n if (!match) return null;\n\n const frontmatter: MarkdownFrontmatter = {};\n const lines = match[1].split('\\n');\n\n for (const line of lines) {\n const colonIndex = line.indexOf(':');\n if (colonIndex === -1) continue;\n\n const key = line.substring(0, colonIndex).trim();\n let value: unknown = line.substring(colonIndex + 1).trim();\n\n if (value === 'true') value = true;\n else if (value === 'false') value = false;\n else if (!isNaN(Number(value)) && value !== '') value = Number(value);\n else if (typeof value === 'string' && value.startsWith('[') && value.endsWith(']')) {\n value = value\n .slice(1, -1)\n .split(',')\n .map((s: string) => s.trim().replace(/^['\"]|['\"]$/g, ''));\n }\n\n frontmatter[key] = value;\n }\n\n return frontmatter;\n}\n\nexport function stripFrontmatter(input: string): string {\n return input.replace(/^---\\s*\\n[\\s\\S]*?\\n---\\s*\\n/, '');\n}\n","import type { MarkdownStats } from './types';\n\nexport function getStats(input: string): MarkdownStats {\n const lines = input.split('\\n');\n const text = input.replace(/```[\\s\\S]*?```/g, '').replace(/`[^`]+`/g, '');\n\n const headings = (text.match(/^#{1,6}\\s+.+$/gm) || []).length;\n const links = (input.match(/\\[([^\\]]*)\\]\\(([^)]+)\\)/g) || []).length;\n const images = (input.match(/!\\[([^\\]]*)\\]\\(([^)]+)\\)/g) || []).length;\n const codeBlocks = (input.match(/```/g) || []).length / 2;\n const lists = (text.match(/^[\\s]*[-*+]\\s+|^[\\s]*\\d+\\.\\s+/gm) || []).length;\n\n const plainText = text\n .replace(/#{1,6}\\s+/g, '')\n .replace(/\\[([^\\]]*)\\]\\([^)]+\\)/g, '$1')\n .replace(/[*_~`]/g, '')\n .trim();\n\n const words = plainText.split(/\\s+/).filter((w) => w.length > 0).length;\n const paragraphs = input.split(/\\n\\s*\\n/).filter((p) => p.trim().length > 0).length;\n\n return {\n words,\n characters: input.length,\n lines: lines.length,\n paragraphs,\n headings,\n links,\n images,\n codeBlocks: Math.floor(codeBlocks),\n lists,\n sizeBytes: Buffer.byteLength(input, 'utf8'),\n };\n}\n"]}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { marked } from 'marked';
|
|
2
|
+
import TurndownService from 'turndown';
|
|
3
|
+
|
|
4
|
+
// src/markdown/convert.ts
|
|
5
|
+
function convert(input, options) {
|
|
6
|
+
const { from, to } = options;
|
|
7
|
+
if (from === to) return input;
|
|
8
|
+
if (from === "markdown" && to === "html") {
|
|
9
|
+
return markdownToHtml(input, options.gfm);
|
|
10
|
+
}
|
|
11
|
+
if (from === "html" && to === "markdown") {
|
|
12
|
+
return htmlToMarkdown(input);
|
|
13
|
+
}
|
|
14
|
+
if (from === "markdown" && to === "text") {
|
|
15
|
+
return markdownToText(input);
|
|
16
|
+
}
|
|
17
|
+
if (from === "html" && to === "text") {
|
|
18
|
+
return htmlToText(input);
|
|
19
|
+
}
|
|
20
|
+
if (from === "text" && to === "markdown") {
|
|
21
|
+
return input;
|
|
22
|
+
}
|
|
23
|
+
if (from === "text" && to === "html") {
|
|
24
|
+
return `<p>${input.split("\n\n").join("</p><p>")}</p>`;
|
|
25
|
+
}
|
|
26
|
+
throw new Error(`Unsupported conversion: ${from} -> ${to}`);
|
|
27
|
+
}
|
|
28
|
+
function markdownToHtml(input, gfm = true) {
|
|
29
|
+
marked.setOptions({ gfm });
|
|
30
|
+
return marked.parse(input);
|
|
31
|
+
}
|
|
32
|
+
function htmlToMarkdown(input) {
|
|
33
|
+
const turndown = new TurndownService({
|
|
34
|
+
headingStyle: "atx",
|
|
35
|
+
codeBlockStyle: "fenced",
|
|
36
|
+
bulletListMarker: "-"
|
|
37
|
+
});
|
|
38
|
+
return turndown.turndown(input);
|
|
39
|
+
}
|
|
40
|
+
function markdownToText(input) {
|
|
41
|
+
const html = markdownToHtml(input);
|
|
42
|
+
return htmlToText(html);
|
|
43
|
+
}
|
|
44
|
+
function htmlToText(input) {
|
|
45
|
+
return input.replace(/<script[^>]*>[\s\S]*?<\/script>/gi, "").replace(/<style[^>]*>[\s\S]*?<\/style>/gi, "").replace(/<[^>]+>/g, "").replace(/ /g, " ").replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, '"').replace(/'/g, "'").replace(/\n{3,}/g, "\n\n").trim();
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// src/markdown/toc.ts
|
|
49
|
+
function generateToc(input) {
|
|
50
|
+
const headingRegex = /^(#{1,6})\s+(.+)$/gm;
|
|
51
|
+
const entries = [];
|
|
52
|
+
let match;
|
|
53
|
+
while ((match = headingRegex.exec(input)) !== null) {
|
|
54
|
+
const level = match[1].length;
|
|
55
|
+
const text = match[2].trim();
|
|
56
|
+
const slug = text.toLowerCase().replace(/[^\w\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-");
|
|
57
|
+
entries.push({ level, text, slug });
|
|
58
|
+
}
|
|
59
|
+
return entries;
|
|
60
|
+
}
|
|
61
|
+
function renderToc(entries) {
|
|
62
|
+
if (entries.length === 0) return "";
|
|
63
|
+
const minLevel = Math.min(...entries.map((e) => e.level));
|
|
64
|
+
return entries.map((entry) => {
|
|
65
|
+
const indent = " ".repeat(entry.level - minLevel);
|
|
66
|
+
return `${indent}- [${entry.text}](#${entry.slug})`;
|
|
67
|
+
}).join("\n");
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// src/markdown/extract.ts
|
|
71
|
+
function extractLinks(input) {
|
|
72
|
+
const links = [];
|
|
73
|
+
const lines = input.split("\n");
|
|
74
|
+
const linkRegex = /\[([^\]]*)\]\(([^)]+)\)/g;
|
|
75
|
+
for (let i = 0; i < lines.length; i++) {
|
|
76
|
+
let match;
|
|
77
|
+
while ((match = linkRegex.exec(lines[i])) !== null) {
|
|
78
|
+
links.push({
|
|
79
|
+
text: match[1],
|
|
80
|
+
href: match[2],
|
|
81
|
+
line: i + 1
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return links;
|
|
86
|
+
}
|
|
87
|
+
function extractFrontmatter(input) {
|
|
88
|
+
const match = input.match(/^---\s*\n([\s\S]*?)\n---\s*\n/);
|
|
89
|
+
if (!match) return null;
|
|
90
|
+
const frontmatter = {};
|
|
91
|
+
const lines = match[1].split("\n");
|
|
92
|
+
for (const line of lines) {
|
|
93
|
+
const colonIndex = line.indexOf(":");
|
|
94
|
+
if (colonIndex === -1) continue;
|
|
95
|
+
const key = line.substring(0, colonIndex).trim();
|
|
96
|
+
let value = line.substring(colonIndex + 1).trim();
|
|
97
|
+
if (value === "true") value = true;
|
|
98
|
+
else if (value === "false") value = false;
|
|
99
|
+
else if (!isNaN(Number(value)) && value !== "") value = Number(value);
|
|
100
|
+
else if (typeof value === "string" && value.startsWith("[") && value.endsWith("]")) {
|
|
101
|
+
value = value.slice(1, -1).split(",").map((s) => s.trim().replace(/^['"]|['"]$/g, ""));
|
|
102
|
+
}
|
|
103
|
+
frontmatter[key] = value;
|
|
104
|
+
}
|
|
105
|
+
return frontmatter;
|
|
106
|
+
}
|
|
107
|
+
function stripFrontmatter(input) {
|
|
108
|
+
return input.replace(/^---\s*\n[\s\S]*?\n---\s*\n/, "");
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// src/markdown/stats.ts
|
|
112
|
+
function getStats(input) {
|
|
113
|
+
const lines = input.split("\n");
|
|
114
|
+
const text = input.replace(/```[\s\S]*?```/g, "").replace(/`[^`]+`/g, "");
|
|
115
|
+
const headings = (text.match(/^#{1,6}\s+.+$/gm) || []).length;
|
|
116
|
+
const links = (input.match(/\[([^\]]*)\]\(([^)]+)\)/g) || []).length;
|
|
117
|
+
const images = (input.match(/!\[([^\]]*)\]\(([^)]+)\)/g) || []).length;
|
|
118
|
+
const codeBlocks = (input.match(/```/g) || []).length / 2;
|
|
119
|
+
const lists = (text.match(/^[\s]*[-*+]\s+|^[\s]*\d+\.\s+/gm) || []).length;
|
|
120
|
+
const plainText = text.replace(/#{1,6}\s+/g, "").replace(/\[([^\]]*)\]\([^)]+\)/g, "$1").replace(/[*_~`]/g, "").trim();
|
|
121
|
+
const words = plainText.split(/\s+/).filter((w) => w.length > 0).length;
|
|
122
|
+
const paragraphs = input.split(/\n\s*\n/).filter((p) => p.trim().length > 0).length;
|
|
123
|
+
return {
|
|
124
|
+
words,
|
|
125
|
+
characters: input.length,
|
|
126
|
+
lines: lines.length,
|
|
127
|
+
paragraphs,
|
|
128
|
+
headings,
|
|
129
|
+
links,
|
|
130
|
+
images,
|
|
131
|
+
codeBlocks: Math.floor(codeBlocks),
|
|
132
|
+
lists,
|
|
133
|
+
sizeBytes: Buffer.byteLength(input, "utf8")
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export { convert, extractFrontmatter, extractLinks, generateToc, getStats, renderToc, stripFrontmatter };
|
|
138
|
+
//# sourceMappingURL=index.mjs.map
|
|
139
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/markdown/convert.ts","../../src/markdown/toc.ts","../../src/markdown/extract.ts","../../src/markdown/stats.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["import { marked } from 'marked';\nimport TurndownService from 'turndown';\nimport type { MarkdownConvertOptions } from './types';\n\nexport function convert(\n input: string,\n options: MarkdownConvertOptions\n): string {\n const { from, to } = options;\n\n if (from === to) return input;\n\n if (from === 'markdown' && to === 'html') {\n return markdownToHtml(input, options.gfm);\n }\n\n if (from === 'html' && to === 'markdown') {\n return htmlToMarkdown(input);\n }\n\n if (from === 'markdown' && to === 'text') {\n return markdownToText(input);\n }\n\n if (from === 'html' && to === 'text') {\n return htmlToText(input);\n }\n\n if (from === 'text' && to === 'markdown') {\n return input;\n }\n\n if (from === 'text' && to === 'html') {\n return `<p>${input.split('\\n\\n').join('</p><p>')}</p>`;\n }\n\n throw new Error(`Unsupported conversion: ${from} -> ${to}`);\n}\n\nfunction markdownToHtml(input: string, gfm = true): string {\n marked.setOptions({ gfm });\n return marked.parse(input) as string;\n}\n\nfunction htmlToMarkdown(input: string): string {\n const turndown = new TurndownService({\n headingStyle: 'atx',\n codeBlockStyle: 'fenced',\n bulletListMarker: '-',\n });\n return turndown.turndown(input);\n}\n\nfunction markdownToText(input: string): string {\n const html = markdownToHtml(input);\n return htmlToText(html);\n}\n\nfunction htmlToText(input: string): string {\n return input\n .replace(/<script[^>]*>[\\s\\S]*?<\\/script>/gi, '')\n .replace(/<style[^>]*>[\\s\\S]*?<\\/style>/gi, '')\n .replace(/<[^>]+>/g, '')\n .replace(/ /g, ' ')\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/"/g, '\"')\n .replace(/'/g, \"'\")\n .replace(/\\n{3,}/g, '\\n\\n')\n .trim();\n}\n","import type { MarkdownTocEntry } from './types';\n\nexport function generateToc(input: string): MarkdownTocEntry[] {\n const headingRegex = /^(#{1,6})\\s+(.+)$/gm;\n const entries: MarkdownTocEntry[] = [];\n let match;\n\n while ((match = headingRegex.exec(input)) !== null) {\n const level = match[1].length;\n const text = match[2].trim();\n const slug = text\n .toLowerCase()\n .replace(/[^\\w\\s-]/g, '')\n .replace(/\\s+/g, '-')\n .replace(/-+/g, '-');\n\n entries.push({ level, text, slug });\n }\n\n return entries;\n}\n\nexport function renderToc(entries: MarkdownTocEntry[]): string {\n if (entries.length === 0) return '';\n\n const minLevel = Math.min(...entries.map((e) => e.level));\n\n return entries\n .map((entry) => {\n const indent = ' '.repeat(entry.level - minLevel);\n return `${indent}- [${entry.text}](#${entry.slug})`;\n })\n .join('\\n');\n}\n","import type { MarkdownLinkInfo, MarkdownFrontmatter } from './types';\n\nexport function extractLinks(input: string): MarkdownLinkInfo[] {\n const links: MarkdownLinkInfo[] = [];\n const lines = input.split('\\n');\n const linkRegex = /\\[([^\\]]*)\\]\\(([^)]+)\\)/g;\n\n for (let i = 0; i < lines.length; i++) {\n let match;\n while ((match = linkRegex.exec(lines[i])) !== null) {\n links.push({\n text: match[1],\n href: match[2],\n line: i + 1,\n });\n }\n }\n\n return links;\n}\n\nexport function extractFrontmatter(input: string): MarkdownFrontmatter | null {\n const match = input.match(/^---\\s*\\n([\\s\\S]*?)\\n---\\s*\\n/);\n if (!match) return null;\n\n const frontmatter: MarkdownFrontmatter = {};\n const lines = match[1].split('\\n');\n\n for (const line of lines) {\n const colonIndex = line.indexOf(':');\n if (colonIndex === -1) continue;\n\n const key = line.substring(0, colonIndex).trim();\n let value: unknown = line.substring(colonIndex + 1).trim();\n\n if (value === 'true') value = true;\n else if (value === 'false') value = false;\n else if (!isNaN(Number(value)) && value !== '') value = Number(value);\n else if (typeof value === 'string' && value.startsWith('[') && value.endsWith(']')) {\n value = value\n .slice(1, -1)\n .split(',')\n .map((s: string) => s.trim().replace(/^['\"]|['\"]$/g, ''));\n }\n\n frontmatter[key] = value;\n }\n\n return frontmatter;\n}\n\nexport function stripFrontmatter(input: string): string {\n return input.replace(/^---\\s*\\n[\\s\\S]*?\\n---\\s*\\n/, '');\n}\n","import type { MarkdownStats } from './types';\n\nexport function getStats(input: string): MarkdownStats {\n const lines = input.split('\\n');\n const text = input.replace(/```[\\s\\S]*?```/g, '').replace(/`[^`]+`/g, '');\n\n const headings = (text.match(/^#{1,6}\\s+.+$/gm) || []).length;\n const links = (input.match(/\\[([^\\]]*)\\]\\(([^)]+)\\)/g) || []).length;\n const images = (input.match(/!\\[([^\\]]*)\\]\\(([^)]+)\\)/g) || []).length;\n const codeBlocks = (input.match(/```/g) || []).length / 2;\n const lists = (text.match(/^[\\s]*[-*+]\\s+|^[\\s]*\\d+\\.\\s+/gm) || []).length;\n\n const plainText = text\n .replace(/#{1,6}\\s+/g, '')\n .replace(/\\[([^\\]]*)\\]\\([^)]+\\)/g, '$1')\n .replace(/[*_~`]/g, '')\n .trim();\n\n const words = plainText.split(/\\s+/).filter((w) => w.length > 0).length;\n const paragraphs = input.split(/\\n\\s*\\n/).filter((p) => p.trim().length > 0).length;\n\n return {\n words,\n characters: input.length,\n lines: lines.length,\n paragraphs,\n headings,\n links,\n images,\n codeBlocks: Math.floor(codeBlocks),\n lists,\n sizeBytes: Buffer.byteLength(input, 'utf8'),\n };\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { B as BaseConversionResult, D as DataUnit, L as LengthUnit, N as NumberBase, a as NumberFormatOptions, P as PercentageChangeResult, b as PercentageResult, S as StatisticsResult, T as TemperatureUnit, U as UnitCategory, c as UnitConversionResult, W as WeightUnit, d as calculateStats, e as convertBase, f as convertUnit, g as formatNumber, p as percentage, h as percentageChange } from '../index-uXdkAfea.mjs';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { B as BaseConversionResult, D as DataUnit, L as LengthUnit, N as NumberBase, a as NumberFormatOptions, P as PercentageChangeResult, b as PercentageResult, S as StatisticsResult, T as TemperatureUnit, U as UnitCategory, c as UnitConversionResult, W as WeightUnit, d as calculateStats, e as convertBase, f as convertUnit, g as formatNumber, p as percentage, h as percentageChange } from '../index-uXdkAfea.js';
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/math/convert.ts
|
|
4
|
+
var lengthFactors = {
|
|
5
|
+
mm: 1e-3,
|
|
6
|
+
cm: 0.01,
|
|
7
|
+
m: 1,
|
|
8
|
+
km: 1e3,
|
|
9
|
+
in: 0.0254,
|
|
10
|
+
ft: 0.3048,
|
|
11
|
+
yd: 0.9144,
|
|
12
|
+
mi: 1609.344
|
|
13
|
+
};
|
|
14
|
+
var weightFactors = {
|
|
15
|
+
mg: 1e-3,
|
|
16
|
+
g: 1,
|
|
17
|
+
kg: 1e3,
|
|
18
|
+
oz: 28.3495,
|
|
19
|
+
lb: 453.592,
|
|
20
|
+
ton: 907185
|
|
21
|
+
};
|
|
22
|
+
var dataFactors = {
|
|
23
|
+
b: 1,
|
|
24
|
+
kb: 1024,
|
|
25
|
+
mb: Math.pow(1024, 2),
|
|
26
|
+
gb: Math.pow(1024, 3),
|
|
27
|
+
tb: Math.pow(1024, 4)
|
|
28
|
+
};
|
|
29
|
+
var temperatureUnits = /* @__PURE__ */ new Set(["celsius", "fahrenheit", "kelvin"]);
|
|
30
|
+
function convertTemperature(value, from, to) {
|
|
31
|
+
if (from === to) return value;
|
|
32
|
+
let celsius;
|
|
33
|
+
switch (from) {
|
|
34
|
+
case "celsius":
|
|
35
|
+
celsius = value;
|
|
36
|
+
break;
|
|
37
|
+
case "fahrenheit":
|
|
38
|
+
celsius = (value - 32) * 5 / 9;
|
|
39
|
+
break;
|
|
40
|
+
case "kelvin":
|
|
41
|
+
celsius = value - 273.15;
|
|
42
|
+
break;
|
|
43
|
+
default:
|
|
44
|
+
throw new Error(`Unknown temperature unit: ${from}`);
|
|
45
|
+
}
|
|
46
|
+
switch (to) {
|
|
47
|
+
case "celsius":
|
|
48
|
+
return celsius;
|
|
49
|
+
case "fahrenheit":
|
|
50
|
+
return celsius * 9 / 5 + 32;
|
|
51
|
+
case "kelvin":
|
|
52
|
+
return celsius + 273.15;
|
|
53
|
+
default:
|
|
54
|
+
throw new Error(`Unknown temperature unit: ${to}`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function getFactors(category) {
|
|
58
|
+
switch (category) {
|
|
59
|
+
case "length":
|
|
60
|
+
return lengthFactors;
|
|
61
|
+
case "weight":
|
|
62
|
+
return weightFactors;
|
|
63
|
+
case "data":
|
|
64
|
+
return dataFactors;
|
|
65
|
+
default:
|
|
66
|
+
throw new Error(`No conversion factors for category: ${category}`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function convertUnit(value, from, to, category) {
|
|
70
|
+
const fromLower = from.toLowerCase();
|
|
71
|
+
const toLower = to.toLowerCase();
|
|
72
|
+
if (category === "temperature") {
|
|
73
|
+
if (!temperatureUnits.has(fromLower)) {
|
|
74
|
+
throw new Error(`Unit '${from}' does not belong to category 'temperature'`);
|
|
75
|
+
}
|
|
76
|
+
if (!temperatureUnits.has(toLower)) {
|
|
77
|
+
throw new Error(`Unit '${to}' does not belong to category 'temperature'`);
|
|
78
|
+
}
|
|
79
|
+
const result2 = convertTemperature(value, fromLower, toLower);
|
|
80
|
+
return { value, from: fromLower, to: toLower, result: result2 };
|
|
81
|
+
}
|
|
82
|
+
const factors = getFactors(category);
|
|
83
|
+
if (!(fromLower in factors)) {
|
|
84
|
+
throw new Error(`Unit '${from}' does not belong to category '${category}'`);
|
|
85
|
+
}
|
|
86
|
+
if (!(toLower in factors)) {
|
|
87
|
+
throw new Error(`Unit '${to}' does not belong to category '${category}'`);
|
|
88
|
+
}
|
|
89
|
+
const baseValue = value * factors[fromLower];
|
|
90
|
+
const result = baseValue / factors[toLower];
|
|
91
|
+
return { value, from: fromLower, to: toLower, result };
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// src/math/base.ts
|
|
95
|
+
var radixMap = {
|
|
96
|
+
binary: 2,
|
|
97
|
+
octal: 8,
|
|
98
|
+
decimal: 10,
|
|
99
|
+
hex: 16
|
|
100
|
+
};
|
|
101
|
+
function convertBase(input, fromBase) {
|
|
102
|
+
const radix = radixMap[fromBase];
|
|
103
|
+
if (radix === void 0) {
|
|
104
|
+
throw new Error(`Unknown base: ${fromBase}`);
|
|
105
|
+
}
|
|
106
|
+
let cleanInput = input.trim();
|
|
107
|
+
if (fromBase === "binary" && cleanInput.startsWith("0b")) {
|
|
108
|
+
cleanInput = cleanInput.slice(2);
|
|
109
|
+
} else if (fromBase === "octal" && cleanInput.startsWith("0o")) {
|
|
110
|
+
cleanInput = cleanInput.slice(2);
|
|
111
|
+
} else if (fromBase === "hex" && cleanInput.startsWith("0x")) {
|
|
112
|
+
cleanInput = cleanInput.slice(2);
|
|
113
|
+
}
|
|
114
|
+
const decimalValue = parseInt(cleanInput, radix);
|
|
115
|
+
if (isNaN(decimalValue)) {
|
|
116
|
+
throw new Error(`Invalid input '${input}' for base '${fromBase}'`);
|
|
117
|
+
}
|
|
118
|
+
return {
|
|
119
|
+
input,
|
|
120
|
+
fromBase,
|
|
121
|
+
binary: "0b" + decimalValue.toString(2),
|
|
122
|
+
octal: "0o" + decimalValue.toString(8),
|
|
123
|
+
decimal: decimalValue.toString(10),
|
|
124
|
+
hex: "0x" + decimalValue.toString(16)
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// src/math/statistics.ts
|
|
129
|
+
function getPercentile(sorted, p) {
|
|
130
|
+
if (sorted.length === 1) return sorted[0];
|
|
131
|
+
const index = p / 100 * (sorted.length - 1);
|
|
132
|
+
const lower = Math.floor(index);
|
|
133
|
+
const upper = Math.ceil(index);
|
|
134
|
+
if (lower === upper) return sorted[lower];
|
|
135
|
+
const fraction = index - lower;
|
|
136
|
+
return sorted[lower] + fraction * (sorted[upper] - sorted[lower]);
|
|
137
|
+
}
|
|
138
|
+
function calculateStats(numbers) {
|
|
139
|
+
if (numbers.length === 0) {
|
|
140
|
+
throw new Error("Cannot calculate statistics for an empty array");
|
|
141
|
+
}
|
|
142
|
+
const count = numbers.length;
|
|
143
|
+
const sum = numbers.reduce((acc, n) => acc + n, 0);
|
|
144
|
+
const mean = sum / count;
|
|
145
|
+
const sorted = [...numbers].sort((a, b) => a - b);
|
|
146
|
+
let median;
|
|
147
|
+
const mid = Math.floor(sorted.length / 2);
|
|
148
|
+
if (sorted.length % 2 === 0) {
|
|
149
|
+
median = (sorted[mid - 1] + sorted[mid]) / 2;
|
|
150
|
+
} else {
|
|
151
|
+
median = sorted[mid];
|
|
152
|
+
}
|
|
153
|
+
const frequencyMap = /* @__PURE__ */ new Map();
|
|
154
|
+
for (const n of numbers) {
|
|
155
|
+
frequencyMap.set(n, (frequencyMap.get(n) || 0) + 1);
|
|
156
|
+
}
|
|
157
|
+
let maxFrequency = 0;
|
|
158
|
+
for (const freq of frequencyMap.values()) {
|
|
159
|
+
if (freq > maxFrequency) maxFrequency = freq;
|
|
160
|
+
}
|
|
161
|
+
const mode = [];
|
|
162
|
+
for (const [value, freq] of frequencyMap.entries()) {
|
|
163
|
+
if (freq === maxFrequency) mode.push(value);
|
|
164
|
+
}
|
|
165
|
+
mode.sort((a, b) => a - b);
|
|
166
|
+
const min = sorted[0];
|
|
167
|
+
const max = sorted[sorted.length - 1];
|
|
168
|
+
const range = max - min;
|
|
169
|
+
const variance = numbers.reduce((acc, n) => acc + Math.pow(n - mean, 2), 0) / count;
|
|
170
|
+
const standardDeviation = Math.sqrt(variance);
|
|
171
|
+
const percentiles = {
|
|
172
|
+
p25: getPercentile(sorted, 25),
|
|
173
|
+
p50: getPercentile(sorted, 50),
|
|
174
|
+
p75: getPercentile(sorted, 75),
|
|
175
|
+
p90: getPercentile(sorted, 90),
|
|
176
|
+
p99: getPercentile(sorted, 99)
|
|
177
|
+
};
|
|
178
|
+
return {
|
|
179
|
+
count,
|
|
180
|
+
sum,
|
|
181
|
+
mean,
|
|
182
|
+
median,
|
|
183
|
+
mode,
|
|
184
|
+
min,
|
|
185
|
+
max,
|
|
186
|
+
range,
|
|
187
|
+
standardDeviation,
|
|
188
|
+
variance,
|
|
189
|
+
percentiles
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// src/math/format.ts
|
|
194
|
+
function formatNumber(value, options) {
|
|
195
|
+
const locale = options?.locale ?? "en-US";
|
|
196
|
+
const formatOptions = {};
|
|
197
|
+
if (options?.style) {
|
|
198
|
+
formatOptions.style = options.style;
|
|
199
|
+
}
|
|
200
|
+
if (options?.currency) {
|
|
201
|
+
formatOptions.currency = options.currency;
|
|
202
|
+
}
|
|
203
|
+
if (options?.minimumFractionDigits !== void 0) {
|
|
204
|
+
formatOptions.minimumFractionDigits = options.minimumFractionDigits;
|
|
205
|
+
}
|
|
206
|
+
if (options?.maximumFractionDigits !== void 0) {
|
|
207
|
+
formatOptions.maximumFractionDigits = options.maximumFractionDigits;
|
|
208
|
+
}
|
|
209
|
+
return new Intl.NumberFormat(locale, formatOptions).format(value);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// src/math/percentage.ts
|
|
213
|
+
function percentage(value, total) {
|
|
214
|
+
if (total === 0) {
|
|
215
|
+
throw new Error("Total cannot be zero");
|
|
216
|
+
}
|
|
217
|
+
const pct = value / total * 100;
|
|
218
|
+
return {
|
|
219
|
+
value,
|
|
220
|
+
total,
|
|
221
|
+
percentage: pct,
|
|
222
|
+
formatted: `${pct}%`
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
function percentageChange(from, to) {
|
|
226
|
+
if (from === 0) {
|
|
227
|
+
throw new Error("Cannot calculate percentage change from zero");
|
|
228
|
+
}
|
|
229
|
+
const change = (to - from) / Math.abs(from) * 100;
|
|
230
|
+
const sign = change >= 0 ? "+" : "";
|
|
231
|
+
const formatted = `${sign}${change}%`;
|
|
232
|
+
return {
|
|
233
|
+
from,
|
|
234
|
+
to,
|
|
235
|
+
change,
|
|
236
|
+
formatted
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
exports.calculateStats = calculateStats;
|
|
241
|
+
exports.convertBase = convertBase;
|
|
242
|
+
exports.convertUnit = convertUnit;
|
|
243
|
+
exports.formatNumber = formatNumber;
|
|
244
|
+
exports.percentage = percentage;
|
|
245
|
+
exports.percentageChange = percentageChange;
|
|
246
|
+
//# sourceMappingURL=index.js.map
|
|
247
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/math/convert.ts","../../src/math/base.ts","../../src/math/statistics.ts","../../src/math/format.ts","../../src/math/percentage.ts"],"names":["result"],"mappings":"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","file":"index.js","sourcesContent":["import type { UnitCategory, UnitConversionResult } from './types';\n\nconst lengthFactors: Record<string, number> = {\n mm: 0.001,\n cm: 0.01,\n m: 1,\n km: 1000,\n in: 0.0254,\n ft: 0.3048,\n yd: 0.9144,\n mi: 1609.344,\n};\n\nconst weightFactors: Record<string, number> = {\n mg: 0.001,\n g: 1,\n kg: 1000,\n oz: 28.3495,\n lb: 453.592,\n ton: 907185,\n};\n\nconst dataFactors: Record<string, number> = {\n b: 1,\n kb: 1024,\n mb: Math.pow(1024, 2),\n gb: Math.pow(1024, 3),\n tb: Math.pow(1024, 4),\n};\n\nconst temperatureUnits = new Set(['celsius', 'fahrenheit', 'kelvin']);\n\nfunction convertTemperature(value: number, from: string, to: string): number {\n if (from === to) return value;\n\n // Convert to Celsius first\n let celsius: number;\n switch (from) {\n case 'celsius':\n celsius = value;\n break;\n case 'fahrenheit':\n celsius = (value - 32) * 5 / 9;\n break;\n case 'kelvin':\n celsius = value - 273.15;\n break;\n default:\n throw new Error(`Unknown temperature unit: ${from}`);\n }\n\n // Convert from Celsius to target\n switch (to) {\n case 'celsius':\n return celsius;\n case 'fahrenheit':\n return celsius * 9 / 5 + 32;\n case 'kelvin':\n return celsius + 273.15;\n default:\n throw new Error(`Unknown temperature unit: ${to}`);\n }\n}\n\nfunction getFactors(category: UnitCategory): Record<string, number> {\n switch (category) {\n case 'length':\n return lengthFactors;\n case 'weight':\n return weightFactors;\n case 'data':\n return dataFactors;\n default:\n throw new Error(`No conversion factors for category: ${category}`);\n }\n}\n\nexport function convertUnit(\n value: number,\n from: string,\n to: string,\n category: UnitCategory\n): UnitConversionResult {\n const fromLower = from.toLowerCase();\n const toLower = to.toLowerCase();\n\n if (category === 'temperature') {\n if (!temperatureUnits.has(fromLower)) {\n throw new Error(`Unit '${from}' does not belong to category 'temperature'`);\n }\n if (!temperatureUnits.has(toLower)) {\n throw new Error(`Unit '${to}' does not belong to category 'temperature'`);\n }\n const result = convertTemperature(value, fromLower, toLower);\n return { value, from: fromLower, to: toLower, result };\n }\n\n const factors = getFactors(category);\n\n if (!(fromLower in factors)) {\n throw new Error(`Unit '${from}' does not belong to category '${category}'`);\n }\n if (!(toLower in factors)) {\n throw new Error(`Unit '${to}' does not belong to category '${category}'`);\n }\n\n // Convert to base unit, then to target unit\n const baseValue = value * factors[fromLower];\n const result = baseValue / factors[toLower];\n\n return { value, from: fromLower, to: toLower, result };\n}\n","import type { BaseConversionResult, NumberBase } from './types';\n\nconst radixMap: Record<NumberBase, number> = {\n binary: 2,\n octal: 8,\n decimal: 10,\n hex: 16,\n};\n\nexport function convertBase(input: string, fromBase: NumberBase): BaseConversionResult {\n const radix = radixMap[fromBase];\n if (radix === undefined) {\n throw new Error(`Unknown base: ${fromBase}`);\n }\n\n // Strip common prefixes before parsing\n let cleanInput = input.trim();\n if (fromBase === 'binary' && cleanInput.startsWith('0b')) {\n cleanInput = cleanInput.slice(2);\n } else if (fromBase === 'octal' && cleanInput.startsWith('0o')) {\n cleanInput = cleanInput.slice(2);\n } else if (fromBase === 'hex' && cleanInput.startsWith('0x')) {\n cleanInput = cleanInput.slice(2);\n }\n\n const decimalValue = parseInt(cleanInput, radix);\n if (isNaN(decimalValue)) {\n throw new Error(`Invalid input '${input}' for base '${fromBase}'`);\n }\n\n return {\n input,\n fromBase,\n binary: '0b' + decimalValue.toString(2),\n octal: '0o' + decimalValue.toString(8),\n decimal: decimalValue.toString(10),\n hex: '0x' + decimalValue.toString(16),\n };\n}\n","import type { StatisticsResult } from './types';\n\nfunction getPercentile(sorted: number[], p: number): number {\n if (sorted.length === 1) return sorted[0];\n\n const index = (p / 100) * (sorted.length - 1);\n const lower = Math.floor(index);\n const upper = Math.ceil(index);\n\n if (lower === upper) return sorted[lower];\n\n const fraction = index - lower;\n return sorted[lower] + fraction * (sorted[upper] - sorted[lower]);\n}\n\nexport function calculateStats(numbers: number[]): StatisticsResult {\n if (numbers.length === 0) {\n throw new Error('Cannot calculate statistics for an empty array');\n }\n\n const count = numbers.length;\n const sum = numbers.reduce((acc, n) => acc + n, 0);\n const mean = sum / count;\n\n const sorted = [...numbers].sort((a, b) => a - b);\n\n // Median\n let median: number;\n const mid = Math.floor(sorted.length / 2);\n if (sorted.length % 2 === 0) {\n median = (sorted[mid - 1] + sorted[mid]) / 2;\n } else {\n median = sorted[mid];\n }\n\n // Mode\n const frequencyMap = new Map<number, number>();\n for (const n of numbers) {\n frequencyMap.set(n, (frequencyMap.get(n) || 0) + 1);\n }\n let maxFrequency = 0;\n for (const freq of frequencyMap.values()) {\n if (freq > maxFrequency) maxFrequency = freq;\n }\n const mode: number[] = [];\n for (const [value, freq] of frequencyMap.entries()) {\n if (freq === maxFrequency) mode.push(value);\n }\n mode.sort((a, b) => a - b);\n\n const min = sorted[0];\n const max = sorted[sorted.length - 1];\n const range = max - min;\n\n // Variance (population variance)\n const variance = numbers.reduce((acc, n) => acc + Math.pow(n - mean, 2), 0) / count;\n const standardDeviation = Math.sqrt(variance);\n\n // Percentiles using linear interpolation\n const percentiles = {\n p25: getPercentile(sorted, 25),\n p50: getPercentile(sorted, 50),\n p75: getPercentile(sorted, 75),\n p90: getPercentile(sorted, 90),\n p99: getPercentile(sorted, 99),\n };\n\n return {\n count,\n sum,\n mean,\n median,\n mode,\n min,\n max,\n range,\n standardDeviation,\n variance,\n percentiles,\n };\n}\n","import type { NumberFormatOptions } from './types';\n\nexport function formatNumber(value: number, options?: NumberFormatOptions): string {\n const locale = options?.locale ?? 'en-US';\n\n const formatOptions: Intl.NumberFormatOptions = {};\n\n if (options?.style) {\n formatOptions.style = options.style;\n }\n\n if (options?.currency) {\n formatOptions.currency = options.currency;\n }\n\n if (options?.minimumFractionDigits !== undefined) {\n formatOptions.minimumFractionDigits = options.minimumFractionDigits;\n }\n\n if (options?.maximumFractionDigits !== undefined) {\n formatOptions.maximumFractionDigits = options.maximumFractionDigits;\n }\n\n return new Intl.NumberFormat(locale, formatOptions).format(value);\n}\n","import type { PercentageResult, PercentageChangeResult } from './types';\n\nexport function percentage(value: number, total: number): PercentageResult {\n if (total === 0) {\n throw new Error('Total cannot be zero');\n }\n\n const pct = (value / total) * 100;\n\n return {\n value,\n total,\n percentage: pct,\n formatted: `${pct}%`,\n };\n}\n\nexport function percentageChange(from: number, to: number): PercentageChangeResult {\n if (from === 0) {\n throw new Error('Cannot calculate percentage change from zero');\n }\n\n const change = ((to - from) / Math.abs(from)) * 100;\n const sign = change >= 0 ? '+' : '';\n const formatted = `${sign}${change}%`;\n\n return {\n from,\n to,\n change,\n formatted,\n };\n}\n"]}
|