@utilix-tech/sdk 0.23.0 → 0.25.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.
@@ -18,6 +18,7 @@
18
18
  * - html-table : detectDelimiter, parseTableData, generateHtmlTable, generateMarkdownTable, csvToHtml, csvToMarkdown
19
19
  * - ascii-art : textToAscii, getAvailableFonts, addBorder, centerText
20
20
  * - morse-code : textToMorse, morseToText, isValidMorse, getMorseForChar, getMorseTiming
21
+ * - string-distance : calculateStringDistance
21
22
  * - passive-voice-detector: detectPassiveVoice
22
23
  * - readability-score: scoreReadability
23
24
  * - filler-word-detector: detectFillerWords
@@ -302,6 +303,30 @@ interface FillerWordResult {
302
303
  * candidate to reconsider, not always wrong in context.
303
304
  */
304
305
  declare function detectFillerWords(text: string): FillerWordResult;
306
+ type StringDistanceMode = 'levenshtein' | 'damerau';
307
+ interface StringDistanceResult {
308
+ a: string;
309
+ b: string;
310
+ distance: number;
311
+ similarity: number;
312
+ maxLength: number;
313
+ mode: StringDistanceMode;
314
+ }
315
+ /**
316
+ * Compute the edit distance between two strings: the minimum number of
317
+ * single-character insertions, deletions, and substitutions (plus adjacent
318
+ * transpositions in "damerau" mode) needed to turn `a` into `b`. "damerau"
319
+ * mode is the optimal-string-alignment variant (each substring edited at
320
+ * most once), not unrestricted Damerau-Levenshtein. Also returns a
321
+ * normalized 0-1 similarity ratio. Classic O(n*m) dynamic programming, pure
322
+ * string comparison with no external dependency.
323
+ */
324
+ declare function calculateStringDistance(a: string, b: string, options?: {
325
+ mode?: StringDistanceMode;
326
+ caseSensitive?: boolean;
327
+ }): StringDistanceResult | {
328
+ error: string;
329
+ };
305
330
 
306
331
  type text_AsciiFont = AsciiFont;
307
332
  type text_AsciiOptions = AsciiOptions;
@@ -335,6 +360,8 @@ type text_PassiveVoiceSentence = PassiveVoiceSentence;
335
360
  type text_ReadabilityResult = ReadabilityResult;
336
361
  type text_ReadabilityScore = ReadabilityScore;
337
362
  type text_SlugSeparator = SlugSeparator;
363
+ type text_StringDistanceMode = StringDistanceMode;
364
+ type text_StringDistanceResult = StringDistanceResult;
338
365
  type text_TableOptions = TableOptions;
339
366
  type text_TextAnalysis = TextAnalysis;
340
367
  type text_WordCountResult = WordCountResult;
@@ -342,6 +369,7 @@ declare const text_addBorder: typeof addBorder;
342
369
  declare const text_analyzeText: typeof analyzeText;
343
370
  declare const text_applyOp: typeof applyOp;
344
371
  declare const text_applyOps: typeof applyOps;
372
+ declare const text_calculateStringDistance: typeof calculateStringDistance;
345
373
  declare const text_centerText: typeof centerText;
346
374
  declare const text_convertAll: typeof convertAll;
347
375
  declare const text_convertCase: typeof convertCase;
@@ -391,7 +419,7 @@ declare const text_textToMorse: typeof textToMorse;
391
419
  declare const text_unescapeString: typeof unescapeString;
392
420
  declare const text_wordFrequency: typeof wordFrequency;
393
421
  declare namespace text {
394
- 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_ESCAPE_MODES as ESCAPE_MODES, 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_SlugSeparator as SlugSeparator, type text_TableOptions as TableOptions, type text_TextAnalysis as TextAnalysis, type text_WordCountResult as WordCountResult, text_addBorder as addBorder, text_analyzeText as analyzeText, text_applyOp as applyOp, text_applyOps as applyOps, 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_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_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 };
422
+ 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_ESCAPE_MODES as ESCAPE_MODES, 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_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_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_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_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 };
395
423
  }
396
424
 
397
- export { escapeString as $, type AsciiFont as A, applyOp as B, CASE_FORMATS as C, DEFAULT_CONVERT_OPTIONS as D, ESCAPE_MODES as E, type FillerCategory as F, applyOps as G, centerText as H, convertAll as I, convertCase as J, countWords as K, LINE_OPS as L, MORSE_CODE as M, csvToHtml as N, csvToMarkdown as O, type ParsedDiff as P, detectDelimiter as Q, type ReadabilityResult as R, type SlugSeparator as S, type TableOptions as T, detectFillerWords as U, detectPassiveVoice as V, type WordCountResult as W, diffLines as X, diffLinesSimple as Y, diffStats as Z, escapeAll as _, type AsciiOptions as a, extractHeadings as a0, formatReadingTime as a1, generate as a2, generateDiff as a3, generateHtmlTable as a4, generateMarkdownTable as a5, generateParagraphs as a6, generateSentences as a7, generateWords as a8, getAvailableFonts as a9, getMorseForChar as aa, getMorseTiming as ab, htmlToMarkdown as ac, isValidMorse as ad, markdownToHtml as ae, morseToText as af, numberToOrdinal as ag, numberToRoman as ah, numberToWords as ai, ordinalWords as aj, parseDiff as ak, parseTableData as al, readabilityScore as am, renderMarkdown as an, romanToNumber as ao, scoreReadability as ap, sentenceCount as aq, slugify as ar, slugifyAll as as, syllableCount as at, textToAscii as au, textToMorse as av, unescapeString as aw, wordFrequency as ax, 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, type EscapeMode as j, type FillerMatch as k, type FillerWordResult as l, type LineOp as m, type LineType as n, type LoremUnit as o, type MarkdownResult as p, type MorseOptions as q, type ParsedTable as r, type PassiveVoiceMatch as s, text as t, type PassiveVoiceResult as u, type PassiveVoiceSentence as v, type ReadabilityScore as w, type TextAnalysis as x, addBorder as y, analyzeText as z };
425
+ export { diffLinesSimple as $, type AsciiFont as A, addBorder as B, CASE_FORMATS as C, DEFAULT_CONVERT_OPTIONS as D, ESCAPE_MODES as E, type FillerCategory as F, analyzeText as G, applyOp as H, applyOps as I, calculateStringDistance as J, centerText as K, LINE_OPS as L, MORSE_CODE as M, convertAll as N, convertCase as O, type ParsedDiff as P, countWords as Q, type ReadabilityResult as R, type SlugSeparator as S, type TableOptions as T, csvToHtml as U, csvToMarkdown as V, type WordCountResult as W, detectDelimiter as X, detectFillerWords as Y, detectPassiveVoice as Z, diffLines as _, type AsciiOptions as a, diffStats as a0, escapeAll as a1, escapeString as a2, extractHeadings as a3, formatReadingTime as a4, generate as a5, generateDiff as a6, generateHtmlTable as a7, generateMarkdownTable as a8, generateParagraphs as a9, wordFrequency as aA, generateSentences as aa, generateWords as ab, getAvailableFonts as ac, getMorseForChar as ad, getMorseTiming as ae, htmlToMarkdown as af, isValidMorse as ag, markdownToHtml as ah, morseToText as ai, numberToOrdinal as aj, numberToRoman as ak, numberToWords as al, ordinalWords as am, parseDiff as an, parseTableData as ao, readabilityScore as ap, renderMarkdown as aq, romanToNumber as ar, scoreReadability as as, sentenceCount as at, slugify as au, slugifyAll as av, syllableCount as aw, textToAscii as ax, textToMorse as ay, unescapeString 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, type EscapeMode as j, type FillerMatch as k, type FillerWordResult as l, type LineOp as m, type LineType as n, type LoremUnit as o, type MarkdownResult as p, type MorseOptions as q, type ParsedTable as r, type PassiveVoiceMatch as s, text as t, type PassiveVoiceResult as u, type PassiveVoiceSentence as v, type ReadabilityScore as w, type StringDistanceMode as x, type StringDistanceResult as y, type TextAnalysis as z };
@@ -18,6 +18,7 @@
18
18
  * - html-table : detectDelimiter, parseTableData, generateHtmlTable, generateMarkdownTable, csvToHtml, csvToMarkdown
19
19
  * - ascii-art : textToAscii, getAvailableFonts, addBorder, centerText
20
20
  * - morse-code : textToMorse, morseToText, isValidMorse, getMorseForChar, getMorseTiming
21
+ * - string-distance : calculateStringDistance
21
22
  * - passive-voice-detector: detectPassiveVoice
22
23
  * - readability-score: scoreReadability
23
24
  * - filler-word-detector: detectFillerWords
@@ -302,6 +303,30 @@ interface FillerWordResult {
302
303
  * candidate to reconsider, not always wrong in context.
303
304
  */
304
305
  declare function detectFillerWords(text: string): FillerWordResult;
306
+ type StringDistanceMode = 'levenshtein' | 'damerau';
307
+ interface StringDistanceResult {
308
+ a: string;
309
+ b: string;
310
+ distance: number;
311
+ similarity: number;
312
+ maxLength: number;
313
+ mode: StringDistanceMode;
314
+ }
315
+ /**
316
+ * Compute the edit distance between two strings: the minimum number of
317
+ * single-character insertions, deletions, and substitutions (plus adjacent
318
+ * transpositions in "damerau" mode) needed to turn `a` into `b`. "damerau"
319
+ * mode is the optimal-string-alignment variant (each substring edited at
320
+ * most once), not unrestricted Damerau-Levenshtein. Also returns a
321
+ * normalized 0-1 similarity ratio. Classic O(n*m) dynamic programming, pure
322
+ * string comparison with no external dependency.
323
+ */
324
+ declare function calculateStringDistance(a: string, b: string, options?: {
325
+ mode?: StringDistanceMode;
326
+ caseSensitive?: boolean;
327
+ }): StringDistanceResult | {
328
+ error: string;
329
+ };
305
330
 
306
331
  type text_AsciiFont = AsciiFont;
307
332
  type text_AsciiOptions = AsciiOptions;
@@ -335,6 +360,8 @@ type text_PassiveVoiceSentence = PassiveVoiceSentence;
335
360
  type text_ReadabilityResult = ReadabilityResult;
336
361
  type text_ReadabilityScore = ReadabilityScore;
337
362
  type text_SlugSeparator = SlugSeparator;
363
+ type text_StringDistanceMode = StringDistanceMode;
364
+ type text_StringDistanceResult = StringDistanceResult;
338
365
  type text_TableOptions = TableOptions;
339
366
  type text_TextAnalysis = TextAnalysis;
340
367
  type text_WordCountResult = WordCountResult;
@@ -342,6 +369,7 @@ declare const text_addBorder: typeof addBorder;
342
369
  declare const text_analyzeText: typeof analyzeText;
343
370
  declare const text_applyOp: typeof applyOp;
344
371
  declare const text_applyOps: typeof applyOps;
372
+ declare const text_calculateStringDistance: typeof calculateStringDistance;
345
373
  declare const text_centerText: typeof centerText;
346
374
  declare const text_convertAll: typeof convertAll;
347
375
  declare const text_convertCase: typeof convertCase;
@@ -391,7 +419,7 @@ declare const text_textToMorse: typeof textToMorse;
391
419
  declare const text_unescapeString: typeof unescapeString;
392
420
  declare const text_wordFrequency: typeof wordFrequency;
393
421
  declare namespace text {
394
- 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_ESCAPE_MODES as ESCAPE_MODES, 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_SlugSeparator as SlugSeparator, type text_TableOptions as TableOptions, type text_TextAnalysis as TextAnalysis, type text_WordCountResult as WordCountResult, text_addBorder as addBorder, text_analyzeText as analyzeText, text_applyOp as applyOp, text_applyOps as applyOps, 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_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_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 };
422
+ 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_ESCAPE_MODES as ESCAPE_MODES, 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_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_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_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_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 };
395
423
  }
396
424
 
397
- export { escapeString as $, type AsciiFont as A, applyOp as B, CASE_FORMATS as C, DEFAULT_CONVERT_OPTIONS as D, ESCAPE_MODES as E, type FillerCategory as F, applyOps as G, centerText as H, convertAll as I, convertCase as J, countWords as K, LINE_OPS as L, MORSE_CODE as M, csvToHtml as N, csvToMarkdown as O, type ParsedDiff as P, detectDelimiter as Q, type ReadabilityResult as R, type SlugSeparator as S, type TableOptions as T, detectFillerWords as U, detectPassiveVoice as V, type WordCountResult as W, diffLines as X, diffLinesSimple as Y, diffStats as Z, escapeAll as _, type AsciiOptions as a, extractHeadings as a0, formatReadingTime as a1, generate as a2, generateDiff as a3, generateHtmlTable as a4, generateMarkdownTable as a5, generateParagraphs as a6, generateSentences as a7, generateWords as a8, getAvailableFonts as a9, getMorseForChar as aa, getMorseTiming as ab, htmlToMarkdown as ac, isValidMorse as ad, markdownToHtml as ae, morseToText as af, numberToOrdinal as ag, numberToRoman as ah, numberToWords as ai, ordinalWords as aj, parseDiff as ak, parseTableData as al, readabilityScore as am, renderMarkdown as an, romanToNumber as ao, scoreReadability as ap, sentenceCount as aq, slugify as ar, slugifyAll as as, syllableCount as at, textToAscii as au, textToMorse as av, unescapeString as aw, wordFrequency as ax, 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, type EscapeMode as j, type FillerMatch as k, type FillerWordResult as l, type LineOp as m, type LineType as n, type LoremUnit as o, type MarkdownResult as p, type MorseOptions as q, type ParsedTable as r, type PassiveVoiceMatch as s, text as t, type PassiveVoiceResult as u, type PassiveVoiceSentence as v, type ReadabilityScore as w, type TextAnalysis as x, addBorder as y, analyzeText as z };
425
+ export { diffLinesSimple as $, type AsciiFont as A, addBorder as B, CASE_FORMATS as C, DEFAULT_CONVERT_OPTIONS as D, ESCAPE_MODES as E, type FillerCategory as F, analyzeText as G, applyOp as H, applyOps as I, calculateStringDistance as J, centerText as K, LINE_OPS as L, MORSE_CODE as M, convertAll as N, convertCase as O, type ParsedDiff as P, countWords as Q, type ReadabilityResult as R, type SlugSeparator as S, type TableOptions as T, csvToHtml as U, csvToMarkdown as V, type WordCountResult as W, detectDelimiter as X, detectFillerWords as Y, detectPassiveVoice as Z, diffLines as _, type AsciiOptions as a, diffStats as a0, escapeAll as a1, escapeString as a2, extractHeadings as a3, formatReadingTime as a4, generate as a5, generateDiff as a6, generateHtmlTable as a7, generateMarkdownTable as a8, generateParagraphs as a9, wordFrequency as aA, generateSentences as aa, generateWords as ab, getAvailableFonts as ac, getMorseForChar as ad, getMorseTiming as ae, htmlToMarkdown as af, isValidMorse as ag, markdownToHtml as ah, morseToText as ai, numberToOrdinal as aj, numberToRoman as ak, numberToWords as al, ordinalWords as am, parseDiff as an, parseTableData as ao, readabilityScore as ap, renderMarkdown as aq, romanToNumber as ar, scoreReadability as as, sentenceCount as at, slugify as au, slugifyAll as av, syllableCount as aw, textToAscii as ax, textToMorse as ay, unescapeString 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, type EscapeMode as j, type FillerMatch as k, type FillerWordResult as l, type LineOp as m, type LineType as n, type LoremUnit as o, type MarkdownResult as p, type MorseOptions as q, type ParsedTable as r, type PassiveVoiceMatch as s, text as t, type PassiveVoiceResult as u, type PassiveVoiceSentence as v, type ReadabilityScore as w, type StringDistanceMode as x, type StringDistanceResult as y, type TextAnalysis as z };
@@ -1139,13 +1139,186 @@ function jsonArrayToNdjson(input) {
1139
1139
  if (!Array.isArray(parsed)) return { error: "Input must be a JSON array" };
1140
1140
  return parsed.map((item) => JSON.stringify(item)).join("\n");
1141
1141
  }
1142
+ var _SUBTITLE_TIMESTAMP_RE = /(\d+):(\d{1,2}):(\d{1,2})[.,](\d{1,3})|(\d{1,3}):(\d{1,2})[.,](\d{1,3})/;
1143
+ var _VTT_BLOCK_KEYWORDS = ["NOTE", "STYLE", "REGION"];
1144
+ function parseSubtitleTimestamp(raw) {
1145
+ const m = _SUBTITLE_TIMESTAMP_RE.exec(raw.trim());
1146
+ if (!m || m.index !== 0) return null;
1147
+ let hours;
1148
+ let minutes;
1149
+ let seconds;
1150
+ let millis;
1151
+ if (m[1] !== void 0) {
1152
+ hours = Number(m[1]);
1153
+ minutes = Number(m[2]);
1154
+ seconds = Number(m[3]);
1155
+ millis = m[4];
1156
+ } else {
1157
+ hours = 0;
1158
+ minutes = Number(m[5]);
1159
+ seconds = Number(m[6]);
1160
+ millis = m[7];
1161
+ }
1162
+ if (minutes > 59 || seconds > 59) return null;
1163
+ return hours * 3600 + minutes * 60 + seconds + Number(millis.padEnd(3, "0")) / 1e3;
1164
+ }
1165
+ function formatSubtitleTimestamp(totalSeconds, format) {
1166
+ const totalMs = Math.round(Math.max(0, totalSeconds) * 1e3);
1167
+ const ms = totalMs % 1e3;
1168
+ const totalSecs = Math.floor(totalMs / 1e3);
1169
+ const pad = (n, width = 2) => String(n).padStart(width, "0");
1170
+ return `${pad(Math.floor(totalSecs / 3600))}:${pad(Math.floor(totalSecs / 60) % 60)}:${pad(totalSecs % 60)}${format === "srt" ? "," : "."}${pad(ms, 3)}`;
1171
+ }
1172
+ function _stripBom(input) {
1173
+ return input.charCodeAt(0) === 65279 ? input.slice(1) : input;
1174
+ }
1175
+ function detectSubtitleFormat(input) {
1176
+ const text = _stripBom(input).trimStart();
1177
+ if (/^WEBVTT/.test(text)) return "vtt";
1178
+ const arrow = /(\d{1,3}):(\d{1,2})(?::(\d{1,2}))?([.,])(\d{1,3})\s*-->/.exec(text);
1179
+ if (arrow && arrow[4] === ".") return "vtt";
1180
+ return "srt";
1181
+ }
1182
+ function parseSubtitles(input, format) {
1183
+ if (typeof input !== "string" || input.trim().length === 0) {
1184
+ return { error: "Subtitle input is empty" };
1185
+ }
1186
+ const sourceFormat = format ?? detectSubtitleFormat(input);
1187
+ const normalised = _stripBom(input).replace(/\r\n?/g, "\n");
1188
+ const warnings = [];
1189
+ let body = normalised;
1190
+ if (sourceFormat === "vtt") {
1191
+ const headerMatch = /^WEBVTT[^\n]*\n?/.exec(body.trimStart());
1192
+ if (headerMatch) {
1193
+ body = body.trimStart().slice(headerMatch[0].length);
1194
+ } else {
1195
+ warnings.push('WebVTT input is missing its "WEBVTT" header line');
1196
+ }
1197
+ }
1198
+ const blocks = body.split(/\n[ \t]*\n+/).map((b) => b.trim()).filter((b) => b.length > 0);
1199
+ const cues = [];
1200
+ for (const block of blocks) {
1201
+ const lines = block.split("\n");
1202
+ const arrowIdx = lines.findIndex((l) => l.includes("-->"));
1203
+ if (arrowIdx === -1) {
1204
+ const keyword = _VTT_BLOCK_KEYWORDS.find((k) => lines[0] === k || lines[0].startsWith(`${k} `));
1205
+ if (sourceFormat === "vtt" && keyword) {
1206
+ warnings.push(`Dropped a WebVTT ${keyword} block, which has no SRT equivalent`);
1207
+ } else {
1208
+ warnings.push(`Skipped a block with no "-->" timing line: ${JSON.stringify(lines[0].slice(0, 40))}`);
1209
+ }
1210
+ continue;
1211
+ }
1212
+ const timingLine = lines[arrowIdx];
1213
+ const parts = timingLine.split("-->");
1214
+ const start = parseSubtitleTimestamp(parts[0] ?? "");
1215
+ const rightTrimmed = (parts[1] ?? "").trim();
1216
+ const end = parseSubtitleTimestamp(rightTrimmed);
1217
+ if (start === null || end === null) {
1218
+ warnings.push(`Skipped a cue with an unparseable timing line: ${JSON.stringify(timingLine.slice(0, 60))}`);
1219
+ continue;
1220
+ }
1221
+ const endMatch = _SUBTITLE_TIMESTAMP_RE.exec(rightTrimmed);
1222
+ const settings = endMatch ? rightTrimmed.slice(endMatch[0].length).trim() : "";
1223
+ const idLines = lines.slice(0, arrowIdx).filter((l) => l.trim().length > 0);
1224
+ const text = lines.slice(arrowIdx + 1).join("\n").trim();
1225
+ const cue = { index: cues.length + 1, start, end, text };
1226
+ if (sourceFormat === "vtt" && idLines.length > 0) cue.id = idLines[idLines.length - 1].trim();
1227
+ if (settings.length > 0) cue.settings = settings;
1228
+ if (end < start) warnings.push(`Cue ${cue.index} ends before it starts`);
1229
+ if (text.length === 0) warnings.push(`Cue ${cue.index} has no text`);
1230
+ if (cues.length > 0 && start < cues[cues.length - 1].end) {
1231
+ warnings.push(`Cue ${cue.index} starts before cue ${cue.index - 1} ends (overlapping cues)`);
1232
+ }
1233
+ cues.push(cue);
1234
+ }
1235
+ if (cues.length === 0) {
1236
+ return { error: "No subtitle cues found: check that the input is a valid SRT or WebVTT file" };
1237
+ }
1238
+ return {
1239
+ format: sourceFormat,
1240
+ cues,
1241
+ cueCount: cues.length,
1242
+ duration: Math.round(Math.max(...cues.map((c) => c.end)) * 1e3) / 1e3,
1243
+ warnings
1244
+ };
1245
+ }
1246
+ function serializeSubtitles(cues, format) {
1247
+ const blocks = cues.map((cue, i) => {
1248
+ const time = `${formatSubtitleTimestamp(cue.start, format)} --> ${formatSubtitleTimestamp(cue.end, format)}`;
1249
+ if (format === "srt") return `${i + 1}
1250
+ ${time}
1251
+ ${cue.text}`;
1252
+ const timing = cue.settings ? `${time} ${cue.settings}` : time;
1253
+ return cue.id ? `${cue.id}
1254
+ ${timing}
1255
+ ${cue.text}` : `${timing}
1256
+ ${cue.text}`;
1257
+ });
1258
+ const body = blocks.join("\n\n");
1259
+ return format === "vtt" ? `WEBVTT
1260
+
1261
+ ${body}
1262
+ ` : `${body}
1263
+ `;
1264
+ }
1265
+ function convertSubtitles(input, target, sourceFormat) {
1266
+ if (target !== "srt" && target !== "vtt") return { error: 'target must be "srt" or "vtt"' };
1267
+ const parsed = parseSubtitles(input, sourceFormat);
1268
+ if ("error" in parsed) return parsed;
1269
+ const warnings = [...parsed.warnings];
1270
+ if (target === "srt") {
1271
+ const droppedSettings = parsed.cues.filter((c) => c.settings).length;
1272
+ const droppedIds = parsed.cues.filter((c) => c.id).length;
1273
+ if (droppedSettings > 0) {
1274
+ warnings.push(`Dropped WebVTT cue settings on ${droppedSettings} cue(s): SRT has no equivalent`);
1275
+ }
1276
+ if (droppedIds > 0) {
1277
+ warnings.push(`Dropped ${droppedIds} WebVTT cue identifier(s): SRT numbers cues sequentially instead`);
1278
+ }
1279
+ }
1280
+ return {
1281
+ format: target,
1282
+ sourceFormat: parsed.format,
1283
+ output: serializeSubtitles(parsed.cues, target),
1284
+ cueCount: parsed.cueCount,
1285
+ duration: parsed.duration,
1286
+ warnings
1287
+ };
1288
+ }
1289
+ function shiftSubtitles(input, offsetSeconds, target) {
1290
+ if (!Number.isFinite(offsetSeconds)) return { error: "offsetSeconds must be a finite number" };
1291
+ const parsed = parseSubtitles(input);
1292
+ if ("error" in parsed) return parsed;
1293
+ const warnings = [...parsed.warnings];
1294
+ let clamped = 0;
1295
+ const shifted = parsed.cues.map((cue) => {
1296
+ const start = cue.start + offsetSeconds;
1297
+ const end = cue.end + offsetSeconds;
1298
+ if (start < 0) clamped += 1;
1299
+ return { ...cue, start: Math.max(0, start), end: Math.max(0, end) };
1300
+ });
1301
+ if (clamped > 0) warnings.push(`${clamped} cue(s) would start before zero and were clamped to 00:00:00`);
1302
+ const outFormat = target ?? parsed.format;
1303
+ return {
1304
+ format: outFormat,
1305
+ sourceFormat: parsed.format,
1306
+ output: serializeSubtitles(shifted, outFormat),
1307
+ cueCount: shifted.length,
1308
+ duration: Math.round(Math.max(...shifted.map((c) => c.end)) * 1e3) / 1e3,
1309
+ warnings
1310
+ };
1311
+ }
1142
1312
 
1313
+ exports.convertSubtitles = convertSubtitles;
1143
1314
  exports.csvToJson = csvToJson;
1144
1315
  exports.detectDelimiter = detectDelimiter;
1316
+ exports.detectSubtitleFormat = detectSubtitleFormat;
1145
1317
  exports.diffEnvExample = diffEnvExample;
1146
1318
  exports.envToExport = envToExport;
1147
1319
  exports.envToJson = envToJson;
1148
1320
  exports.formatNdjson = formatNdjson;
1321
+ exports.formatSubtitleTimestamp = formatSubtitleTimestamp;
1149
1322
  exports.formatToml = formatToml;
1150
1323
  exports.formatXml = formatXml;
1151
1324
  exports.getSection = getSection;
@@ -1165,7 +1338,11 @@ exports.ndjsonToJsonArray = ndjsonToJsonArray;
1165
1338
  exports.parseCsv = parseCsv;
1166
1339
  exports.parseEnv = parseEnv;
1167
1340
  exports.parseIni = parseIni;
1341
+ exports.parseSubtitleTimestamp = parseSubtitleTimestamp;
1342
+ exports.parseSubtitles = parseSubtitles;
1168
1343
  exports.parseXmlToObject = parseXmlToObject;
1344
+ exports.serializeSubtitles = serializeSubtitles;
1345
+ exports.shiftSubtitles = shiftSubtitles;
1169
1346
  exports.stringifyIni = stringifyIni;
1170
1347
  exports.toCsvString = toCsvString;
1171
1348
  exports.tomlToJson = tomlToJson;
@@ -1 +1 @@
1
- export { C as CsvParseResult, E as EnvDiffError, a as EnvDiffResult, b as EnvEntry, c as EnvParseResult, I as IniSection, N as NdjsonLineResult, e as NdjsonValidateResult, P as ParseOptions, f as ParsedIni, T as TomlFormatResult, V as ValidationResult, X as XmlFormatResult, g as XmlToJsonOptions, h as csvToJson, i as detectDelimiter, j as diffEnvExample, k as envToExport, l as envToJson, m as formatNdjson, n as formatToml, o as formatXml, p as getSection, q as getSectionNames, r as getTomlStats, s as getXmlStats, t as getYamlStats, u as iniToJson, v as jsonArrayToNdjson, w as jsonToIni, x as jsonToToml, y as jsonToXml, z as minifyNdjson, A as minifyToml, B as minifyXml, D as ndjsonToJsonArray, F as parseCsv, G as parseEnv, H as parseIni, J as parseXmlToObject, K as stringifyIni, L as toCsvString, M as tomlToJson, O as validateEnvKey, Q as validateIni, R as validateNdjson, S as validateToml, U as validateXml, W as validateYaml, Y as xmlToJson } from '../data-D8XTI7Du.cjs';
1
+ export { C as ConvertedSubtitles, a as CsvParseResult, E as EnvDiffError, b as EnvDiffResult, c as EnvEntry, e as EnvParseResult, I as IniSection, N as NdjsonLineResult, f as NdjsonValidateResult, P as ParseOptions, g as ParsedIni, h as ParsedSubtitles, S as SubtitleCue, i as SubtitleFormat, T as TomlFormatResult, V as ValidationResult, X as XmlFormatResult, j as XmlToJsonOptions, k as convertSubtitles, l as csvToJson, m as detectDelimiter, n as detectSubtitleFormat, o as diffEnvExample, p as envToExport, q as envToJson, r as formatNdjson, s as formatSubtitleTimestamp, t as formatToml, u as formatXml, v as getSection, w as getSectionNames, x as getTomlStats, y as getXmlStats, z as getYamlStats, A as iniToJson, B as jsonArrayToNdjson, D as jsonToIni, F as jsonToToml, G as jsonToXml, H as minifyNdjson, J as minifyToml, K as minifyXml, L as ndjsonToJsonArray, M as parseCsv, O as parseEnv, Q as parseIni, R as parseSubtitleTimestamp, U as parseSubtitles, W as parseXmlToObject, Y as serializeSubtitles, Z as shiftSubtitles, _ as stringifyIni, $ as toCsvString, a0 as tomlToJson, a1 as validateEnvKey, a2 as validateIni, a3 as validateNdjson, a4 as validateToml, a5 as validateXml, a6 as validateYaml, a7 as xmlToJson } from '../data-XRb0D7Zn.cjs';
@@ -1 +1 @@
1
- export { C as CsvParseResult, E as EnvDiffError, a as EnvDiffResult, b as EnvEntry, c as EnvParseResult, I as IniSection, N as NdjsonLineResult, e as NdjsonValidateResult, P as ParseOptions, f as ParsedIni, T as TomlFormatResult, V as ValidationResult, X as XmlFormatResult, g as XmlToJsonOptions, h as csvToJson, i as detectDelimiter, j as diffEnvExample, k as envToExport, l as envToJson, m as formatNdjson, n as formatToml, o as formatXml, p as getSection, q as getSectionNames, r as getTomlStats, s as getXmlStats, t as getYamlStats, u as iniToJson, v as jsonArrayToNdjson, w as jsonToIni, x as jsonToToml, y as jsonToXml, z as minifyNdjson, A as minifyToml, B as minifyXml, D as ndjsonToJsonArray, F as parseCsv, G as parseEnv, H as parseIni, J as parseXmlToObject, K as stringifyIni, L as toCsvString, M as tomlToJson, O as validateEnvKey, Q as validateIni, R as validateNdjson, S as validateToml, U as validateXml, W as validateYaml, Y as xmlToJson } from '../data-D8XTI7Du.js';
1
+ export { C as ConvertedSubtitles, a as CsvParseResult, E as EnvDiffError, b as EnvDiffResult, c as EnvEntry, e as EnvParseResult, I as IniSection, N as NdjsonLineResult, f as NdjsonValidateResult, P as ParseOptions, g as ParsedIni, h as ParsedSubtitles, S as SubtitleCue, i as SubtitleFormat, T as TomlFormatResult, V as ValidationResult, X as XmlFormatResult, j as XmlToJsonOptions, k as convertSubtitles, l as csvToJson, m as detectDelimiter, n as detectSubtitleFormat, o as diffEnvExample, p as envToExport, q as envToJson, r as formatNdjson, s as formatSubtitleTimestamp, t as formatToml, u as formatXml, v as getSection, w as getSectionNames, x as getTomlStats, y as getXmlStats, z as getYamlStats, A as iniToJson, B as jsonArrayToNdjson, D as jsonToIni, F as jsonToToml, G as jsonToXml, H as minifyNdjson, J as minifyToml, K as minifyXml, L as ndjsonToJsonArray, M as parseCsv, O as parseEnv, Q as parseIni, R as parseSubtitleTimestamp, U as parseSubtitles, W as parseXmlToObject, Y as serializeSubtitles, Z as shiftSubtitles, _ as stringifyIni, $ as toCsvString, a0 as tomlToJson, a1 as validateEnvKey, a2 as validateIni, a3 as validateNdjson, a4 as validateToml, a5 as validateXml, a6 as validateYaml, a7 as xmlToJson } from '../data-XRb0D7Zn.js';
@@ -1,2 +1,2 @@
1
- export { csvToJson, detectDelimiter, diffEnvExample, envToExport, envToJson, formatNdjson, formatToml, formatXml, getSection, getSectionNames, getTomlStats, getXmlStats, getYamlStats, iniToJson, jsonArrayToNdjson, jsonToIni, jsonToToml, jsonToXml, minifyNdjson, minifyToml, minifyXml, ndjsonToJsonArray, parseCsv, parseEnv, parseIni, parseXmlToObject, stringifyIni, toCsvString, tomlToJson, validateEnvKey, validateIni, validateNdjson, validateToml, validateXml, validateYaml, xmlToJson } from '../chunk-TINQFTLO.js';
1
+ export { convertSubtitles, csvToJson, detectDelimiter, detectSubtitleFormat, diffEnvExample, envToExport, envToJson, formatNdjson, formatSubtitleTimestamp, formatToml, formatXml, getSection, getSectionNames, getTomlStats, getXmlStats, getYamlStats, iniToJson, jsonArrayToNdjson, jsonToIni, jsonToToml, jsonToXml, minifyNdjson, minifyToml, minifyXml, ndjsonToJsonArray, parseCsv, parseEnv, parseIni, parseSubtitleTimestamp, parseSubtitles, parseXmlToObject, serializeSubtitles, shiftSubtitles, stringifyIni, toCsvString, tomlToJson, validateEnvKey, validateIni, validateNdjson, validateToml, validateXml, validateYaml, xmlToJson } from '../chunk-66QHV5KW.js';
2
2
  import '../chunk-MLKGABMK.js';
@@ -2497,6 +2497,47 @@ function detectFillerWords(text) {
2497
2497
  const density = totalWords > 0 ? Math.round(totalMatches / totalWords * 1e3) / 10 : 0;
2498
2498
  return { totalWords, totalMatches, fillerCount, hedgeCount, clicheCount, density, matches };
2499
2499
  }
2500
+ var MAX_STRING_DISTANCE_LENGTH = 5e3;
2501
+ function calculateStringDistance(a, b, options) {
2502
+ if (typeof a !== "string" || typeof b !== "string") {
2503
+ return { error: "Both a and b must be strings" };
2504
+ }
2505
+ if (a.length > MAX_STRING_DISTANCE_LENGTH || b.length > MAX_STRING_DISTANCE_LENGTH) {
2506
+ return { error: `Strings must be at most ${MAX_STRING_DISTANCE_LENGTH} characters` };
2507
+ }
2508
+ const mode = options?.mode ?? "levenshtein";
2509
+ const caseSensitive = options?.caseSensitive ?? true;
2510
+ const s1 = caseSensitive ? a : a.toLowerCase();
2511
+ const s2 = caseSensitive ? b : b.toLowerCase();
2512
+ const m = s1.length;
2513
+ const n = s2.length;
2514
+ const maxLength = Math.max(m, n);
2515
+ if (m === 0 || n === 0) {
2516
+ return { a, b, distance: maxLength, similarity: maxLength === 0 ? 1 : 0, maxLength, mode };
2517
+ }
2518
+ const dp = Array.from({ length: m + 1 }, () => new Array(n + 1).fill(0));
2519
+ for (let i = 0; i <= m; i++) dp[i][0] = i;
2520
+ for (let j = 0; j <= n; j++) dp[0][j] = j;
2521
+ for (let i = 1; i <= m; i++) {
2522
+ for (let j = 1; j <= n; j++) {
2523
+ const cost = s1[i - 1] === s2[j - 1] ? 0 : 1;
2524
+ dp[i][j] = Math.min(
2525
+ dp[i - 1][j] + 1,
2526
+ // deletion
2527
+ dp[i][j - 1] + 1,
2528
+ // insertion
2529
+ dp[i - 1][j - 1] + cost
2530
+ // substitution
2531
+ );
2532
+ if (mode === "damerau" && i > 1 && j > 1 && s1[i - 1] === s2[j - 2] && s1[i - 2] === s2[j - 1]) {
2533
+ dp[i][j] = Math.min(dp[i][j], dp[i - 2][j - 2] + 1);
2534
+ }
2535
+ }
2536
+ }
2537
+ const distance = dp[m][n];
2538
+ const similarity = maxLength === 0 ? 1 : Math.round((1 - distance / maxLength) * 1e4) / 1e4;
2539
+ return { a, b, distance, similarity, maxLength, mode };
2540
+ }
2500
2541
 
2501
2542
  exports.CASE_FORMATS = CASE_FORMATS;
2502
2543
  exports.DEFAULT_CONVERT_OPTIONS = DEFAULT_CONVERT_OPTIONS;
@@ -2507,6 +2548,7 @@ exports.addBorder = addBorder;
2507
2548
  exports.analyzeText = analyzeText;
2508
2549
  exports.applyOp = applyOp;
2509
2550
  exports.applyOps = applyOps;
2551
+ exports.calculateStringDistance = calculateStringDistance;
2510
2552
  exports.centerText = centerText;
2511
2553
  exports.convertAll = convertAll;
2512
2554
  exports.convertCase = convertCase;
@@ -1 +1 @@
1
- export { A as AsciiFont, a as AsciiOptions, C as CASE_FORMATS, b as CaseFormat, c as ConvertOptions, D as DEFAULT_CONVERT_OPTIONS, d as DiffFile, e as DiffHunk, f as DiffLine, g as DiffResult, h as DiffType, i as DiffViewerLine, E as ESCAPE_MODES, j as EscapeMode, F as FillerCategory, k as FillerMatch, l as FillerWordResult, L as LINE_OPS, m as LineOp, n as LineType, o as LoremUnit, M as MORSE_CODE, p as MarkdownResult, q as MorseOptions, P as ParsedDiff, r as ParsedTable, s as PassiveVoiceMatch, u as PassiveVoiceResult, v as PassiveVoiceSentence, R as ReadabilityResult, w as ReadabilityScore, S as SlugSeparator, T as TableOptions, x as TextAnalysis, W as WordCountResult, y as addBorder, z as analyzeText, B as applyOp, G as applyOps, H as centerText, I as convertAll, J as convertCase, K as countWords, N as csvToHtml, O as csvToMarkdown, Q as detectDelimiter, U as detectFillerWords, V as detectPassiveVoice, X as diffLines, Y as diffLinesSimple, Z as diffStats, _ as escapeAll, $ as escapeString, a0 as extractHeadings, a1 as formatReadingTime, a2 as generate, a3 as generateDiff, a4 as generateHtmlTable, a5 as generateMarkdownTable, a6 as generateParagraphs, a7 as generateSentences, a8 as generateWords, a9 as getAvailableFonts, aa as getMorseForChar, ab as getMorseTiming, ac as htmlToMarkdown, ad as isValidMorse, ae as markdownToHtml, af as morseToText, ag as numberToOrdinal, ah as numberToRoman, ai as numberToWords, aj as ordinalWords, ak as parseDiff, al as parseTableData, am as readabilityScore, an as renderMarkdown, ao as romanToNumber, ap as scoreReadability, aq as sentenceCount, ar as slugify, as as slugifyAll, at as syllableCount, au as textToAscii, av as textToMorse, aw as unescapeString, ax as wordFrequency } from '../text-DS70aMY5.cjs';
1
+ export { A as AsciiFont, a as AsciiOptions, C as CASE_FORMATS, b as CaseFormat, c as ConvertOptions, D as DEFAULT_CONVERT_OPTIONS, d as DiffFile, e as DiffHunk, f as DiffLine, g as DiffResult, h as DiffType, i as DiffViewerLine, E as ESCAPE_MODES, j as EscapeMode, F as FillerCategory, k as FillerMatch, l as FillerWordResult, L as LINE_OPS, m as LineOp, n as LineType, o as LoremUnit, M as MORSE_CODE, p as MarkdownResult, q as MorseOptions, P as ParsedDiff, r as ParsedTable, s as PassiveVoiceMatch, u as PassiveVoiceResult, v as PassiveVoiceSentence, R as ReadabilityResult, w as ReadabilityScore, S as SlugSeparator, x as StringDistanceMode, y as StringDistanceResult, T as TableOptions, z as TextAnalysis, W as WordCountResult, B as addBorder, G as analyzeText, H as applyOp, I as applyOps, J as calculateStringDistance, K as centerText, N as convertAll, O as convertCase, Q as countWords, U as csvToHtml, V as csvToMarkdown, X as detectDelimiter, Y as detectFillerWords, Z as detectPassiveVoice, _ as diffLines, $ as diffLinesSimple, a0 as diffStats, a1 as escapeAll, a2 as escapeString, a3 as extractHeadings, a4 as formatReadingTime, a5 as generate, a6 as generateDiff, a7 as generateHtmlTable, a8 as generateMarkdownTable, a9 as generateParagraphs, aa as generateSentences, ab as generateWords, ac as getAvailableFonts, ad as getMorseForChar, ae as getMorseTiming, af as htmlToMarkdown, ag as isValidMorse, ah as markdownToHtml, ai as morseToText, aj as numberToOrdinal, ak as numberToRoman, al as numberToWords, am as ordinalWords, an as parseDiff, ao as parseTableData, ap as readabilityScore, aq as renderMarkdown, ar as romanToNumber, as as scoreReadability, at as sentenceCount, au as slugify, av as slugifyAll, aw as syllableCount, ax as textToAscii, ay as textToMorse, az as unescapeString, aA as wordFrequency } from '../text-D1fySkCB.cjs';
@@ -1 +1 @@
1
- export { A as AsciiFont, a as AsciiOptions, C as CASE_FORMATS, b as CaseFormat, c as ConvertOptions, D as DEFAULT_CONVERT_OPTIONS, d as DiffFile, e as DiffHunk, f as DiffLine, g as DiffResult, h as DiffType, i as DiffViewerLine, E as ESCAPE_MODES, j as EscapeMode, F as FillerCategory, k as FillerMatch, l as FillerWordResult, L as LINE_OPS, m as LineOp, n as LineType, o as LoremUnit, M as MORSE_CODE, p as MarkdownResult, q as MorseOptions, P as ParsedDiff, r as ParsedTable, s as PassiveVoiceMatch, u as PassiveVoiceResult, v as PassiveVoiceSentence, R as ReadabilityResult, w as ReadabilityScore, S as SlugSeparator, T as TableOptions, x as TextAnalysis, W as WordCountResult, y as addBorder, z as analyzeText, B as applyOp, G as applyOps, H as centerText, I as convertAll, J as convertCase, K as countWords, N as csvToHtml, O as csvToMarkdown, Q as detectDelimiter, U as detectFillerWords, V as detectPassiveVoice, X as diffLines, Y as diffLinesSimple, Z as diffStats, _ as escapeAll, $ as escapeString, a0 as extractHeadings, a1 as formatReadingTime, a2 as generate, a3 as generateDiff, a4 as generateHtmlTable, a5 as generateMarkdownTable, a6 as generateParagraphs, a7 as generateSentences, a8 as generateWords, a9 as getAvailableFonts, aa as getMorseForChar, ab as getMorseTiming, ac as htmlToMarkdown, ad as isValidMorse, ae as markdownToHtml, af as morseToText, ag as numberToOrdinal, ah as numberToRoman, ai as numberToWords, aj as ordinalWords, ak as parseDiff, al as parseTableData, am as readabilityScore, an as renderMarkdown, ao as romanToNumber, ap as scoreReadability, aq as sentenceCount, ar as slugify, as as slugifyAll, at as syllableCount, au as textToAscii, av as textToMorse, aw as unescapeString, ax as wordFrequency } from '../text-DS70aMY5.js';
1
+ export { A as AsciiFont, a as AsciiOptions, C as CASE_FORMATS, b as CaseFormat, c as ConvertOptions, D as DEFAULT_CONVERT_OPTIONS, d as DiffFile, e as DiffHunk, f as DiffLine, g as DiffResult, h as DiffType, i as DiffViewerLine, E as ESCAPE_MODES, j as EscapeMode, F as FillerCategory, k as FillerMatch, l as FillerWordResult, L as LINE_OPS, m as LineOp, n as LineType, o as LoremUnit, M as MORSE_CODE, p as MarkdownResult, q as MorseOptions, P as ParsedDiff, r as ParsedTable, s as PassiveVoiceMatch, u as PassiveVoiceResult, v as PassiveVoiceSentence, R as ReadabilityResult, w as ReadabilityScore, S as SlugSeparator, x as StringDistanceMode, y as StringDistanceResult, T as TableOptions, z as TextAnalysis, W as WordCountResult, B as addBorder, G as analyzeText, H as applyOp, I as applyOps, J as calculateStringDistance, K as centerText, N as convertAll, O as convertCase, Q as countWords, U as csvToHtml, V as csvToMarkdown, X as detectDelimiter, Y as detectFillerWords, Z as detectPassiveVoice, _ as diffLines, $ as diffLinesSimple, a0 as diffStats, a1 as escapeAll, a2 as escapeString, a3 as extractHeadings, a4 as formatReadingTime, a5 as generate, a6 as generateDiff, a7 as generateHtmlTable, a8 as generateMarkdownTable, a9 as generateParagraphs, aa as generateSentences, ab as generateWords, ac as getAvailableFonts, ad as getMorseForChar, ae as getMorseTiming, af as htmlToMarkdown, ag as isValidMorse, ah as markdownToHtml, ai as morseToText, aj as numberToOrdinal, ak as numberToRoman, al as numberToWords, am as ordinalWords, an as parseDiff, ao as parseTableData, ap as readabilityScore, aq as renderMarkdown, ar as romanToNumber, as as scoreReadability, at as sentenceCount, au as slugify, av as slugifyAll, aw as syllableCount, ax as textToAscii, ay as textToMorse, az as unescapeString, aA as wordFrequency } from '../text-D1fySkCB.js';
@@ -1,2 +1,2 @@
1
- export { CASE_FORMATS, DEFAULT_CONVERT_OPTIONS, ESCAPE_MODES, LINE_OPS, MORSE_CODE, addBorder, analyzeText, applyOp, applyOps, centerText, convertAll, convertCase, countWords, csvToHtml, csvToMarkdown, detectDelimiter, detectFillerWords, detectPassiveVoice, diffLines, diffLinesSimple, diffStats, escapeAll, escapeString, extractHeadings, formatReadingTime, generate, generateDiff, generateHtmlTable, generateMarkdownTable, generateParagraphs, generateSentences, generateWords, getAvailableFonts, getMorseForChar, getMorseTiming, htmlToMarkdown, isValidMorse, markdownToHtml, morseToText, numberToOrdinal, numberToRoman, numberToWords, ordinalWords, parseDiff, parseTableData, readabilityScore, renderMarkdown, romanToNumber, scoreReadability, sentenceCount, slugify, slugifyAll, syllableCount, textToAscii, textToMorse, unescapeString, wordFrequency } from '../chunk-2I4O5YCT.js';
1
+ export { CASE_FORMATS, DEFAULT_CONVERT_OPTIONS, ESCAPE_MODES, LINE_OPS, MORSE_CODE, addBorder, 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, getMorseForChar, getMorseTiming, htmlToMarkdown, isValidMorse, markdownToHtml, morseToText, numberToOrdinal, numberToRoman, numberToWords, ordinalWords, parseDiff, parseTableData, readabilityScore, renderMarkdown, romanToNumber, scoreReadability, sentenceCount, slugify, slugifyAll, syllableCount, textToAscii, textToMorse, unescapeString, wordFrequency } from '../chunk-AFEZ6N4A.js';
2
2
  import '../chunk-MLKGABMK.js';
@@ -1386,6 +1386,128 @@ function markupToMargin(markupPercent) {
1386
1386
  }
1387
1387
  return Math.round(markupPercent / (100 + markupPercent) * 100 * 1e4) / 1e4;
1388
1388
  }
1389
+ var _DISCOUNT_FIELDS = ["discountPercent", "discountAmount", "finalPrice"];
1390
+ function calculateDiscount(input) {
1391
+ const provided = (v) => typeof v === "number" && Number.isFinite(v);
1392
+ if (!provided(input.originalPrice)) {
1393
+ return { error: "originalPrice is required and must be a finite number" };
1394
+ }
1395
+ const originalPrice = input.originalPrice;
1396
+ if (originalPrice <= 0) return { error: "Original price must be greater than zero" };
1397
+ const given = _DISCOUNT_FIELDS.filter((f) => provided(input[f]));
1398
+ if (given.length !== 1) {
1399
+ return { error: `Provide exactly one of discountPercent, discountAmount, finalPrice (got ${given.length})` };
1400
+ }
1401
+ const field = given[0];
1402
+ let discountAmount;
1403
+ if (field === "discountPercent") {
1404
+ const pct = input.discountPercent;
1405
+ if (pct < 0) return { error: "Discount percent cannot be negative" };
1406
+ if (pct > 100) return { error: "Discount percent cannot exceed 100" };
1407
+ discountAmount = originalPrice * (pct / 100);
1408
+ } else if (field === "discountAmount") {
1409
+ const amt = input.discountAmount;
1410
+ if (amt < 0) return { error: "Discount amount cannot be negative" };
1411
+ if (amt > originalPrice) return { error: "Discount amount cannot exceed the original price" };
1412
+ discountAmount = amt;
1413
+ } else {
1414
+ const fin = input.finalPrice;
1415
+ if (fin < 0) return { error: "Final price cannot be negative" };
1416
+ if (fin > originalPrice) {
1417
+ return { error: "Final price cannot exceed the original price: that is a price increase, not a discount" };
1418
+ }
1419
+ discountAmount = originalPrice - fin;
1420
+ }
1421
+ const round4 = (n) => Math.round(n * 1e4) / 1e4;
1422
+ const finalPrice = originalPrice - discountAmount;
1423
+ return {
1424
+ originalPrice: round4(originalPrice),
1425
+ finalPrice: round4(finalPrice),
1426
+ discountAmount: round4(discountAmount),
1427
+ discountPercent: round4(discountAmount / originalPrice * 100),
1428
+ given: field,
1429
+ solvedFor: _DISCOUNT_FIELDS.filter((f) => f !== field)
1430
+ };
1431
+ }
1432
+ function applySuccessiveDiscounts(originalPrice, discountPercents) {
1433
+ if (!Number.isFinite(originalPrice) || originalPrice <= 0) {
1434
+ return { error: "Original price must be a finite number greater than zero" };
1435
+ }
1436
+ if (!Array.isArray(discountPercents) || discountPercents.length === 0) {
1437
+ return { error: "Provide at least one discount percent" };
1438
+ }
1439
+ if (discountPercents.length > 20) {
1440
+ return { error: "Provide at most 20 successive discounts" };
1441
+ }
1442
+ const round4 = (n) => Math.round(n * 1e4) / 1e4;
1443
+ const steps = [];
1444
+ let running = originalPrice;
1445
+ let sumOfDiscountPercents = 0;
1446
+ for (const pct of discountPercents) {
1447
+ if (!Number.isFinite(pct)) return { error: "Every discount percent must be a finite number" };
1448
+ if (pct < 0) return { error: "Discount percent cannot be negative" };
1449
+ if (pct > 100) return { error: "Discount percent cannot exceed 100" };
1450
+ const priceBefore = running;
1451
+ const saved = priceBefore * (pct / 100);
1452
+ running = priceBefore - saved;
1453
+ sumOfDiscountPercents += pct;
1454
+ steps.push({
1455
+ discountPercent: round4(pct),
1456
+ priceBefore: round4(priceBefore),
1457
+ priceAfter: round4(running),
1458
+ saved: round4(saved)
1459
+ });
1460
+ }
1461
+ const totalSaved = originalPrice - running;
1462
+ return {
1463
+ originalPrice: round4(originalPrice),
1464
+ finalPrice: round4(running),
1465
+ totalSaved: round4(totalSaved),
1466
+ effectiveDiscountPercent: round4(totalSaved / originalPrice * 100),
1467
+ sumOfDiscountPercents: round4(sumOfDiscountPercents),
1468
+ steps
1469
+ };
1470
+ }
1471
+ function calculateBreakEven(input) {
1472
+ const { fixedCosts, variableCostPerUnit, pricePerUnit, salesVolume } = input;
1473
+ if (!Number.isFinite(fixedCosts)) return { error: "fixedCosts must be a finite number" };
1474
+ if (!Number.isFinite(variableCostPerUnit)) return { error: "variableCostPerUnit must be a finite number" };
1475
+ if (!Number.isFinite(pricePerUnit)) return { error: "pricePerUnit must be a finite number" };
1476
+ if (fixedCosts < 0) return { error: "fixedCosts cannot be negative" };
1477
+ if (variableCostPerUnit < 0) return { error: "variableCostPerUnit cannot be negative" };
1478
+ if (pricePerUnit <= 0) return { error: "pricePerUnit must be greater than zero" };
1479
+ if (pricePerUnit <= variableCostPerUnit) {
1480
+ return { error: "pricePerUnit must be greater than variableCostPerUnit, otherwise every unit sold loses money and break-even is never reached" };
1481
+ }
1482
+ const round4 = (n) => Math.round(n * 1e4) / 1e4;
1483
+ const contributionMarginPerUnit = pricePerUnit - variableCostPerUnit;
1484
+ const contributionMarginRatio = contributionMarginPerUnit / pricePerUnit * 100;
1485
+ const breakEvenUnits = fixedCosts / contributionMarginPerUnit;
1486
+ const breakEvenUnitsRounded = Math.ceil(breakEvenUnits);
1487
+ const breakEvenRevenue = breakEvenUnits * pricePerUnit;
1488
+ const result = {
1489
+ fixedCosts: round4(fixedCosts),
1490
+ variableCostPerUnit: round4(variableCostPerUnit),
1491
+ pricePerUnit: round4(pricePerUnit),
1492
+ contributionMarginPerUnit: round4(contributionMarginPerUnit),
1493
+ contributionMarginRatio: round4(contributionMarginRatio),
1494
+ breakEvenUnits: round4(breakEvenUnits),
1495
+ breakEvenUnitsRounded,
1496
+ breakEvenRevenue: round4(breakEvenRevenue)
1497
+ };
1498
+ if (typeof salesVolume === "number" && Number.isFinite(salesVolume)) {
1499
+ if (salesVolume < 0) return { error: "salesVolume cannot be negative" };
1500
+ const revenueAtSalesVolume = salesVolume * pricePerUnit;
1501
+ const profitAtSalesVolume = salesVolume * contributionMarginPerUnit - fixedCosts;
1502
+ const marginOfSafetyUnits = salesVolume - breakEvenUnits;
1503
+ result.salesVolume = round4(salesVolume);
1504
+ result.revenueAtSalesVolume = round4(revenueAtSalesVolume);
1505
+ result.profitAtSalesVolume = round4(profitAtSalesVolume);
1506
+ result.marginOfSafetyUnits = round4(marginOfSafetyUnits);
1507
+ result.marginOfSafetyPercent = salesVolume > 0 ? round4(marginOfSafetyUnits / salesVolume * 100) : 0;
1508
+ }
1509
+ return result;
1510
+ }
1389
1511
 
1390
1512
  exports.BASE_LABELS = BASE_LABELS;
1391
1513
  exports.BASE_PREFIXES = BASE_PREFIXES;
@@ -1398,11 +1520,14 @@ exports.COMMON_SIZES = COMMON_SIZES;
1398
1520
  exports.COMMON_TAX_RATES = COMMON_TAX_RATES;
1399
1521
  exports.COMMON_TIP_PERCENTAGES = COMMON_TIP_PERCENTAGES;
1400
1522
  exports.COMMON_VIEWPORTS = COMMON_VIEWPORTS;
1523
+ exports.applySuccessiveDiscounts = applySuccessiveDiscounts;
1401
1524
  exports.autoFormat = autoFormat;
1402
1525
  exports.bumpVersion = bumpVersion;
1403
1526
  exports.calcAspectRatio = calcAspectRatio;
1404
1527
  exports.calcSubnet = calcSubnet;
1528
+ exports.calculateBreakEven = calculateBreakEven;
1405
1529
  exports.calculateCompoundInterest = calculateCompoundInterest;
1530
+ exports.calculateDiscount = calculateDiscount;
1406
1531
  exports.calculateLoan = calculateLoan;
1407
1532
  exports.calculateMarginMarkup = calculateMarginMarkup;
1408
1533
  exports.calculatePercentageChange = calculatePercentageChange;