@utilix-tech/sdk 0.45.0 → 0.46.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/CHANGELOG.md CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  Full release notes for all Utilix surfaces (browser tools, REST API, SDKs, MCP server) live at [utilix.tech/changelog](https://utilix.tech/changelog). This file tracks just this package.
4
4
 
5
+ ## 0.46.0
6
+ - Add `calculateDepreciationSchedule` (depreciation-schedule-calculator): build a year-by-year fixed-asset depreciation schedule from cost, salvage value, and useful life, using straight-line, double-declining-balance, or sum-of-years-digits.
7
+ - Add `analyzeKeywordDensity` (keyword-density-analyzer): count keyword/phrase frequency and density (occurrences per 100 words) across a block of text, with single-word or 2/3-word phrase modes.
8
+
5
9
  ## 0.45.0
6
10
  - Add `calculateCdMaturity` (cd-maturity-calculator): compute a certificate of deposit's maturity value and effective annual yield (APY) from a principal, nominal rate, term, and compounding frequency, plus the net payout if withdrawn early.
7
11
  - Add `buildClientHints`, `parseClientHintHeaders` (client-hints-header-builder): build an `Accept-CH`/`Critical-CH` response header from a list of client hint names with a plain-English note per hint, or decode raw Client Hints request-header text into structured values.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @utilix-tech/sdk
2
2
 
3
- **630 developer utility functions for Node.js: runs locally, no API key required.**
3
+ **632 developer utility functions for Node.js: runs locally, no API key required.**
4
4
 
5
5
  [![npm version](https://img.shields.io/npm/v/@utilix-tech/sdk?style=flat-square&color=cb3837)](https://www.npmjs.com/package/@utilix-tech/sdk)
6
6
  [![npm downloads](https://img.shields.io/npm/dm/@utilix-tech/sdk?style=flat-square)](https://www.npmjs.com/package/@utilix-tech/sdk)
@@ -149,7 +149,7 @@ generateEtag("console.log(1)");
149
149
  import { convertCase, slugify, countWords, generateWords, generateParagraphs,
150
150
  escapeString, htmlToMarkdown, applyOps, detectPassiveVoice, scoreReadability,
151
151
  detectFillerWords, calculateStringDistance, analyzeSentenceLengths,
152
- searchEmoji, getEmojiByShortcode } from "@utilix-tech/sdk/text";
152
+ analyzeKeywordDensity, searchEmoji, getEmojiByShortcode } from "@utilix-tech/sdk/text";
153
153
 
154
154
  convertCase("hello world", "camelCase"); // "helloWorld"
155
155
  convertCase("hello world", "PascalCase"); // "HelloWorld"
@@ -190,6 +190,10 @@ analyzeSentenceLengths("The cat sat on the mat. It was a sunny day, and the dog
190
190
  // Search ~280 common emoji by name, keyword, or GitHub-style shortcode
191
191
  searchEmoji("fire"); // [{ emoji: "🔥", name: "fire", shortcode: "fire", codepoint: "U+1F525", ... }]
192
192
  getEmojiByShortcode(":joy:"); // { emoji: "😂", name: "face with tears of joy", ... }
193
+
194
+ // Keyword/phrase frequency and density (occurrences per 100 words); ngramSize 2 or 3 for phrases
195
+ analyzeKeywordDensity("machine learning models power machine learning systems");
196
+ // { totalWords: 7, uniqueKeywords: 5, ngramSize: 1, keywords: [{ keyword: "learning", count: 2, density: 28.6 }, ...] }
193
197
  ```
194
198
 
195
199
  ---
@@ -312,7 +316,7 @@ formatIso8601Duration(90061); // { iso: "P1DT1H1M1S", ... }
312
316
  ### `/units`: Conversions
313
317
 
314
318
  ```ts
315
- import { convertBytes, pxToAll, convert, formatValue, validateCardNumber, validateIban, calculateLoan, validateBarcode, calculateTax, calculateCompoundInterest, validateIsbn, calculateTipSplit, calculateSimpleInterest, calculateTimeValue, calculatePercentageChange, convertAprApy, calculateMarginMarkup, calculateDiscount, applySuccessiveDiscounts, calculateBreakEven, calculateVideoBitrate, calculateRuleOf72, calculateEmi, calculateRoi, compareUnitPrices, calculatePaybackPeriod, calculateCdMaturity } from "@utilix-tech/sdk/units";
319
+ import { convertBytes, pxToAll, convert, formatValue, validateCardNumber, validateIban, calculateLoan, validateBarcode, calculateTax, calculateCompoundInterest, validateIsbn, calculateTipSplit, calculateSimpleInterest, calculateTimeValue, calculatePercentageChange, convertAprApy, calculateMarginMarkup, calculateDiscount, applySuccessiveDiscounts, calculateBreakEven, calculateVideoBitrate, calculateRuleOf72, calculateEmi, calculateRoi, compareUnitPrices, calculatePaybackPeriod, calculateCdMaturity, calculateDepreciationSchedule } from "@utilix-tech/sdk/units";
316
320
 
317
321
  // File sizes
318
322
  convertBytes(1073741824, "GB"); // 1
@@ -430,6 +434,10 @@ calculatePaybackPeriod({ initialInvestment: 1000, cashFlows: [400, 400, 400], di
430
434
  // Certificate of deposit maturity value, APY, and net early-withdrawal payout
431
435
  calculateCdMaturity(1000, 12, 12, 12, 3);
432
436
  // { maturityValue: 1126.83, totalInterest: 126.83, apy: 12.6825, earlyWithdrawalPayout: 1096.83, ... }
437
+
438
+ // Year-by-year depreciation schedule: straight-line, double-declining-balance, or sum-of-years-digits
439
+ calculateDepreciationSchedule(10000, 1000, 5, "straight-line");
440
+ // { totalDepreciation: 9000, schedule: [{ year: 1, depreciationExpense: 1800, accumulatedDepreciation: 1800, bookValue: 8200 }, ...] }
433
441
  ```
434
442
 
435
443
  ---
@@ -25,6 +25,7 @@ __export(units_exports, {
25
25
  calculateCdMaturity: () => calculateCdMaturity,
26
26
  calculateChange: () => calculateChange,
27
27
  calculateCompoundInterest: () => calculateCompoundInterest,
28
+ calculateDepreciationSchedule: () => calculateDepreciationSchedule,
28
29
  calculateDiscount: () => calculateDiscount,
29
30
  calculateEmi: () => calculateEmi,
30
31
  calculateLoan: () => calculateLoan,
@@ -2022,5 +2023,58 @@ function calculateCdMaturity(principal, annualRatePercent, termMonths, compounds
2022
2023
  }
2023
2024
  return result;
2024
2025
  }
2026
+ var DEPRECIATION_METHODS = ["straight-line", "double-declining-balance", "sum-of-years-digits"];
2027
+ function calculateDepreciationSchedule(cost, salvageValue, usefulLifeYears, method) {
2028
+ if (!Number.isFinite(cost) || cost <= 0) return { error: "Cost must be a positive number" };
2029
+ if (!Number.isFinite(salvageValue) || salvageValue < 0) {
2030
+ return { error: "Salvage value must be zero or a positive number" };
2031
+ }
2032
+ if (salvageValue >= cost) return { error: "Salvage value must be less than cost" };
2033
+ if (!Number.isInteger(usefulLifeYears) || usefulLifeYears <= 0) {
2034
+ return { error: "Useful life must be a positive whole number of years" };
2035
+ }
2036
+ if (!DEPRECIATION_METHODS.includes(method)) {
2037
+ return { error: `Method must be one of: ${DEPRECIATION_METHODS.join(", ")}` };
2038
+ }
2039
+ const round22 = (n) => Math.round(n * 100) / 100;
2040
+ const depreciableBase = round22(cost - salvageValue);
2041
+ const schedule = [];
2042
+ let accumulated = 0;
2043
+ if (method === "straight-line") {
2044
+ const annual = round22(depreciableBase / usefulLifeYears);
2045
+ for (let year = 1; year <= usefulLifeYears; year++) {
2046
+ const expense = year === usefulLifeYears ? round22(depreciableBase - accumulated) : annual;
2047
+ accumulated = round22(accumulated + expense);
2048
+ schedule.push({ year, depreciationExpense: expense, accumulatedDepreciation: accumulated, bookValue: round22(cost - accumulated) });
2049
+ }
2050
+ } else if (method === "double-declining-balance") {
2051
+ const rate = 2 / usefulLifeYears;
2052
+ let bookValue = cost;
2053
+ for (let year = 1; year <= usefulLifeYears; year++) {
2054
+ let expense = round22(bookValue * rate);
2055
+ if (bookValue - expense < salvageValue) expense = round22(bookValue - salvageValue);
2056
+ if (expense < 0) expense = 0;
2057
+ bookValue = round22(bookValue - expense);
2058
+ accumulated = round22(accumulated + expense);
2059
+ schedule.push({ year, depreciationExpense: expense, accumulatedDepreciation: accumulated, bookValue });
2060
+ }
2061
+ } else {
2062
+ const sumOfYears = usefulLifeYears * (usefulLifeYears + 1) / 2;
2063
+ for (let year = 1; year <= usefulLifeYears; year++) {
2064
+ const fraction = (usefulLifeYears - year + 1) / sumOfYears;
2065
+ const expense = year === usefulLifeYears ? round22(depreciableBase - accumulated) : round22(fraction * depreciableBase);
2066
+ accumulated = round22(accumulated + expense);
2067
+ schedule.push({ year, depreciationExpense: expense, accumulatedDepreciation: accumulated, bookValue: round22(cost - accumulated) });
2068
+ }
2069
+ }
2070
+ return {
2071
+ cost,
2072
+ salvageValue,
2073
+ usefulLifeYears,
2074
+ method,
2075
+ totalDepreciation: accumulated,
2076
+ schedule
2077
+ };
2078
+ }
2025
2079
 
2026
- export { BASE_LABELS, BASE_PREFIXES, BYTE_UNITS, COMMON_CURRENCIES, COMMON_LOCALES, COMMON_PERMISSIONS, COMMON_RATIOS, COMMON_SIZES, COMMON_TAX_RATES, COMMON_TIP_PERCENTAGES, COMMON_VIEWPORTS, USD_DENOMINATIONS, applySuccessiveDiscounts, autoFormat, bumpVersion, calcAspectRatio, calcSubnet, calculateBreakEven, calculateCashBreakdown, calculateCdMaturity, calculateChange, calculateCompoundInterest, calculateDiscount, calculateEmi, calculateLoan, calculateMarginMarkup, calculatePaybackPeriod, calculatePercentageChange, calculateRoi, calculateRuleOf72, calculateSavingsGoal, calculateSimpleInterest, calculateTax, calculateTimeValue, calculateTipSplit, calculateVideoBitrate, compareSemver, compareUnitPrices, convert, convertAprApy, convertBytes, convertIp, coverBox, decimalToIp, decimalToIpCidr, describePermissions, fitIntoBox, formatNumber, formatValue, formatVwValue, formatWithSeparator, gcd, ipFromBinary, ipFromDecimal, ipFromHex, ipToBinary, ipToDecimal, ipToDecimalCidr, ipToHex, ipToOctal, isValid, isValidCidr, isValidIp, isValidIpv4, marginToMarkup, markupToMargin, octalToPermissions, parseFileSize, parseInput, parseNumberString, parseSemver, permissionsToChmod, permissionsToOctal, permissionsToSymbolic, ptToPx, pxToAll, pxToViewport, remToPx, satisfiesRange, scaleByHeight, scaleByWidth, sortVersions, splitSubnet, symbolicToPermissions, units_exports, validateBarcode, validateCardNumber, validateIban, validateIsbn, viewportToPx };
2080
+ export { BASE_LABELS, BASE_PREFIXES, BYTE_UNITS, COMMON_CURRENCIES, COMMON_LOCALES, COMMON_PERMISSIONS, COMMON_RATIOS, COMMON_SIZES, COMMON_TAX_RATES, COMMON_TIP_PERCENTAGES, COMMON_VIEWPORTS, USD_DENOMINATIONS, applySuccessiveDiscounts, autoFormat, bumpVersion, calcAspectRatio, calcSubnet, calculateBreakEven, calculateCashBreakdown, calculateCdMaturity, calculateChange, calculateCompoundInterest, calculateDepreciationSchedule, calculateDiscount, calculateEmi, calculateLoan, calculateMarginMarkup, calculatePaybackPeriod, calculatePercentageChange, calculateRoi, calculateRuleOf72, calculateSavingsGoal, calculateSimpleInterest, calculateTax, calculateTimeValue, calculateTipSplit, calculateVideoBitrate, compareSemver, compareUnitPrices, convert, convertAprApy, convertBytes, convertIp, coverBox, decimalToIp, decimalToIpCidr, describePermissions, fitIntoBox, formatNumber, formatValue, formatVwValue, formatWithSeparator, gcd, ipFromBinary, ipFromDecimal, ipFromHex, ipToBinary, ipToDecimal, ipToDecimalCidr, ipToHex, ipToOctal, isValid, isValidCidr, isValidIp, isValidIpv4, marginToMarkup, markupToMargin, octalToPermissions, parseFileSize, parseInput, parseNumberString, parseSemver, permissionsToChmod, permissionsToOctal, permissionsToSymbolic, ptToPx, pxToAll, pxToViewport, remToPx, satisfiesRange, scaleByHeight, scaleByWidth, sortVersions, splitSubnet, symbolicToPermissions, units_exports, validateBarcode, validateCardNumber, validateIban, validateIsbn, viewportToPx };
@@ -11,6 +11,7 @@ __export(text_exports, {
11
11
  LINE_OPS: () => LINE_OPS,
12
12
  MORSE_CODE: () => MORSE_CODE,
13
13
  addBorder: () => addBorder,
14
+ analyzeKeywordDensity: () => analyzeKeywordDensity,
14
15
  analyzeSentenceLengths: () => analyzeSentenceLengths,
15
16
  analyzeText: () => analyzeText,
16
17
  applyOp: () => applyOp,
@@ -2670,6 +2671,131 @@ function analyzeSentenceLengths(text) {
2670
2671
  buckets
2671
2672
  };
2672
2673
  }
2674
+ var KEYWORD_DENSITY_STOPWORDS = /* @__PURE__ */ new Set([
2675
+ "a",
2676
+ "an",
2677
+ "the",
2678
+ "and",
2679
+ "or",
2680
+ "but",
2681
+ "if",
2682
+ "then",
2683
+ "else",
2684
+ "for",
2685
+ "nor",
2686
+ "so",
2687
+ "yet",
2688
+ "of",
2689
+ "in",
2690
+ "on",
2691
+ "at",
2692
+ "to",
2693
+ "from",
2694
+ "by",
2695
+ "with",
2696
+ "about",
2697
+ "against",
2698
+ "between",
2699
+ "into",
2700
+ "through",
2701
+ "during",
2702
+ "before",
2703
+ "after",
2704
+ "above",
2705
+ "below",
2706
+ "up",
2707
+ "down",
2708
+ "out",
2709
+ "off",
2710
+ "over",
2711
+ "under",
2712
+ "again",
2713
+ "further",
2714
+ "once",
2715
+ "is",
2716
+ "are",
2717
+ "was",
2718
+ "were",
2719
+ "be",
2720
+ "been",
2721
+ "being",
2722
+ "am",
2723
+ "do",
2724
+ "does",
2725
+ "did",
2726
+ "doing",
2727
+ "have",
2728
+ "has",
2729
+ "had",
2730
+ "having",
2731
+ "i",
2732
+ "me",
2733
+ "my",
2734
+ "we",
2735
+ "our",
2736
+ "you",
2737
+ "your",
2738
+ "he",
2739
+ "him",
2740
+ "his",
2741
+ "she",
2742
+ "her",
2743
+ "it",
2744
+ "its",
2745
+ "they",
2746
+ "them",
2747
+ "their",
2748
+ "this",
2749
+ "that",
2750
+ "these",
2751
+ "those",
2752
+ "as",
2753
+ "not",
2754
+ "no",
2755
+ "can",
2756
+ "will",
2757
+ "just",
2758
+ "than",
2759
+ "too",
2760
+ "very",
2761
+ "would",
2762
+ "should",
2763
+ "could",
2764
+ "there",
2765
+ "here",
2766
+ "what",
2767
+ "which",
2768
+ "who",
2769
+ "whom"
2770
+ ]);
2771
+ function analyzeKeywordDensity(text, options = {}) {
2772
+ if (!text || !text.trim()) return { error: "Input text is empty" };
2773
+ const topN = options.topN ?? 10;
2774
+ const minWordLength = options.minWordLength ?? 3;
2775
+ const ngramSize = options.ngramSize ?? 1;
2776
+ if (!Number.isInteger(topN) || topN <= 0) return { error: "topN must be a positive whole number" };
2777
+ if (!Number.isInteger(minWordLength) || minWordLength < 1) return { error: "minWordLength must be a positive whole number" };
2778
+ if (!Number.isInteger(ngramSize) || ngramSize < 1 || ngramSize > 3) return { error: "ngramSize must be 1, 2, or 3" };
2779
+ const tokens = text.toLowerCase().match(/[a-z0-9']+/g) ?? [];
2780
+ const totalWords = tokens.length;
2781
+ if (totalWords === 0) return { error: "No words found in input text" };
2782
+ if (totalWords < ngramSize) return { error: "Input text has fewer words than the requested phrase length" };
2783
+ const counts = /* @__PURE__ */ new Map();
2784
+ for (let i = 0; i <= tokens.length - ngramSize; i++) {
2785
+ const phraseWords = tokens.slice(i, i + ngramSize);
2786
+ if (phraseWords.some((w) => w.length < minWordLength)) continue;
2787
+ if (ngramSize === 1 && KEYWORD_DENSITY_STOPWORDS.has(phraseWords[0])) continue;
2788
+ const phrase = phraseWords.join(" ");
2789
+ counts.set(phrase, (counts.get(phrase) ?? 0) + 1);
2790
+ }
2791
+ const keywords = Array.from(counts.entries()).map(([keyword, count]) => ({ keyword, count, density: Math.round(count / totalWords * 1e3) / 10 })).sort((a, b) => b.count - a.count || a.keyword.localeCompare(b.keyword)).slice(0, topN);
2792
+ return {
2793
+ totalWords,
2794
+ uniqueKeywords: counts.size,
2795
+ ngramSize,
2796
+ keywords
2797
+ };
2798
+ }
2673
2799
  var EMOJI_TABLE = [
2674
2800
  { emoji: "\u{1F600}", name: "grinning face", shortcode: "grinning", codepoint: "U+1F600", category: "Smileys & Emotion", keywords: ["happy", "smile"] },
2675
2801
  { emoji: "\u{1F603}", name: "grinning face with big eyes", shortcode: "smiley", codepoint: "U+1F603", category: "Smileys & Emotion", keywords: ["happy", "joy"] },
@@ -2970,4 +3096,4 @@ function getEmojiCategories() {
2970
3096
  return Array.from(new Set(EMOJI_TABLE.map((e) => e.category)));
2971
3097
  }
2972
3098
 
2973
- export { CASE_FORMATS, DEFAULT_CONVERT_OPTIONS, EMOJI_TABLE, ESCAPE_MODES, LINE_OPS, MORSE_CODE, addBorder, analyzeSentenceLengths, analyzeText, applyOp, applyOps, calculateStringDistance, centerText, convertAll, convertCase, countWords, csvToHtml, csvToMarkdown, detectDelimiter, detectFillerWords, detectPassiveVoice, diffLines, diffLinesSimple, diffStats, escapeAll, escapeString, extractHeadings, formatReadingTime, generate, generateDiff, generateHtmlTable, generateMarkdownTable, generateParagraphs, generateSentences, generateWords, getAvailableFonts, getEmojiByCategory, getEmojiByChar, getEmojiByShortcode, getEmojiCategories, getMorseForChar, getMorseTiming, htmlToMarkdown, isValidMorse, markdownToHtml, morseToText, numberToOrdinal, numberToRoman, numberToWords, ordinalWords, parseDiff, parseTableData, readabilityScore, renderMarkdown, romanToNumber, scoreReadability, searchEmoji, sentenceCount, slugify, slugifyAll, syllableCount, textToAscii, textToMorse, text_exports, unescapeString, wordFrequency };
3099
+ export { CASE_FORMATS, DEFAULT_CONVERT_OPTIONS, EMOJI_TABLE, ESCAPE_MODES, LINE_OPS, MORSE_CODE, addBorder, analyzeKeywordDensity, analyzeSentenceLengths, analyzeText, applyOp, applyOps, calculateStringDistance, centerText, convertAll, convertCase, countWords, csvToHtml, csvToMarkdown, detectDelimiter, detectFillerWords, detectPassiveVoice, diffLines, diffLinesSimple, diffStats, escapeAll, escapeString, extractHeadings, formatReadingTime, generate, generateDiff, generateHtmlTable, generateMarkdownTable, generateParagraphs, generateSentences, generateWords, getAvailableFonts, getEmojiByCategory, getEmojiByChar, getEmojiByShortcode, getEmojiCategories, getMorseForChar, getMorseTiming, htmlToMarkdown, isValidMorse, markdownToHtml, morseToText, numberToOrdinal, numberToRoman, numberToWords, ordinalWords, parseDiff, parseTableData, readabilityScore, renderMarkdown, romanToNumber, scoreReadability, searchEmoji, sentenceCount, slugify, slugifyAll, syllableCount, textToAscii, textToMorse, text_exports, unescapeString, wordFrequency };
package/dist/index.cjs CHANGED
@@ -2063,6 +2063,7 @@ __export(text_exports, {
2063
2063
  LINE_OPS: () => LINE_OPS,
2064
2064
  MORSE_CODE: () => MORSE_CODE,
2065
2065
  addBorder: () => addBorder,
2066
+ analyzeKeywordDensity: () => analyzeKeywordDensity,
2066
2067
  analyzeSentenceLengths: () => analyzeSentenceLengths,
2067
2068
  analyzeText: () => analyzeText,
2068
2069
  applyOp: () => applyOp,
@@ -4722,6 +4723,131 @@ function analyzeSentenceLengths(text) {
4722
4723
  buckets
4723
4724
  };
4724
4725
  }
4726
+ var KEYWORD_DENSITY_STOPWORDS = /* @__PURE__ */ new Set([
4727
+ "a",
4728
+ "an",
4729
+ "the",
4730
+ "and",
4731
+ "or",
4732
+ "but",
4733
+ "if",
4734
+ "then",
4735
+ "else",
4736
+ "for",
4737
+ "nor",
4738
+ "so",
4739
+ "yet",
4740
+ "of",
4741
+ "in",
4742
+ "on",
4743
+ "at",
4744
+ "to",
4745
+ "from",
4746
+ "by",
4747
+ "with",
4748
+ "about",
4749
+ "against",
4750
+ "between",
4751
+ "into",
4752
+ "through",
4753
+ "during",
4754
+ "before",
4755
+ "after",
4756
+ "above",
4757
+ "below",
4758
+ "up",
4759
+ "down",
4760
+ "out",
4761
+ "off",
4762
+ "over",
4763
+ "under",
4764
+ "again",
4765
+ "further",
4766
+ "once",
4767
+ "is",
4768
+ "are",
4769
+ "was",
4770
+ "were",
4771
+ "be",
4772
+ "been",
4773
+ "being",
4774
+ "am",
4775
+ "do",
4776
+ "does",
4777
+ "did",
4778
+ "doing",
4779
+ "have",
4780
+ "has",
4781
+ "had",
4782
+ "having",
4783
+ "i",
4784
+ "me",
4785
+ "my",
4786
+ "we",
4787
+ "our",
4788
+ "you",
4789
+ "your",
4790
+ "he",
4791
+ "him",
4792
+ "his",
4793
+ "she",
4794
+ "her",
4795
+ "it",
4796
+ "its",
4797
+ "they",
4798
+ "them",
4799
+ "their",
4800
+ "this",
4801
+ "that",
4802
+ "these",
4803
+ "those",
4804
+ "as",
4805
+ "not",
4806
+ "no",
4807
+ "can",
4808
+ "will",
4809
+ "just",
4810
+ "than",
4811
+ "too",
4812
+ "very",
4813
+ "would",
4814
+ "should",
4815
+ "could",
4816
+ "there",
4817
+ "here",
4818
+ "what",
4819
+ "which",
4820
+ "who",
4821
+ "whom"
4822
+ ]);
4823
+ function analyzeKeywordDensity(text, options = {}) {
4824
+ if (!text || !text.trim()) return { error: "Input text is empty" };
4825
+ const topN = options.topN ?? 10;
4826
+ const minWordLength = options.minWordLength ?? 3;
4827
+ const ngramSize = options.ngramSize ?? 1;
4828
+ if (!Number.isInteger(topN) || topN <= 0) return { error: "topN must be a positive whole number" };
4829
+ if (!Number.isInteger(minWordLength) || minWordLength < 1) return { error: "minWordLength must be a positive whole number" };
4830
+ if (!Number.isInteger(ngramSize) || ngramSize < 1 || ngramSize > 3) return { error: "ngramSize must be 1, 2, or 3" };
4831
+ const tokens = text.toLowerCase().match(/[a-z0-9']+/g) ?? [];
4832
+ const totalWords = tokens.length;
4833
+ if (totalWords === 0) return { error: "No words found in input text" };
4834
+ if (totalWords < ngramSize) return { error: "Input text has fewer words than the requested phrase length" };
4835
+ const counts = /* @__PURE__ */ new Map();
4836
+ for (let i = 0; i <= tokens.length - ngramSize; i++) {
4837
+ const phraseWords = tokens.slice(i, i + ngramSize);
4838
+ if (phraseWords.some((w) => w.length < minWordLength)) continue;
4839
+ if (ngramSize === 1 && KEYWORD_DENSITY_STOPWORDS.has(phraseWords[0])) continue;
4840
+ const phrase = phraseWords.join(" ");
4841
+ counts.set(phrase, (counts.get(phrase) ?? 0) + 1);
4842
+ }
4843
+ const keywords = Array.from(counts.entries()).map(([keyword, count]) => ({ keyword, count, density: Math.round(count / totalWords * 1e3) / 10 })).sort((a, b) => b.count - a.count || a.keyword.localeCompare(b.keyword)).slice(0, topN);
4844
+ return {
4845
+ totalWords,
4846
+ uniqueKeywords: counts.size,
4847
+ ngramSize,
4848
+ keywords
4849
+ };
4850
+ }
4725
4851
  var EMOJI_TABLE = [
4726
4852
  { emoji: "\u{1F600}", name: "grinning face", shortcode: "grinning", codepoint: "U+1F600", category: "Smileys & Emotion", keywords: ["happy", "smile"] },
4727
4853
  { emoji: "\u{1F603}", name: "grinning face with big eyes", shortcode: "smiley", codepoint: "U+1F603", category: "Smileys & Emotion", keywords: ["happy", "joy"] },
@@ -8002,6 +8128,7 @@ __export(units_exports, {
8002
8128
  calculateCdMaturity: () => calculateCdMaturity,
8003
8129
  calculateChange: () => calculateChange,
8004
8130
  calculateCompoundInterest: () => calculateCompoundInterest,
8131
+ calculateDepreciationSchedule: () => calculateDepreciationSchedule,
8005
8132
  calculateDiscount: () => calculateDiscount,
8006
8133
  calculateEmi: () => calculateEmi,
8007
8134
  calculateLoan: () => calculateLoan,
@@ -9999,6 +10126,59 @@ function calculateCdMaturity(principal, annualRatePercent, termMonths, compounds
9999
10126
  }
10000
10127
  return result;
10001
10128
  }
10129
+ var DEPRECIATION_METHODS = ["straight-line", "double-declining-balance", "sum-of-years-digits"];
10130
+ function calculateDepreciationSchedule(cost, salvageValue, usefulLifeYears, method) {
10131
+ if (!Number.isFinite(cost) || cost <= 0) return { error: "Cost must be a positive number" };
10132
+ if (!Number.isFinite(salvageValue) || salvageValue < 0) {
10133
+ return { error: "Salvage value must be zero or a positive number" };
10134
+ }
10135
+ if (salvageValue >= cost) return { error: "Salvage value must be less than cost" };
10136
+ if (!Number.isInteger(usefulLifeYears) || usefulLifeYears <= 0) {
10137
+ return { error: "Useful life must be a positive whole number of years" };
10138
+ }
10139
+ if (!DEPRECIATION_METHODS.includes(method)) {
10140
+ return { error: `Method must be one of: ${DEPRECIATION_METHODS.join(", ")}` };
10141
+ }
10142
+ const round23 = (n) => Math.round(n * 100) / 100;
10143
+ const depreciableBase = round23(cost - salvageValue);
10144
+ const schedule = [];
10145
+ let accumulated = 0;
10146
+ if (method === "straight-line") {
10147
+ const annual = round23(depreciableBase / usefulLifeYears);
10148
+ for (let year = 1; year <= usefulLifeYears; year++) {
10149
+ const expense = year === usefulLifeYears ? round23(depreciableBase - accumulated) : annual;
10150
+ accumulated = round23(accumulated + expense);
10151
+ schedule.push({ year, depreciationExpense: expense, accumulatedDepreciation: accumulated, bookValue: round23(cost - accumulated) });
10152
+ }
10153
+ } else if (method === "double-declining-balance") {
10154
+ const rate = 2 / usefulLifeYears;
10155
+ let bookValue = cost;
10156
+ for (let year = 1; year <= usefulLifeYears; year++) {
10157
+ let expense = round23(bookValue * rate);
10158
+ if (bookValue - expense < salvageValue) expense = round23(bookValue - salvageValue);
10159
+ if (expense < 0) expense = 0;
10160
+ bookValue = round23(bookValue - expense);
10161
+ accumulated = round23(accumulated + expense);
10162
+ schedule.push({ year, depreciationExpense: expense, accumulatedDepreciation: accumulated, bookValue });
10163
+ }
10164
+ } else {
10165
+ const sumOfYears = usefulLifeYears * (usefulLifeYears + 1) / 2;
10166
+ for (let year = 1; year <= usefulLifeYears; year++) {
10167
+ const fraction = (usefulLifeYears - year + 1) / sumOfYears;
10168
+ const expense = year === usefulLifeYears ? round23(depreciableBase - accumulated) : round23(fraction * depreciableBase);
10169
+ accumulated = round23(accumulated + expense);
10170
+ schedule.push({ year, depreciationExpense: expense, accumulatedDepreciation: accumulated, bookValue: round23(cost - accumulated) });
10171
+ }
10172
+ }
10173
+ return {
10174
+ cost,
10175
+ salvageValue,
10176
+ usefulLifeYears,
10177
+ method,
10178
+ totalDepreciation: accumulated,
10179
+ schedule
10180
+ };
10181
+ }
10002
10182
 
10003
10183
  // src/tools/network.ts
10004
10184
  var network_exports = {};
package/dist/index.d.cts CHANGED
@@ -1,11 +1,11 @@
1
1
  export { j as json } from './json-Ta9JykSB.cjs';
2
2
  export { e as encoding } from './encoding-Dk3wpmb3.cjs';
3
3
  export { h as hashing } from './hashing-CJjlvqS_.cjs';
4
- export { t as text } from './text-kHkT9VtT.cjs';
4
+ export { t as text } from './text-DWUcY8H1.cjs';
5
5
  export { d as data } from './data-BKpEOcOX.cjs';
6
6
  export { g as generators } from './generators-Du8cBesn.cjs';
7
7
  export { t as time } from './time-KqJjdqII.cjs';
8
- export { u as units } from './units-DWRmbS_a.cjs';
8
+ export { u as units } from './units-DU4Pisfx.cjs';
9
9
  export { n as network } from './network-Bzm1tjMA.cjs';
10
10
  export { a as api } from './api-DmTNE4c1.cjs';
11
11
  export { c as code } from './code-KXoRsHtl.cjs';
package/dist/index.d.ts CHANGED
@@ -1,11 +1,11 @@
1
1
  export { j as json } from './json-Ta9JykSB.js';
2
2
  export { e as encoding } from './encoding-Dk3wpmb3.js';
3
3
  export { h as hashing } from './hashing-CJjlvqS_.js';
4
- export { t as text } from './text-kHkT9VtT.js';
4
+ export { t as text } from './text-DWUcY8H1.js';
5
5
  export { d as data } from './data-BKpEOcOX.js';
6
6
  export { g as generators } from './generators-Du8cBesn.js';
7
7
  export { t as time } from './time-KqJjdqII.js';
8
- export { u as units } from './units-DWRmbS_a.js';
8
+ export { u as units } from './units-DU4Pisfx.js';
9
9
  export { n as network } from './network-Bzm1tjMA.js';
10
10
  export { a as api } from './api-DmTNE4c1.js';
11
11
  export { c as code } from './code-KXoRsHtl.js';
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  export { media_exports as media } from './chunk-L6V4W4SU.js';
2
- export { units_exports as units } from './chunk-DFLHX4NW.js';
2
+ export { units_exports as units } from './chunk-KMQHBUYO.js';
3
3
  export { network_exports as network } from './chunk-7PEKYLRB.js';
4
4
  export { api_exports as api } from './chunk-52ZDKSIX.js';
5
5
  export { code_exports as code } from './chunk-JL7YTXRB.js';
@@ -10,7 +10,7 @@ export { ai_agent_exports as ai_agent } from './chunk-EKIXOA7B.js';
10
10
  export { json_exports as json } from './chunk-WVEKRKGU.js';
11
11
  export { encoding_exports as encoding } from './chunk-DOWQZUTP.js';
12
12
  export { hashing_exports as hashing } from './chunk-PET2CGTH.js';
13
- export { text_exports as text } from './chunk-F2CEN226.js';
13
+ export { text_exports as text } from './chunk-P7TXG7CI.js';
14
14
  export { data_exports as data } from './chunk-JR354NH4.js';
15
15
  export { generators_exports as generators } from './chunk-3TYWIX3B.js';
16
16
  export { time_exports as time } from './chunk-IEPWZERQ.js';
@@ -23,6 +23,7 @@
23
23
  * - readability-score: scoreReadability
24
24
  * - filler-word-detector: detectFillerWords
25
25
  * - sentence-length-distribution: analyzeSentenceLengths
26
+ * - keyword-density-analyzer: analyzeKeywordDensity
26
27
  * - emoji-lookup : searchEmoji, getEmojiByShortcode, getEmojiByChar, getEmojiByCategory, getEmojiCategories, EMOJI_TABLE
27
28
  */
28
29
  interface WordCountResult {
@@ -357,6 +358,33 @@ interface SentenceLengthDistribution {
357
358
  * (e.g. "Dr.") as sentence boundaries.
358
359
  */
359
360
  declare function analyzeSentenceLengths(text: string): SentenceLengthDistribution;
361
+ interface KeywordDensityEntry {
362
+ keyword: string;
363
+ count: number;
364
+ density: number;
365
+ }
366
+ interface KeywordDensityResult {
367
+ totalWords: number;
368
+ uniqueKeywords: number;
369
+ ngramSize: number;
370
+ keywords: KeywordDensityEntry[];
371
+ }
372
+ interface KeywordDensityOptions {
373
+ topN?: number;
374
+ minWordLength?: number;
375
+ ngramSize?: number;
376
+ }
377
+ /**
378
+ * Count keyword/phrase frequency and density (occurrences per 100 words)
379
+ * across a block of text, the way an SEO keyword-density checker does.
380
+ * With the default ngramSize of 1, common English stopwords and words
381
+ * shorter than minWordLength are excluded; for ngramSize 2 or 3 (phrases),
382
+ * stopwords are kept since useful phrases often contain them, but every
383
+ * word in the phrase must still meet minWordLength.
384
+ */
385
+ declare function analyzeKeywordDensity(text: string, options?: KeywordDensityOptions): KeywordDensityResult | {
386
+ error: string;
387
+ };
360
388
  interface EmojiEntry {
361
389
  emoji: string;
362
390
  name: string;
@@ -401,6 +429,9 @@ type text_EscapeMode = EscapeMode;
401
429
  type text_FillerCategory = FillerCategory;
402
430
  type text_FillerMatch = FillerMatch;
403
431
  type text_FillerWordResult = FillerWordResult;
432
+ type text_KeywordDensityEntry = KeywordDensityEntry;
433
+ type text_KeywordDensityOptions = KeywordDensityOptions;
434
+ type text_KeywordDensityResult = KeywordDensityResult;
404
435
  declare const text_LINE_OPS: typeof LINE_OPS;
405
436
  type text_LineOp = LineOp;
406
437
  type text_LineType = LineType;
@@ -424,6 +455,7 @@ type text_TableOptions = TableOptions;
424
455
  type text_TextAnalysis = TextAnalysis;
425
456
  type text_WordCountResult = WordCountResult;
426
457
  declare const text_addBorder: typeof addBorder;
458
+ declare const text_analyzeKeywordDensity: typeof analyzeKeywordDensity;
427
459
  declare const text_analyzeSentenceLengths: typeof analyzeSentenceLengths;
428
460
  declare const text_analyzeText: typeof analyzeText;
429
461
  declare const text_applyOp: typeof applyOp;
@@ -483,7 +515,7 @@ declare const text_textToMorse: typeof textToMorse;
483
515
  declare const text_unescapeString: typeof unescapeString;
484
516
  declare const text_wordFrequency: typeof wordFrequency;
485
517
  declare namespace text {
486
- export { type text_AsciiFont as AsciiFont, type text_AsciiOptions as AsciiOptions, text_CASE_FORMATS as CASE_FORMATS, type text_CaseFormat as CaseFormat, type text_ConvertOptions as ConvertOptions, text_DEFAULT_CONVERT_OPTIONS as DEFAULT_CONVERT_OPTIONS, type text_DiffFile as DiffFile, type text_DiffHunk as DiffHunk, type text_DiffLine as DiffLine, type text_DiffResult as DiffResult, type text_DiffType as DiffType, type text_DiffViewerLine as DiffViewerLine, text_EMOJI_TABLE as EMOJI_TABLE, text_ESCAPE_MODES as ESCAPE_MODES, type text_EmojiEntry as EmojiEntry, type text_EscapeMode as EscapeMode, type text_FillerCategory as FillerCategory, type text_FillerMatch as FillerMatch, type text_FillerWordResult as FillerWordResult, text_LINE_OPS as LINE_OPS, type text_LineOp as LineOp, type text_LineType as LineType, type text_LoremUnit as LoremUnit, text_MORSE_CODE as MORSE_CODE, type text_MarkdownResult as MarkdownResult, type text_MorseOptions as MorseOptions, type text_ParsedDiff as ParsedDiff, type text_ParsedTable as ParsedTable, type text_PassiveVoiceMatch as PassiveVoiceMatch, type text_PassiveVoiceResult as PassiveVoiceResult, type text_PassiveVoiceSentence as PassiveVoiceSentence, type text_ReadabilityResult as ReadabilityResult, type text_ReadabilityScore as ReadabilityScore, type text_SentenceLengthBucket as SentenceLengthBucket, type text_SentenceLengthDistribution as SentenceLengthDistribution, type text_SlugSeparator as SlugSeparator, type text_StringDistanceMode as StringDistanceMode, type text_StringDistanceResult as StringDistanceResult, type text_TableOptions as TableOptions, type text_TextAnalysis as TextAnalysis, type text_WordCountResult as WordCountResult, text_addBorder as addBorder, text_analyzeSentenceLengths as analyzeSentenceLengths, text_analyzeText as analyzeText, text_applyOp as applyOp, text_applyOps as applyOps, text_calculateStringDistance as calculateStringDistance, text_centerText as centerText, text_convertAll as convertAll, text_convertCase as convertCase, text_countWords as countWords, text_csvToHtml as csvToHtml, text_csvToMarkdown as csvToMarkdown, text_detectDelimiter as detectDelimiter, text_detectFillerWords as detectFillerWords, text_detectPassiveVoice as detectPassiveVoice, text_diffLines as diffLines, text_diffLinesSimple as diffLinesSimple, text_diffStats as diffStats, text_escapeAll as escapeAll, text_escapeString as escapeString, text_extractHeadings as extractHeadings, text_formatReadingTime as formatReadingTime, text_generate as generate, text_generateDiff as generateDiff, text_generateHtmlTable as generateHtmlTable, text_generateMarkdownTable as generateMarkdownTable, text_generateParagraphs as generateParagraphs, text_generateSentences as generateSentences, text_generateWords as generateWords, text_getAvailableFonts as getAvailableFonts, text_getEmojiByCategory as getEmojiByCategory, text_getEmojiByChar as getEmojiByChar, text_getEmojiByShortcode as getEmojiByShortcode, text_getEmojiCategories as getEmojiCategories, text_getMorseForChar as getMorseForChar, text_getMorseTiming as getMorseTiming, text_htmlToMarkdown as htmlToMarkdown, text_isValidMorse as isValidMorse, text_markdownToHtml as markdownToHtml, text_morseToText as morseToText, text_numberToOrdinal as numberToOrdinal, text_numberToRoman as numberToRoman, text_numberToWords as numberToWords, text_ordinalWords as ordinalWords, text_parseDiff as parseDiff, text_parseTableData as parseTableData, text_readabilityScore as readabilityScore, text_renderMarkdown as renderMarkdown, text_romanToNumber as romanToNumber, text_scoreReadability as scoreReadability, text_searchEmoji as searchEmoji, text_sentenceCount as sentenceCount, text_slugify as slugify, text_slugifyAll as slugifyAll, text_syllableCount as syllableCount, text_textToAscii as textToAscii, text_textToMorse as textToMorse, text_unescapeString as unescapeString, text_wordFrequency as wordFrequency };
518
+ export { type text_AsciiFont as AsciiFont, type text_AsciiOptions as AsciiOptions, text_CASE_FORMATS as CASE_FORMATS, type text_CaseFormat as CaseFormat, type text_ConvertOptions as ConvertOptions, text_DEFAULT_CONVERT_OPTIONS as DEFAULT_CONVERT_OPTIONS, type text_DiffFile as DiffFile, type text_DiffHunk as DiffHunk, type text_DiffLine as DiffLine, type text_DiffResult as DiffResult, type text_DiffType as DiffType, type text_DiffViewerLine as DiffViewerLine, text_EMOJI_TABLE as EMOJI_TABLE, text_ESCAPE_MODES as ESCAPE_MODES, type text_EmojiEntry as EmojiEntry, type text_EscapeMode as EscapeMode, type text_FillerCategory as FillerCategory, type text_FillerMatch as FillerMatch, type text_FillerWordResult as FillerWordResult, type text_KeywordDensityEntry as KeywordDensityEntry, type text_KeywordDensityOptions as KeywordDensityOptions, type text_KeywordDensityResult as KeywordDensityResult, text_LINE_OPS as LINE_OPS, type text_LineOp as LineOp, type text_LineType as LineType, type text_LoremUnit as LoremUnit, text_MORSE_CODE as MORSE_CODE, type text_MarkdownResult as MarkdownResult, type text_MorseOptions as MorseOptions, type text_ParsedDiff as ParsedDiff, type text_ParsedTable as ParsedTable, type text_PassiveVoiceMatch as PassiveVoiceMatch, type text_PassiveVoiceResult as PassiveVoiceResult, type text_PassiveVoiceSentence as PassiveVoiceSentence, type text_ReadabilityResult as ReadabilityResult, type text_ReadabilityScore as ReadabilityScore, type text_SentenceLengthBucket as SentenceLengthBucket, type text_SentenceLengthDistribution as SentenceLengthDistribution, type text_SlugSeparator as SlugSeparator, type text_StringDistanceMode as StringDistanceMode, type text_StringDistanceResult as StringDistanceResult, type text_TableOptions as TableOptions, type text_TextAnalysis as TextAnalysis, type text_WordCountResult as WordCountResult, text_addBorder as addBorder, text_analyzeKeywordDensity as analyzeKeywordDensity, text_analyzeSentenceLengths as analyzeSentenceLengths, text_analyzeText as analyzeText, text_applyOp as applyOp, text_applyOps as applyOps, text_calculateStringDistance as calculateStringDistance, text_centerText as centerText, text_convertAll as convertAll, text_convertCase as convertCase, text_countWords as countWords, text_csvToHtml as csvToHtml, text_csvToMarkdown as csvToMarkdown, text_detectDelimiter as detectDelimiter, text_detectFillerWords as detectFillerWords, text_detectPassiveVoice as detectPassiveVoice, text_diffLines as diffLines, text_diffLinesSimple as diffLinesSimple, text_diffStats as diffStats, text_escapeAll as escapeAll, text_escapeString as escapeString, text_extractHeadings as extractHeadings, text_formatReadingTime as formatReadingTime, text_generate as generate, text_generateDiff as generateDiff, text_generateHtmlTable as generateHtmlTable, text_generateMarkdownTable as generateMarkdownTable, text_generateParagraphs as generateParagraphs, text_generateSentences as generateSentences, text_generateWords as generateWords, text_getAvailableFonts as getAvailableFonts, text_getEmojiByCategory as getEmojiByCategory, text_getEmojiByChar as getEmojiByChar, text_getEmojiByShortcode as getEmojiByShortcode, text_getEmojiCategories as getEmojiCategories, text_getMorseForChar as getMorseForChar, text_getMorseTiming as getMorseTiming, text_htmlToMarkdown as htmlToMarkdown, text_isValidMorse as isValidMorse, text_markdownToHtml as markdownToHtml, text_morseToText as morseToText, text_numberToOrdinal as numberToOrdinal, text_numberToRoman as numberToRoman, text_numberToWords as numberToWords, text_ordinalWords as ordinalWords, text_parseDiff as parseDiff, text_parseTableData as parseTableData, text_readabilityScore as readabilityScore, text_renderMarkdown as renderMarkdown, text_romanToNumber as romanToNumber, text_scoreReadability as scoreReadability, text_searchEmoji as searchEmoji, text_sentenceCount as sentenceCount, text_slugify as slugify, text_slugifyAll as slugifyAll, text_syllableCount as syllableCount, text_textToAscii as textToAscii, text_textToMorse as textToMorse, text_unescapeString as unescapeString, text_wordFrequency as wordFrequency };
487
519
  }
488
520
 
489
- export { csvToMarkdown as $, type AsciiFont as A, type SlugSeparator as B, CASE_FORMATS as C, DEFAULT_CONVERT_OPTIONS as D, EMOJI_TABLE as E, type FillerCategory as F, type StringDistanceMode as G, type StringDistanceResult as H, type TextAnalysis as I, addBorder as J, analyzeSentenceLengths as K, LINE_OPS as L, MORSE_CODE as M, analyzeText as N, applyOp as O, type ParsedDiff as P, applyOps as Q, type ReadabilityResult as R, type SentenceLengthBucket as S, type TableOptions as T, calculateStringDistance as U, centerText as V, type WordCountResult as W, convertAll as X, convertCase as Y, countWords as Z, csvToHtml as _, type AsciiOptions as a, detectDelimiter as a0, detectFillerWords as a1, detectPassiveVoice as a2, diffLines as a3, diffLinesSimple as a4, diffStats as a5, escapeAll as a6, escapeString as a7, extractHeadings as a8, formatReadingTime as a9, romanToNumber as aA, scoreReadability as aB, searchEmoji as aC, sentenceCount as aD, slugify as aE, slugifyAll as aF, syllableCount as aG, textToAscii as aH, textToMorse as aI, unescapeString as aJ, wordFrequency as aK, generate as aa, generateDiff as ab, generateHtmlTable as ac, generateMarkdownTable as ad, generateParagraphs as ae, generateSentences as af, generateWords as ag, getAvailableFonts as ah, getEmojiByCategory as ai, getEmojiByChar as aj, getEmojiByShortcode as ak, getEmojiCategories as al, getMorseForChar as am, getMorseTiming as an, htmlToMarkdown as ao, isValidMorse as ap, markdownToHtml as aq, morseToText as ar, numberToOrdinal as as, numberToRoman as at, numberToWords as au, ordinalWords as av, parseDiff as aw, parseTableData as ax, readabilityScore as ay, renderMarkdown as az, type CaseFormat as b, type ConvertOptions as c, type DiffFile as d, type DiffHunk as e, type DiffLine as f, type DiffResult as g, type DiffType as h, type DiffViewerLine as i, ESCAPE_MODES as j, type EmojiEntry as k, type EscapeMode as l, type FillerMatch as m, type FillerWordResult as n, type LineOp as o, type LineType as p, type LoremUnit as q, type MarkdownResult as r, type MorseOptions as s, text as t, type ParsedTable as u, type PassiveVoiceMatch as v, type PassiveVoiceResult as w, type PassiveVoiceSentence as x, type ReadabilityScore as y, type SentenceLengthDistribution as z };
521
+ export { convertAll as $, type AsciiFont as A, type ReadabilityScore as B, CASE_FORMATS as C, DEFAULT_CONVERT_OPTIONS as D, EMOJI_TABLE as E, type FillerCategory as F, type SentenceLengthDistribution as G, type SlugSeparator as H, type StringDistanceMode as I, type StringDistanceResult as J, type KeywordDensityEntry as K, LINE_OPS as L, MORSE_CODE as M, type TextAnalysis as N, addBorder as O, type ParsedDiff as P, analyzeKeywordDensity as Q, type ReadabilityResult as R, type SentenceLengthBucket as S, type TableOptions as T, analyzeSentenceLengths as U, analyzeText as V, type WordCountResult as W, applyOp as X, applyOps as Y, calculateStringDistance as Z, centerText as _, type AsciiOptions as a, convertCase as a0, countWords as a1, csvToHtml as a2, csvToMarkdown as a3, detectDelimiter as a4, detectFillerWords as a5, detectPassiveVoice as a6, diffLines as a7, diffLinesSimple as a8, diffStats as a9, parseDiff as aA, parseTableData as aB, readabilityScore as aC, renderMarkdown as aD, romanToNumber as aE, scoreReadability as aF, searchEmoji as aG, sentenceCount as aH, slugify as aI, slugifyAll as aJ, syllableCount as aK, textToAscii as aL, textToMorse as aM, unescapeString as aN, wordFrequency as aO, escapeAll as aa, escapeString as ab, extractHeadings as ac, formatReadingTime as ad, generate as ae, generateDiff as af, generateHtmlTable as ag, generateMarkdownTable as ah, generateParagraphs as ai, generateSentences as aj, generateWords as ak, getAvailableFonts as al, getEmojiByCategory as am, getEmojiByChar as an, getEmojiByShortcode as ao, getEmojiCategories as ap, getMorseForChar as aq, getMorseTiming as ar, htmlToMarkdown as as, isValidMorse as at, markdownToHtml as au, morseToText as av, numberToOrdinal as aw, numberToRoman as ax, numberToWords as ay, ordinalWords as az, type CaseFormat as b, type ConvertOptions as c, type DiffFile as d, type DiffHunk as e, type DiffLine as f, type DiffResult as g, type DiffType as h, type DiffViewerLine as i, ESCAPE_MODES as j, type EmojiEntry as k, type EscapeMode as l, type FillerMatch as m, type FillerWordResult as n, type KeywordDensityOptions as o, type KeywordDensityResult as p, type LineOp as q, type LineType as r, type LoremUnit as s, text as t, type MarkdownResult as u, type MorseOptions as v, type ParsedTable as w, type PassiveVoiceMatch as x, type PassiveVoiceResult as y, type PassiveVoiceSentence as z };