ortoni-report 3.0.1 → 3.0.3

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.
@@ -5,6 +5,7 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __getProtoOf = Object.getPrototypeOf;
7
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
9
  var __export = (target, all) => {
9
10
  for (var name in all)
10
11
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -26,6 +27,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
26
27
  mod
27
28
  ));
28
29
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
29
31
 
30
32
  // src/ortoni-report.ts
31
33
  var ortoni_report_exports = {};
@@ -58,21 +60,41 @@ var FileManager = class {
58
60
  return outputPath;
59
61
  }
60
62
  readCssContent() {
61
- return import_fs.default.readFileSync(import_path.default.resolve(__dirname, "style", "main.css"), "utf-8");
63
+ return import_fs.default.readFileSync(
64
+ import_path.default.resolve(__dirname, "style", "main.css"),
65
+ "utf-8"
66
+ );
62
67
  }
63
- copyTraceViewerAssets() {
64
- const traceViewerFolder = import_path.default.join(require.resolve("playwright-core"), "..", "lib", "vite", "traceViewer");
68
+ copyTraceViewerAssets(skip) {
69
+ if (skip) return;
70
+ const traceViewerFolder = import_path.default.join(
71
+ require.resolve("playwright-core"),
72
+ "..",
73
+ "lib",
74
+ "vite",
75
+ "traceViewer"
76
+ );
65
77
  const traceViewerTargetFolder = import_path.default.join(this.folderPath, "trace");
66
- const traceViewerAssetsTargetFolder = import_path.default.join(traceViewerTargetFolder, "assets");
78
+ const traceViewerAssetsTargetFolder = import_path.default.join(
79
+ traceViewerTargetFolder,
80
+ "assets"
81
+ );
67
82
  import_fs.default.mkdirSync(traceViewerAssetsTargetFolder, { recursive: true });
68
83
  for (const file of import_fs.default.readdirSync(traceViewerFolder)) {
69
- if (file.endsWith(".map") || file.includes("watch") || file.includes("assets")) continue;
70
- import_fs.default.copyFileSync(import_path.default.join(traceViewerFolder, file), import_path.default.join(traceViewerTargetFolder, file));
84
+ if (file.endsWith(".map") || file.includes("watch") || file.includes("assets"))
85
+ continue;
86
+ import_fs.default.copyFileSync(
87
+ import_path.default.join(traceViewerFolder, file),
88
+ import_path.default.join(traceViewerTargetFolder, file)
89
+ );
71
90
  }
72
91
  const assetsFolder = import_path.default.join(traceViewerFolder, "assets");
73
92
  for (const file of import_fs.default.readdirSync(assetsFolder)) {
74
93
  if (file.endsWith(".map") || file.includes("xtermModule")) continue;
75
- import_fs.default.copyFileSync(import_path.default.join(assetsFolder, file), import_path.default.join(traceViewerAssetsTargetFolder, file));
94
+ import_fs.default.copyFileSync(
95
+ import_path.default.join(assetsFolder, file),
96
+ import_path.default.join(traceViewerAssetsTargetFolder, file)
97
+ );
76
98
  }
77
99
  }
78
100
  };
@@ -143,15 +165,19 @@ function formatDate(date) {
143
165
  }
144
166
  function safeStringify(obj, indent = 2) {
145
167
  const cache = /* @__PURE__ */ new Set();
146
- const json = JSON.stringify(obj, (key, value) => {
147
- if (typeof value === "object" && value !== null) {
148
- if (cache.has(value)) {
149
- return;
168
+ const json = JSON.stringify(
169
+ obj,
170
+ (key, value) => {
171
+ if (typeof value === "object" && value !== null) {
172
+ if (cache.has(value)) {
173
+ return;
174
+ }
175
+ cache.add(value);
150
176
  }
151
- cache.add(value);
152
- }
153
- return value;
154
- }, indent);
177
+ return value;
178
+ },
179
+ indent
180
+ );
155
181
  cache.clear();
156
182
  return json;
157
183
  }
@@ -188,12 +214,18 @@ function formatDateLocal(isoString) {
188
214
  day: "2-digit",
189
215
  hour: "2-digit",
190
216
  minute: "2-digit",
191
- // second: '2-digit',
192
217
  hour12: true,
193
218
  timeZoneName: "short"
194
219
  };
195
220
  return new Intl.DateTimeFormat(void 0, options).format(date);
196
221
  }
222
+ function formatDateNoTimezone(isoString) {
223
+ const date = new Date(isoString);
224
+ return date.toLocaleString("en-US", {
225
+ dateStyle: "medium",
226
+ timeStyle: "short"
227
+ });
228
+ }
197
229
 
198
230
  // src/helpers/HTMLGenerator.ts
199
231
  var import_fs2 = __toESM(require("fs"));
@@ -219,6 +251,26 @@ var HTMLGenerator = class {
219
251
  const template = import_handlebars.default.compile(templateSource);
220
252
  return template({ ...data, inlineCss: cssContent });
221
253
  }
254
+ async getReportData() {
255
+ return {
256
+ summary: await this.dbManager.getSummaryData(),
257
+ trends: await this.dbManager.getTrends(),
258
+ flakyTests: await this.dbManager.getFlakyTests(),
259
+ slowTests: await this.dbManager.getSlowTests()
260
+ };
261
+ }
262
+ async chartTrendData() {
263
+ return {
264
+ labels: (await this.getReportData()).trends.map(
265
+ (t) => formatDateNoTimezone(t.run_date)
266
+ ),
267
+ passed: (await this.getReportData()).trends.map((t) => t.passed),
268
+ failed: (await this.getReportData()).trends.map((t) => t.failed),
269
+ avgDuration: (await this.getReportData()).trends.map(
270
+ (t) => t.avg_duration
271
+ )
272
+ };
273
+ }
222
274
  async prepareReportData(filteredResults, totalDuration, results, projectSet) {
223
275
  const totalTests = filteredResults.length;
224
276
  const passedTests = results.filter((r) => r.status === "passed").length;
@@ -273,6 +325,9 @@ var HTMLGenerator = class {
273
325
  allTags: Array.from(allTags),
274
326
  showProject: this.ortoniConfig.showProject || false,
275
327
  title: this.ortoniConfig.title || "Ortoni Playwright Test Report",
328
+ chartType: this.ortoniConfig.chartType || "pie",
329
+ reportAnalyticsData: await this.getReportData(),
330
+ chartData: await this.chartTrendData(),
276
331
  ...this.extractProjectStats(projectResults)
277
332
  };
278
333
  }
@@ -320,8 +375,8 @@ var HTMLGenerator = class {
320
375
  (actualStatus, expectedStatus) => actualStatus.includes(expectedStatus)
321
376
  );
322
377
  import_handlebars.default.registerHelper("gr", (count) => count > 0);
323
- import_handlebars.default.registerHelper("or", function(a, b) {
324
- return a || b;
378
+ import_handlebars.default.registerHelper("or", function(a3, b2) {
379
+ return a3 || b2;
325
380
  });
326
381
  import_handlebars.default.registerHelper("concat", function(...args) {
327
382
  args.pop();
@@ -337,7 +392,8 @@ var HTMLGenerator = class {
337
392
  "userInfo",
338
393
  "project",
339
394
  "testStatus",
340
- "testIcons"
395
+ "testIcons",
396
+ "analytics"
341
397
  ].forEach((partialName) => {
342
398
  import_handlebars.default.registerPartial(
343
399
  partialName,
@@ -356,12 +412,1190 @@ var import_path5 = __toESM(require("path"));
356
412
 
357
413
  // src/utils/attachFiles.ts
358
414
  var import_path4 = __toESM(require("path"));
415
+ var import_fs4 = __toESM(require("fs"));
416
+
417
+ // src/helpers/markdownConverter.ts
359
418
  var import_fs3 = __toESM(require("fs"));
360
- function attachFiles(subFolder, result, testResult, config) {
419
+
420
+ // node_modules/marked/lib/marked.esm.js
421
+ function M() {
422
+ return { async: false, breaks: false, extensions: null, gfm: true, hooks: null, pedantic: false, renderer: null, silent: false, tokenizer: null, walkTokens: null };
423
+ }
424
+ var w = M();
425
+ function H(a3) {
426
+ w = a3;
427
+ }
428
+ var C = { exec: () => null };
429
+ function h(a3, e = "") {
430
+ let t = typeof a3 == "string" ? a3 : a3.source, n = { replace: (s, i) => {
431
+ let r = typeof i == "string" ? i : i.source;
432
+ return r = r.replace(m.caret, "$1"), t = t.replace(s, r), n;
433
+ }, getRegex: () => new RegExp(t, e) };
434
+ return n;
435
+ }
436
+ var m = { codeRemoveIndent: /^(?: {1,4}| {0,3}\t)/gm, outputLinkReplace: /\\([\[\]])/g, indentCodeCompensation: /^(\s+)(?:```)/, beginningSpace: /^\s+/, endingHash: /#$/, startingSpaceChar: /^ /, endingSpaceChar: / $/, nonSpaceChar: /[^ ]/, newLineCharGlobal: /\n/g, tabCharGlobal: /\t/g, multipleSpaceGlobal: /\s+/g, blankLine: /^[ \t]*$/, doubleBlankLine: /\n[ \t]*\n[ \t]*$/, blockquoteStart: /^ {0,3}>/, blockquoteSetextReplace: /\n {0,3}((?:=+|-+) *)(?=\n|$)/g, blockquoteSetextReplace2: /^ {0,3}>[ \t]?/gm, listReplaceTabs: /^\t+/, listReplaceNesting: /^ {1,4}(?=( {4})*[^ ])/g, listIsTask: /^\[[ xX]\] /, listReplaceTask: /^\[[ xX]\] +/, anyLine: /\n.*\n/, hrefBrackets: /^<(.*)>$/, tableDelimiter: /[:|]/, tableAlignChars: /^\||\| *$/g, tableRowBlankLine: /\n[ \t]*$/, tableAlignRight: /^ *-+: *$/, tableAlignCenter: /^ *:-+: *$/, tableAlignLeft: /^ *:-+ *$/, startATag: /^<a /i, endATag: /^<\/a>/i, startPreScriptTag: /^<(pre|code|kbd|script)(\s|>)/i, endPreScriptTag: /^<\/(pre|code|kbd|script)(\s|>)/i, startAngleBracket: /^</, endAngleBracket: />$/, pedanticHrefTitle: /^([^'"]*[^\s])\s+(['"])(.*)\2/, unicodeAlphaNumeric: /[\p{L}\p{N}]/u, escapeTest: /[&<>"']/, escapeReplace: /[&<>"']/g, escapeTestNoEncode: /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/, escapeReplaceNoEncode: /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/g, unescapeTest: /&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig, caret: /(^|[^\[])\^/g, percentDecode: /%25/g, findPipe: /\|/g, splitPipe: / \|/, slashPipe: /\\\|/g, carriageReturn: /\r\n|\r/g, spaceLine: /^ +$/gm, notSpaceStart: /^\S*/, endingNewline: /\n$/, listItemRegex: (a3) => new RegExp(`^( {0,3}${a3})((?:[ ][^\\n]*)?(?:\\n|$))`), nextBulletRegex: (a3) => new RegExp(`^ {0,${Math.min(3, a3 - 1)}}(?:[*+-]|\\d{1,9}[.)])((?:[ ][^\\n]*)?(?:\\n|$))`), hrRegex: (a3) => new RegExp(`^ {0,${Math.min(3, a3 - 1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`), fencesBeginRegex: (a3) => new RegExp(`^ {0,${Math.min(3, a3 - 1)}}(?:\`\`\`|~~~)`), headingBeginRegex: (a3) => new RegExp(`^ {0,${Math.min(3, a3 - 1)}}#`), htmlBeginRegex: (a3) => new RegExp(`^ {0,${Math.min(3, a3 - 1)}}<(?:[a-z].*>|!--)`, "i") };
437
+ var xe = /^(?:[ \t]*(?:\n|$))+/;
438
+ var be = /^((?: {4}| {0,3}\t)[^\n]+(?:\n(?:[ \t]*(?:\n|$))*)?)+/;
439
+ var Te = /^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/;
440
+ var I = /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/;
441
+ var we = /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/;
442
+ var j = /(?:[*+-]|\d{1,9}[.)])/;
443
+ var re = /^(?!bull |blockCode|fences|blockquote|heading|html|table)((?:.|\n(?!\s*?\n|bull |blockCode|fences|blockquote|heading|html|table))+?)\n {0,3}(=+|-+) *(?:\n+|$)/;
444
+ var ie = h(re).replace(/bull/g, j).replace(/blockCode/g, /(?: {4}| {0,3}\t)/).replace(/fences/g, / {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g, / {0,3}>/).replace(/heading/g, / {0,3}#{1,6}/).replace(/html/g, / {0,3}<[^\n>]+>\n/).replace(/\|table/g, "").getRegex();
445
+ var ye = h(re).replace(/bull/g, j).replace(/blockCode/g, /(?: {4}| {0,3}\t)/).replace(/fences/g, / {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g, / {0,3}>/).replace(/heading/g, / {0,3}#{1,6}/).replace(/html/g, / {0,3}<[^\n>]+>\n/).replace(/table/g, / {0,3}\|?(?:[:\- ]*\|)+[\:\- ]*\n/).getRegex();
446
+ var F = /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/;
447
+ var Re = /^[^\n]+/;
448
+ var Q = /(?!\s*\])(?:\\.|[^\[\]\\])+/;
449
+ var Se = h(/^ {0,3}\[(label)\]: *(?:\n[ \t]*)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n[ \t]*)?| *\n[ \t]*)(title))? *(?:\n+|$)/).replace("label", Q).replace("title", /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/).getRegex();
450
+ var $e = h(/^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/).replace(/bull/g, j).getRegex();
451
+ var v = "address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul";
452
+ var U = /<!--(?:-?>|[\s\S]*?(?:-->|$))/;
453
+ var _e = h("^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|<![A-Z][\\s\\S]*?(?:>\\n*|$)|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>\\n*|$)|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$))", "i").replace("comment", U).replace("tag", v).replace("attribute", / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex();
454
+ var oe = h(F).replace("hr", I).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("|lheading", "").replace("|table", "").replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", v).getRegex();
455
+ var Le = h(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/).replace("paragraph", oe).getRegex();
456
+ var K = { blockquote: Le, code: be, def: Se, fences: Te, heading: we, hr: I, html: _e, lheading: ie, list: $e, newline: xe, paragraph: oe, table: C, text: Re };
457
+ var se = h("^ *([^\\n ].*)\\n {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)").replace("hr", I).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("blockquote", " {0,3}>").replace("code", "(?: {4}| {0,3} )[^\\n]").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", v).getRegex();
458
+ var ze = { ...K, lheading: ye, table: se, paragraph: h(F).replace("hr", I).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("|lheading", "").replace("table", se).replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", v).getRegex() };
459
+ var Me = { ...K, html: h(`^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)|<tag(?:"[^"]*"|'[^']*'|\\s[^'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))`).replace("comment", U).replace(/tag/g, "(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(), def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/, heading: /^(#{1,6})(.*)(?:\n+|$)/, fences: C, lheading: /^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/, paragraph: h(F).replace("hr", I).replace("heading", ` *#{1,6} *[^
460
+ ]`).replace("lheading", ie).replace("|table", "").replace("blockquote", " {0,3}>").replace("|fences", "").replace("|list", "").replace("|html", "").replace("|tag", "").getRegex() };
461
+ var Pe = /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/;
462
+ var Ae = /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/;
463
+ var le = /^( {2,}|\\)\n(?!\s*$)/;
464
+ var Ee = /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/;
465
+ var D = /[\p{P}\p{S}]/u;
466
+ var X = /[\s\p{P}\p{S}]/u;
467
+ var ae = /[^\s\p{P}\p{S}]/u;
468
+ var Ce = h(/^((?![*_])punctSpace)/, "u").replace(/punctSpace/g, X).getRegex();
469
+ var ce = /(?!~)[\p{P}\p{S}]/u;
470
+ var Ie = /(?!~)[\s\p{P}\p{S}]/u;
471
+ var Oe = /(?:[^\s\p{P}\p{S}]|~)/u;
472
+ var Be = /\[[^[\]]*?\]\((?:\\.|[^\\\(\)]|\((?:\\.|[^\\\(\)])*\))*\)|`[^`]*?`|<[^<>]*?>/g;
473
+ var pe = /^(?:\*+(?:((?!\*)punct)|[^\s*]))|^_+(?:((?!_)punct)|([^\s_]))/;
474
+ var qe = h(pe, "u").replace(/punct/g, D).getRegex();
475
+ var ve = h(pe, "u").replace(/punct/g, ce).getRegex();
476
+ var ue = "^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\*)punct(\\*+)(?=[\\s]|$)|notPunctSpace(\\*+)(?!\\*)(?=punctSpace|$)|(?!\\*)punctSpace(\\*+)(?=notPunctSpace)|[\\s](\\*+)(?!\\*)(?=punct)|(?!\\*)punct(\\*+)(?!\\*)(?=punct)|notPunctSpace(\\*+)(?=notPunctSpace)";
477
+ var De = h(ue, "gu").replace(/notPunctSpace/g, ae).replace(/punctSpace/g, X).replace(/punct/g, D).getRegex();
478
+ var Ze = h(ue, "gu").replace(/notPunctSpace/g, Oe).replace(/punctSpace/g, Ie).replace(/punct/g, ce).getRegex();
479
+ var Ge = h("^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)|[^_]+(?=[^_])|(?!_)punct(_+)(?=[\\s]|$)|notPunctSpace(_+)(?!_)(?=punctSpace|$)|(?!_)punctSpace(_+)(?=notPunctSpace)|[\\s](_+)(?!_)(?=punct)|(?!_)punct(_+)(?!_)(?=punct)", "gu").replace(/notPunctSpace/g, ae).replace(/punctSpace/g, X).replace(/punct/g, D).getRegex();
480
+ var He = h(/\\(punct)/, "gu").replace(/punct/g, D).getRegex();
481
+ var Ne = h(/^<(scheme:[^\s\x00-\x1f<>]*|email)>/).replace("scheme", /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/).replace("email", /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/).getRegex();
482
+ var je = h(U).replace("(?:-->|$)", "-->").getRegex();
483
+ var Fe = h("^comment|^</[a-zA-Z][\\w:-]*\\s*>|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^<![a-zA-Z]+\\s[\\s\\S]*?>|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>").replace("comment", je).replace("attribute", /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/).getRegex();
484
+ var q = /(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/;
485
+ var Qe = h(/^!?\[(label)\]\(\s*(href)(?:(?:[ \t]*(?:\n[ \t]*)?)(title))?\s*\)/).replace("label", q).replace("href", /<(?:\\.|[^\n<>\\])+>|[^ \t\n\x00-\x1f]*/).replace("title", /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/).getRegex();
486
+ var he = h(/^!?\[(label)\]\[(ref)\]/).replace("label", q).replace("ref", Q).getRegex();
487
+ var ke = h(/^!?\[(ref)\](?:\[\])?/).replace("ref", Q).getRegex();
488
+ var Ue = h("reflink|nolink(?!\\()", "g").replace("reflink", he).replace("nolink", ke).getRegex();
489
+ var W = { _backpedal: C, anyPunctuation: He, autolink: Ne, blockSkip: Be, br: le, code: Ae, del: C, emStrongLDelim: qe, emStrongRDelimAst: De, emStrongRDelimUnd: Ge, escape: Pe, link: Qe, nolink: ke, punctuation: Ce, reflink: he, reflinkSearch: Ue, tag: Fe, text: Ee, url: C };
490
+ var Ke = { ...W, link: h(/^!?\[(label)\]\((.*?)\)/).replace("label", q).getRegex(), reflink: h(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label", q).getRegex() };
491
+ var N = { ...W, emStrongRDelimAst: Ze, emStrongLDelim: ve, url: h(/^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/, "i").replace("email", /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/).getRegex(), _backpedal: /(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/, del: /^(~~?)(?=[^\s~])((?:\\.|[^\\])*?(?:\\.|[^\s~\\]))\1(?=[^~]|$)/, text: /^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|https?:\/\/|ftp:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/ };
492
+ var Xe = { ...N, br: h(le).replace("{2,}", "*").getRegex(), text: h(N.text).replace("\\b_", "\\b_| {2,}\\n").replace(/\{2,\}/g, "*").getRegex() };
493
+ var O = { normal: K, gfm: ze, pedantic: Me };
494
+ var P = { normal: W, gfm: N, breaks: Xe, pedantic: Ke };
495
+ var We = { "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#39;" };
496
+ var ge = (a3) => We[a3];
497
+ function R(a3, e) {
498
+ if (e) {
499
+ if (m.escapeTest.test(a3)) return a3.replace(m.escapeReplace, ge);
500
+ } else if (m.escapeTestNoEncode.test(a3)) return a3.replace(m.escapeReplaceNoEncode, ge);
501
+ return a3;
502
+ }
503
+ function J(a3) {
504
+ try {
505
+ a3 = encodeURI(a3).replace(m.percentDecode, "%");
506
+ } catch {
507
+ return null;
508
+ }
509
+ return a3;
510
+ }
511
+ function V(a3, e) {
512
+ let t = a3.replace(m.findPipe, (i, r, o) => {
513
+ let l = false, c = r;
514
+ for (; --c >= 0 && o[c] === "\\"; ) l = !l;
515
+ return l ? "|" : " |";
516
+ }), n = t.split(m.splitPipe), s = 0;
517
+ if (n[0].trim() || n.shift(), n.length > 0 && !n.at(-1)?.trim() && n.pop(), e) if (n.length > e) n.splice(e);
518
+ else for (; n.length < e; ) n.push("");
519
+ for (; s < n.length; s++) n[s] = n[s].trim().replace(m.slashPipe, "|");
520
+ return n;
521
+ }
522
+ function A(a3, e, t) {
523
+ let n = a3.length;
524
+ if (n === 0) return "";
525
+ let s = 0;
526
+ for (; s < n; ) {
527
+ let i = a3.charAt(n - s - 1);
528
+ if (i === e && !t) s++;
529
+ else if (i !== e && t) s++;
530
+ else break;
531
+ }
532
+ return a3.slice(0, n - s);
533
+ }
534
+ function fe(a3, e) {
535
+ if (a3.indexOf(e[1]) === -1) return -1;
536
+ let t = 0;
537
+ for (let n = 0; n < a3.length; n++) if (a3[n] === "\\") n++;
538
+ else if (a3[n] === e[0]) t++;
539
+ else if (a3[n] === e[1] && (t--, t < 0)) return n;
540
+ return t > 0 ? -2 : -1;
541
+ }
542
+ function de(a3, e, t, n, s) {
543
+ let i = e.href, r = e.title || null, o = a3[1].replace(s.other.outputLinkReplace, "$1");
544
+ n.state.inLink = true;
545
+ let l = { type: a3[0].charAt(0) === "!" ? "image" : "link", raw: t, href: i, title: r, text: o, tokens: n.inlineTokens(o) };
546
+ return n.state.inLink = false, l;
547
+ }
548
+ function Je(a3, e, t) {
549
+ let n = a3.match(t.other.indentCodeCompensation);
550
+ if (n === null) return e;
551
+ let s = n[1];
552
+ return e.split(`
553
+ `).map((i) => {
554
+ let r = i.match(t.other.beginningSpace);
555
+ if (r === null) return i;
556
+ let [o] = r;
557
+ return o.length >= s.length ? i.slice(s.length) : i;
558
+ }).join(`
559
+ `);
560
+ }
561
+ var S = class {
562
+ constructor(e) {
563
+ __publicField(this, "options");
564
+ __publicField(this, "rules");
565
+ __publicField(this, "lexer");
566
+ this.options = e || w;
567
+ }
568
+ space(e) {
569
+ let t = this.rules.block.newline.exec(e);
570
+ if (t && t[0].length > 0) return { type: "space", raw: t[0] };
571
+ }
572
+ code(e) {
573
+ let t = this.rules.block.code.exec(e);
574
+ if (t) {
575
+ let n = t[0].replace(this.rules.other.codeRemoveIndent, "");
576
+ return { type: "code", raw: t[0], codeBlockStyle: "indented", text: this.options.pedantic ? n : A(n, `
577
+ `) };
578
+ }
579
+ }
580
+ fences(e) {
581
+ let t = this.rules.block.fences.exec(e);
582
+ if (t) {
583
+ let n = t[0], s = Je(n, t[3] || "", this.rules);
584
+ return { type: "code", raw: n, lang: t[2] ? t[2].trim().replace(this.rules.inline.anyPunctuation, "$1") : t[2], text: s };
585
+ }
586
+ }
587
+ heading(e) {
588
+ let t = this.rules.block.heading.exec(e);
589
+ if (t) {
590
+ let n = t[2].trim();
591
+ if (this.rules.other.endingHash.test(n)) {
592
+ let s = A(n, "#");
593
+ (this.options.pedantic || !s || this.rules.other.endingSpaceChar.test(s)) && (n = s.trim());
594
+ }
595
+ return { type: "heading", raw: t[0], depth: t[1].length, text: n, tokens: this.lexer.inline(n) };
596
+ }
597
+ }
598
+ hr(e) {
599
+ let t = this.rules.block.hr.exec(e);
600
+ if (t) return { type: "hr", raw: A(t[0], `
601
+ `) };
602
+ }
603
+ blockquote(e) {
604
+ let t = this.rules.block.blockquote.exec(e);
605
+ if (t) {
606
+ let n = A(t[0], `
607
+ `).split(`
608
+ `), s = "", i = "", r = [];
609
+ for (; n.length > 0; ) {
610
+ let o = false, l = [], c;
611
+ for (c = 0; c < n.length; c++) if (this.rules.other.blockquoteStart.test(n[c])) l.push(n[c]), o = true;
612
+ else if (!o) l.push(n[c]);
613
+ else break;
614
+ n = n.slice(c);
615
+ let p = l.join(`
616
+ `), u = p.replace(this.rules.other.blockquoteSetextReplace, `
617
+ $1`).replace(this.rules.other.blockquoteSetextReplace2, "");
618
+ s = s ? `${s}
619
+ ${p}` : p, i = i ? `${i}
620
+ ${u}` : u;
621
+ let d = this.lexer.state.top;
622
+ if (this.lexer.state.top = true, this.lexer.blockTokens(u, r, true), this.lexer.state.top = d, n.length === 0) break;
623
+ let g = r.at(-1);
624
+ if (g?.type === "code") break;
625
+ if (g?.type === "blockquote") {
626
+ let x = g, f = x.raw + `
627
+ ` + n.join(`
628
+ `), y = this.blockquote(f);
629
+ r[r.length - 1] = y, s = s.substring(0, s.length - x.raw.length) + y.raw, i = i.substring(0, i.length - x.text.length) + y.text;
630
+ break;
631
+ } else if (g?.type === "list") {
632
+ let x = g, f = x.raw + `
633
+ ` + n.join(`
634
+ `), y = this.list(f);
635
+ r[r.length - 1] = y, s = s.substring(0, s.length - g.raw.length) + y.raw, i = i.substring(0, i.length - x.raw.length) + y.raw, n = f.substring(r.at(-1).raw.length).split(`
636
+ `);
637
+ continue;
638
+ }
639
+ }
640
+ return { type: "blockquote", raw: s, tokens: r, text: i };
641
+ }
642
+ }
643
+ list(e) {
644
+ let t = this.rules.block.list.exec(e);
645
+ if (t) {
646
+ let n = t[1].trim(), s = n.length > 1, i = { type: "list", raw: "", ordered: s, start: s ? +n.slice(0, -1) : "", loose: false, items: [] };
647
+ n = s ? `\\d{1,9}\\${n.slice(-1)}` : `\\${n}`, this.options.pedantic && (n = s ? n : "[*+-]");
648
+ let r = this.rules.other.listItemRegex(n), o = false;
649
+ for (; e; ) {
650
+ let c = false, p = "", u = "";
651
+ if (!(t = r.exec(e)) || this.rules.block.hr.test(e)) break;
652
+ p = t[0], e = e.substring(p.length);
653
+ let d = t[2].split(`
654
+ `, 1)[0].replace(this.rules.other.listReplaceTabs, (Z) => " ".repeat(3 * Z.length)), g = e.split(`
655
+ `, 1)[0], x = !d.trim(), f = 0;
656
+ if (this.options.pedantic ? (f = 2, u = d.trimStart()) : x ? f = t[1].length + 1 : (f = t[2].search(this.rules.other.nonSpaceChar), f = f > 4 ? 1 : f, u = d.slice(f), f += t[1].length), x && this.rules.other.blankLine.test(g) && (p += g + `
657
+ `, e = e.substring(g.length + 1), c = true), !c) {
658
+ let Z = this.rules.other.nextBulletRegex(f), ee = this.rules.other.hrRegex(f), te = this.rules.other.fencesBeginRegex(f), ne = this.rules.other.headingBeginRegex(f), me = this.rules.other.htmlBeginRegex(f);
659
+ for (; e; ) {
660
+ let G = e.split(`
661
+ `, 1)[0], E;
662
+ if (g = G, this.options.pedantic ? (g = g.replace(this.rules.other.listReplaceNesting, " "), E = g) : E = g.replace(this.rules.other.tabCharGlobal, " "), te.test(g) || ne.test(g) || me.test(g) || Z.test(g) || ee.test(g)) break;
663
+ if (E.search(this.rules.other.nonSpaceChar) >= f || !g.trim()) u += `
664
+ ` + E.slice(f);
665
+ else {
666
+ if (x || d.replace(this.rules.other.tabCharGlobal, " ").search(this.rules.other.nonSpaceChar) >= 4 || te.test(d) || ne.test(d) || ee.test(d)) break;
667
+ u += `
668
+ ` + g;
669
+ }
670
+ !x && !g.trim() && (x = true), p += G + `
671
+ `, e = e.substring(G.length + 1), d = E.slice(f);
672
+ }
673
+ }
674
+ i.loose || (o ? i.loose = true : this.rules.other.doubleBlankLine.test(p) && (o = true));
675
+ let y = null, Y;
676
+ this.options.gfm && (y = this.rules.other.listIsTask.exec(u), y && (Y = y[0] !== "[ ] ", u = u.replace(this.rules.other.listReplaceTask, ""))), i.items.push({ type: "list_item", raw: p, task: !!y, checked: Y, loose: false, text: u, tokens: [] }), i.raw += p;
677
+ }
678
+ let l = i.items.at(-1);
679
+ if (l) l.raw = l.raw.trimEnd(), l.text = l.text.trimEnd();
680
+ else return;
681
+ i.raw = i.raw.trimEnd();
682
+ for (let c = 0; c < i.items.length; c++) if (this.lexer.state.top = false, i.items[c].tokens = this.lexer.blockTokens(i.items[c].text, []), !i.loose) {
683
+ let p = i.items[c].tokens.filter((d) => d.type === "space"), u = p.length > 0 && p.some((d) => this.rules.other.anyLine.test(d.raw));
684
+ i.loose = u;
685
+ }
686
+ if (i.loose) for (let c = 0; c < i.items.length; c++) i.items[c].loose = true;
687
+ return i;
688
+ }
689
+ }
690
+ html(e) {
691
+ let t = this.rules.block.html.exec(e);
692
+ if (t) return { type: "html", block: true, raw: t[0], pre: t[1] === "pre" || t[1] === "script" || t[1] === "style", text: t[0] };
693
+ }
694
+ def(e) {
695
+ let t = this.rules.block.def.exec(e);
696
+ if (t) {
697
+ let n = t[1].toLowerCase().replace(this.rules.other.multipleSpaceGlobal, " "), s = t[2] ? t[2].replace(this.rules.other.hrefBrackets, "$1").replace(this.rules.inline.anyPunctuation, "$1") : "", i = t[3] ? t[3].substring(1, t[3].length - 1).replace(this.rules.inline.anyPunctuation, "$1") : t[3];
698
+ return { type: "def", tag: n, raw: t[0], href: s, title: i };
699
+ }
700
+ }
701
+ table(e) {
702
+ let t = this.rules.block.table.exec(e);
703
+ if (!t || !this.rules.other.tableDelimiter.test(t[2])) return;
704
+ let n = V(t[1]), s = t[2].replace(this.rules.other.tableAlignChars, "").split("|"), i = t[3]?.trim() ? t[3].replace(this.rules.other.tableRowBlankLine, "").split(`
705
+ `) : [], r = { type: "table", raw: t[0], header: [], align: [], rows: [] };
706
+ if (n.length === s.length) {
707
+ for (let o of s) this.rules.other.tableAlignRight.test(o) ? r.align.push("right") : this.rules.other.tableAlignCenter.test(o) ? r.align.push("center") : this.rules.other.tableAlignLeft.test(o) ? r.align.push("left") : r.align.push(null);
708
+ for (let o = 0; o < n.length; o++) r.header.push({ text: n[o], tokens: this.lexer.inline(n[o]), header: true, align: r.align[o] });
709
+ for (let o of i) r.rows.push(V(o, r.header.length).map((l, c) => ({ text: l, tokens: this.lexer.inline(l), header: false, align: r.align[c] })));
710
+ return r;
711
+ }
712
+ }
713
+ lheading(e) {
714
+ let t = this.rules.block.lheading.exec(e);
715
+ if (t) return { type: "heading", raw: t[0], depth: t[2].charAt(0) === "=" ? 1 : 2, text: t[1], tokens: this.lexer.inline(t[1]) };
716
+ }
717
+ paragraph(e) {
718
+ let t = this.rules.block.paragraph.exec(e);
719
+ if (t) {
720
+ let n = t[1].charAt(t[1].length - 1) === `
721
+ ` ? t[1].slice(0, -1) : t[1];
722
+ return { type: "paragraph", raw: t[0], text: n, tokens: this.lexer.inline(n) };
723
+ }
724
+ }
725
+ text(e) {
726
+ let t = this.rules.block.text.exec(e);
727
+ if (t) return { type: "text", raw: t[0], text: t[0], tokens: this.lexer.inline(t[0]) };
728
+ }
729
+ escape(e) {
730
+ let t = this.rules.inline.escape.exec(e);
731
+ if (t) return { type: "escape", raw: t[0], text: t[1] };
732
+ }
733
+ tag(e) {
734
+ let t = this.rules.inline.tag.exec(e);
735
+ if (t) return !this.lexer.state.inLink && this.rules.other.startATag.test(t[0]) ? this.lexer.state.inLink = true : this.lexer.state.inLink && this.rules.other.endATag.test(t[0]) && (this.lexer.state.inLink = false), !this.lexer.state.inRawBlock && this.rules.other.startPreScriptTag.test(t[0]) ? this.lexer.state.inRawBlock = true : this.lexer.state.inRawBlock && this.rules.other.endPreScriptTag.test(t[0]) && (this.lexer.state.inRawBlock = false), { type: "html", raw: t[0], inLink: this.lexer.state.inLink, inRawBlock: this.lexer.state.inRawBlock, block: false, text: t[0] };
736
+ }
737
+ link(e) {
738
+ let t = this.rules.inline.link.exec(e);
739
+ if (t) {
740
+ let n = t[2].trim();
741
+ if (!this.options.pedantic && this.rules.other.startAngleBracket.test(n)) {
742
+ if (!this.rules.other.endAngleBracket.test(n)) return;
743
+ let r = A(n.slice(0, -1), "\\");
744
+ if ((n.length - r.length) % 2 === 0) return;
745
+ } else {
746
+ let r = fe(t[2], "()");
747
+ if (r === -2) return;
748
+ if (r > -1) {
749
+ let l = (t[0].indexOf("!") === 0 ? 5 : 4) + t[1].length + r;
750
+ t[2] = t[2].substring(0, r), t[0] = t[0].substring(0, l).trim(), t[3] = "";
751
+ }
752
+ }
753
+ let s = t[2], i = "";
754
+ if (this.options.pedantic) {
755
+ let r = this.rules.other.pedanticHrefTitle.exec(s);
756
+ r && (s = r[1], i = r[3]);
757
+ } else i = t[3] ? t[3].slice(1, -1) : "";
758
+ return s = s.trim(), this.rules.other.startAngleBracket.test(s) && (this.options.pedantic && !this.rules.other.endAngleBracket.test(n) ? s = s.slice(1) : s = s.slice(1, -1)), de(t, { href: s && s.replace(this.rules.inline.anyPunctuation, "$1"), title: i && i.replace(this.rules.inline.anyPunctuation, "$1") }, t[0], this.lexer, this.rules);
759
+ }
760
+ }
761
+ reflink(e, t) {
762
+ let n;
763
+ if ((n = this.rules.inline.reflink.exec(e)) || (n = this.rules.inline.nolink.exec(e))) {
764
+ let s = (n[2] || n[1]).replace(this.rules.other.multipleSpaceGlobal, " "), i = t[s.toLowerCase()];
765
+ if (!i) {
766
+ let r = n[0].charAt(0);
767
+ return { type: "text", raw: r, text: r };
768
+ }
769
+ return de(n, i, n[0], this.lexer, this.rules);
770
+ }
771
+ }
772
+ emStrong(e, t, n = "") {
773
+ let s = this.rules.inline.emStrongLDelim.exec(e);
774
+ if (!s || s[3] && n.match(this.rules.other.unicodeAlphaNumeric)) return;
775
+ if (!(s[1] || s[2] || "") || !n || this.rules.inline.punctuation.exec(n)) {
776
+ let r = [...s[0]].length - 1, o, l, c = r, p = 0, u = s[0][0] === "*" ? this.rules.inline.emStrongRDelimAst : this.rules.inline.emStrongRDelimUnd;
777
+ for (u.lastIndex = 0, t = t.slice(-1 * e.length + r); (s = u.exec(t)) != null; ) {
778
+ if (o = s[1] || s[2] || s[3] || s[4] || s[5] || s[6], !o) continue;
779
+ if (l = [...o].length, s[3] || s[4]) {
780
+ c += l;
781
+ continue;
782
+ } else if ((s[5] || s[6]) && r % 3 && !((r + l) % 3)) {
783
+ p += l;
784
+ continue;
785
+ }
786
+ if (c -= l, c > 0) continue;
787
+ l = Math.min(l, l + c + p);
788
+ let d = [...s[0]][0].length, g = e.slice(0, r + s.index + d + l);
789
+ if (Math.min(r, l) % 2) {
790
+ let f = g.slice(1, -1);
791
+ return { type: "em", raw: g, text: f, tokens: this.lexer.inlineTokens(f) };
792
+ }
793
+ let x = g.slice(2, -2);
794
+ return { type: "strong", raw: g, text: x, tokens: this.lexer.inlineTokens(x) };
795
+ }
796
+ }
797
+ }
798
+ codespan(e) {
799
+ let t = this.rules.inline.code.exec(e);
800
+ if (t) {
801
+ let n = t[2].replace(this.rules.other.newLineCharGlobal, " "), s = this.rules.other.nonSpaceChar.test(n), i = this.rules.other.startingSpaceChar.test(n) && this.rules.other.endingSpaceChar.test(n);
802
+ return s && i && (n = n.substring(1, n.length - 1)), { type: "codespan", raw: t[0], text: n };
803
+ }
804
+ }
805
+ br(e) {
806
+ let t = this.rules.inline.br.exec(e);
807
+ if (t) return { type: "br", raw: t[0] };
808
+ }
809
+ del(e) {
810
+ let t = this.rules.inline.del.exec(e);
811
+ if (t) return { type: "del", raw: t[0], text: t[2], tokens: this.lexer.inlineTokens(t[2]) };
812
+ }
813
+ autolink(e) {
814
+ let t = this.rules.inline.autolink.exec(e);
815
+ if (t) {
816
+ let n, s;
817
+ return t[2] === "@" ? (n = t[1], s = "mailto:" + n) : (n = t[1], s = n), { type: "link", raw: t[0], text: n, href: s, tokens: [{ type: "text", raw: n, text: n }] };
818
+ }
819
+ }
820
+ url(e) {
821
+ let t;
822
+ if (t = this.rules.inline.url.exec(e)) {
823
+ let n, s;
824
+ if (t[2] === "@") n = t[0], s = "mailto:" + n;
825
+ else {
826
+ let i;
827
+ do
828
+ i = t[0], t[0] = this.rules.inline._backpedal.exec(t[0])?.[0] ?? "";
829
+ while (i !== t[0]);
830
+ n = t[0], t[1] === "www." ? s = "http://" + t[0] : s = t[0];
831
+ }
832
+ return { type: "link", raw: t[0], text: n, href: s, tokens: [{ type: "text", raw: n, text: n }] };
833
+ }
834
+ }
835
+ inlineText(e) {
836
+ let t = this.rules.inline.text.exec(e);
837
+ if (t) {
838
+ let n = this.lexer.state.inRawBlock;
839
+ return { type: "text", raw: t[0], text: t[0], escaped: n };
840
+ }
841
+ }
842
+ };
843
+ var b = class a {
844
+ constructor(e) {
845
+ __publicField(this, "tokens");
846
+ __publicField(this, "options");
847
+ __publicField(this, "state");
848
+ __publicField(this, "tokenizer");
849
+ __publicField(this, "inlineQueue");
850
+ this.tokens = [], this.tokens.links = /* @__PURE__ */ Object.create(null), this.options = e || w, this.options.tokenizer = this.options.tokenizer || new S(), this.tokenizer = this.options.tokenizer, this.tokenizer.options = this.options, this.tokenizer.lexer = this, this.inlineQueue = [], this.state = { inLink: false, inRawBlock: false, top: true };
851
+ let t = { other: m, block: O.normal, inline: P.normal };
852
+ this.options.pedantic ? (t.block = O.pedantic, t.inline = P.pedantic) : this.options.gfm && (t.block = O.gfm, this.options.breaks ? t.inline = P.breaks : t.inline = P.gfm), this.tokenizer.rules = t;
853
+ }
854
+ static get rules() {
855
+ return { block: O, inline: P };
856
+ }
857
+ static lex(e, t) {
858
+ return new a(t).lex(e);
859
+ }
860
+ static lexInline(e, t) {
861
+ return new a(t).inlineTokens(e);
862
+ }
863
+ lex(e) {
864
+ e = e.replace(m.carriageReturn, `
865
+ `), this.blockTokens(e, this.tokens);
866
+ for (let t = 0; t < this.inlineQueue.length; t++) {
867
+ let n = this.inlineQueue[t];
868
+ this.inlineTokens(n.src, n.tokens);
869
+ }
870
+ return this.inlineQueue = [], this.tokens;
871
+ }
872
+ blockTokens(e, t = [], n = false) {
873
+ for (this.options.pedantic && (e = e.replace(m.tabCharGlobal, " ").replace(m.spaceLine, "")); e; ) {
874
+ let s;
875
+ if (this.options.extensions?.block?.some((r) => (s = r.call({ lexer: this }, e, t)) ? (e = e.substring(s.raw.length), t.push(s), true) : false)) continue;
876
+ if (s = this.tokenizer.space(e)) {
877
+ e = e.substring(s.raw.length);
878
+ let r = t.at(-1);
879
+ s.raw.length === 1 && r !== void 0 ? r.raw += `
880
+ ` : t.push(s);
881
+ continue;
882
+ }
883
+ if (s = this.tokenizer.code(e)) {
884
+ e = e.substring(s.raw.length);
885
+ let r = t.at(-1);
886
+ r?.type === "paragraph" || r?.type === "text" ? (r.raw += `
887
+ ` + s.raw, r.text += `
888
+ ` + s.text, this.inlineQueue.at(-1).src = r.text) : t.push(s);
889
+ continue;
890
+ }
891
+ if (s = this.tokenizer.fences(e)) {
892
+ e = e.substring(s.raw.length), t.push(s);
893
+ continue;
894
+ }
895
+ if (s = this.tokenizer.heading(e)) {
896
+ e = e.substring(s.raw.length), t.push(s);
897
+ continue;
898
+ }
899
+ if (s = this.tokenizer.hr(e)) {
900
+ e = e.substring(s.raw.length), t.push(s);
901
+ continue;
902
+ }
903
+ if (s = this.tokenizer.blockquote(e)) {
904
+ e = e.substring(s.raw.length), t.push(s);
905
+ continue;
906
+ }
907
+ if (s = this.tokenizer.list(e)) {
908
+ e = e.substring(s.raw.length), t.push(s);
909
+ continue;
910
+ }
911
+ if (s = this.tokenizer.html(e)) {
912
+ e = e.substring(s.raw.length), t.push(s);
913
+ continue;
914
+ }
915
+ if (s = this.tokenizer.def(e)) {
916
+ e = e.substring(s.raw.length);
917
+ let r = t.at(-1);
918
+ r?.type === "paragraph" || r?.type === "text" ? (r.raw += `
919
+ ` + s.raw, r.text += `
920
+ ` + s.raw, this.inlineQueue.at(-1).src = r.text) : this.tokens.links[s.tag] || (this.tokens.links[s.tag] = { href: s.href, title: s.title });
921
+ continue;
922
+ }
923
+ if (s = this.tokenizer.table(e)) {
924
+ e = e.substring(s.raw.length), t.push(s);
925
+ continue;
926
+ }
927
+ if (s = this.tokenizer.lheading(e)) {
928
+ e = e.substring(s.raw.length), t.push(s);
929
+ continue;
930
+ }
931
+ let i = e;
932
+ if (this.options.extensions?.startBlock) {
933
+ let r = 1 / 0, o = e.slice(1), l;
934
+ this.options.extensions.startBlock.forEach((c) => {
935
+ l = c.call({ lexer: this }, o), typeof l == "number" && l >= 0 && (r = Math.min(r, l));
936
+ }), r < 1 / 0 && r >= 0 && (i = e.substring(0, r + 1));
937
+ }
938
+ if (this.state.top && (s = this.tokenizer.paragraph(i))) {
939
+ let r = t.at(-1);
940
+ n && r?.type === "paragraph" ? (r.raw += `
941
+ ` + s.raw, r.text += `
942
+ ` + s.text, this.inlineQueue.pop(), this.inlineQueue.at(-1).src = r.text) : t.push(s), n = i.length !== e.length, e = e.substring(s.raw.length);
943
+ continue;
944
+ }
945
+ if (s = this.tokenizer.text(e)) {
946
+ e = e.substring(s.raw.length);
947
+ let r = t.at(-1);
948
+ r?.type === "text" ? (r.raw += `
949
+ ` + s.raw, r.text += `
950
+ ` + s.text, this.inlineQueue.pop(), this.inlineQueue.at(-1).src = r.text) : t.push(s);
951
+ continue;
952
+ }
953
+ if (e) {
954
+ let r = "Infinite loop on byte: " + e.charCodeAt(0);
955
+ if (this.options.silent) {
956
+ console.error(r);
957
+ break;
958
+ } else throw new Error(r);
959
+ }
960
+ }
961
+ return this.state.top = true, t;
962
+ }
963
+ inline(e, t = []) {
964
+ return this.inlineQueue.push({ src: e, tokens: t }), t;
965
+ }
966
+ inlineTokens(e, t = []) {
967
+ let n = e, s = null;
968
+ if (this.tokens.links) {
969
+ let o = Object.keys(this.tokens.links);
970
+ if (o.length > 0) for (; (s = this.tokenizer.rules.inline.reflinkSearch.exec(n)) != null; ) o.includes(s[0].slice(s[0].lastIndexOf("[") + 1, -1)) && (n = n.slice(0, s.index) + "[" + "a".repeat(s[0].length - 2) + "]" + n.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex));
971
+ }
972
+ for (; (s = this.tokenizer.rules.inline.anyPunctuation.exec(n)) != null; ) n = n.slice(0, s.index) + "++" + n.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex);
973
+ for (; (s = this.tokenizer.rules.inline.blockSkip.exec(n)) != null; ) n = n.slice(0, s.index) + "[" + "a".repeat(s[0].length - 2) + "]" + n.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);
974
+ let i = false, r = "";
975
+ for (; e; ) {
976
+ i || (r = ""), i = false;
977
+ let o;
978
+ if (this.options.extensions?.inline?.some((c) => (o = c.call({ lexer: this }, e, t)) ? (e = e.substring(o.raw.length), t.push(o), true) : false)) continue;
979
+ if (o = this.tokenizer.escape(e)) {
980
+ e = e.substring(o.raw.length), t.push(o);
981
+ continue;
982
+ }
983
+ if (o = this.tokenizer.tag(e)) {
984
+ e = e.substring(o.raw.length), t.push(o);
985
+ continue;
986
+ }
987
+ if (o = this.tokenizer.link(e)) {
988
+ e = e.substring(o.raw.length), t.push(o);
989
+ continue;
990
+ }
991
+ if (o = this.tokenizer.reflink(e, this.tokens.links)) {
992
+ e = e.substring(o.raw.length);
993
+ let c = t.at(-1);
994
+ o.type === "text" && c?.type === "text" ? (c.raw += o.raw, c.text += o.text) : t.push(o);
995
+ continue;
996
+ }
997
+ if (o = this.tokenizer.emStrong(e, n, r)) {
998
+ e = e.substring(o.raw.length), t.push(o);
999
+ continue;
1000
+ }
1001
+ if (o = this.tokenizer.codespan(e)) {
1002
+ e = e.substring(o.raw.length), t.push(o);
1003
+ continue;
1004
+ }
1005
+ if (o = this.tokenizer.br(e)) {
1006
+ e = e.substring(o.raw.length), t.push(o);
1007
+ continue;
1008
+ }
1009
+ if (o = this.tokenizer.del(e)) {
1010
+ e = e.substring(o.raw.length), t.push(o);
1011
+ continue;
1012
+ }
1013
+ if (o = this.tokenizer.autolink(e)) {
1014
+ e = e.substring(o.raw.length), t.push(o);
1015
+ continue;
1016
+ }
1017
+ if (!this.state.inLink && (o = this.tokenizer.url(e))) {
1018
+ e = e.substring(o.raw.length), t.push(o);
1019
+ continue;
1020
+ }
1021
+ let l = e;
1022
+ if (this.options.extensions?.startInline) {
1023
+ let c = 1 / 0, p = e.slice(1), u;
1024
+ this.options.extensions.startInline.forEach((d) => {
1025
+ u = d.call({ lexer: this }, p), typeof u == "number" && u >= 0 && (c = Math.min(c, u));
1026
+ }), c < 1 / 0 && c >= 0 && (l = e.substring(0, c + 1));
1027
+ }
1028
+ if (o = this.tokenizer.inlineText(l)) {
1029
+ e = e.substring(o.raw.length), o.raw.slice(-1) !== "_" && (r = o.raw.slice(-1)), i = true;
1030
+ let c = t.at(-1);
1031
+ c?.type === "text" ? (c.raw += o.raw, c.text += o.text) : t.push(o);
1032
+ continue;
1033
+ }
1034
+ if (e) {
1035
+ let c = "Infinite loop on byte: " + e.charCodeAt(0);
1036
+ if (this.options.silent) {
1037
+ console.error(c);
1038
+ break;
1039
+ } else throw new Error(c);
1040
+ }
1041
+ }
1042
+ return t;
1043
+ }
1044
+ };
1045
+ var $ = class {
1046
+ constructor(e) {
1047
+ __publicField(this, "options");
1048
+ __publicField(this, "parser");
1049
+ this.options = e || w;
1050
+ }
1051
+ space(e) {
1052
+ return "";
1053
+ }
1054
+ code({ text: e, lang: t, escaped: n }) {
1055
+ let s = (t || "").match(m.notSpaceStart)?.[0], i = e.replace(m.endingNewline, "") + `
1056
+ `;
1057
+ return s ? '<pre><code class="language-' + R(s) + '">' + (n ? i : R(i, true)) + `</code></pre>
1058
+ ` : "<pre><code>" + (n ? i : R(i, true)) + `</code></pre>
1059
+ `;
1060
+ }
1061
+ blockquote({ tokens: e }) {
1062
+ return `<blockquote>
1063
+ ${this.parser.parse(e)}</blockquote>
1064
+ `;
1065
+ }
1066
+ html({ text: e }) {
1067
+ return e;
1068
+ }
1069
+ heading({ tokens: e, depth: t }) {
1070
+ return `<h${t}>${this.parser.parseInline(e)}</h${t}>
1071
+ `;
1072
+ }
1073
+ hr(e) {
1074
+ return `<hr>
1075
+ `;
1076
+ }
1077
+ list(e) {
1078
+ let t = e.ordered, n = e.start, s = "";
1079
+ for (let o = 0; o < e.items.length; o++) {
1080
+ let l = e.items[o];
1081
+ s += this.listitem(l);
1082
+ }
1083
+ let i = t ? "ol" : "ul", r = t && n !== 1 ? ' start="' + n + '"' : "";
1084
+ return "<" + i + r + `>
1085
+ ` + s + "</" + i + `>
1086
+ `;
1087
+ }
1088
+ listitem(e) {
1089
+ let t = "";
1090
+ if (e.task) {
1091
+ let n = this.checkbox({ checked: !!e.checked });
1092
+ e.loose ? e.tokens[0]?.type === "paragraph" ? (e.tokens[0].text = n + " " + e.tokens[0].text, e.tokens[0].tokens && e.tokens[0].tokens.length > 0 && e.tokens[0].tokens[0].type === "text" && (e.tokens[0].tokens[0].text = n + " " + R(e.tokens[0].tokens[0].text), e.tokens[0].tokens[0].escaped = true)) : e.tokens.unshift({ type: "text", raw: n + " ", text: n + " ", escaped: true }) : t += n + " ";
1093
+ }
1094
+ return t += this.parser.parse(e.tokens, !!e.loose), `<li>${t}</li>
1095
+ `;
1096
+ }
1097
+ checkbox({ checked: e }) {
1098
+ return "<input " + (e ? 'checked="" ' : "") + 'disabled="" type="checkbox">';
1099
+ }
1100
+ paragraph({ tokens: e }) {
1101
+ return `<p>${this.parser.parseInline(e)}</p>
1102
+ `;
1103
+ }
1104
+ table(e) {
1105
+ let t = "", n = "";
1106
+ for (let i = 0; i < e.header.length; i++) n += this.tablecell(e.header[i]);
1107
+ t += this.tablerow({ text: n });
1108
+ let s = "";
1109
+ for (let i = 0; i < e.rows.length; i++) {
1110
+ let r = e.rows[i];
1111
+ n = "";
1112
+ for (let o = 0; o < r.length; o++) n += this.tablecell(r[o]);
1113
+ s += this.tablerow({ text: n });
1114
+ }
1115
+ return s && (s = `<tbody>${s}</tbody>`), `<table>
1116
+ <thead>
1117
+ ` + t + `</thead>
1118
+ ` + s + `</table>
1119
+ `;
1120
+ }
1121
+ tablerow({ text: e }) {
1122
+ return `<tr>
1123
+ ${e}</tr>
1124
+ `;
1125
+ }
1126
+ tablecell(e) {
1127
+ let t = this.parser.parseInline(e.tokens), n = e.header ? "th" : "td";
1128
+ return (e.align ? `<${n} align="${e.align}">` : `<${n}>`) + t + `</${n}>
1129
+ `;
1130
+ }
1131
+ strong({ tokens: e }) {
1132
+ return `<strong>${this.parser.parseInline(e)}</strong>`;
1133
+ }
1134
+ em({ tokens: e }) {
1135
+ return `<em>${this.parser.parseInline(e)}</em>`;
1136
+ }
1137
+ codespan({ text: e }) {
1138
+ return `<code>${R(e, true)}</code>`;
1139
+ }
1140
+ br(e) {
1141
+ return "<br>";
1142
+ }
1143
+ del({ tokens: e }) {
1144
+ return `<del>${this.parser.parseInline(e)}</del>`;
1145
+ }
1146
+ link({ href: e, title: t, tokens: n }) {
1147
+ let s = this.parser.parseInline(n), i = J(e);
1148
+ if (i === null) return s;
1149
+ e = i;
1150
+ let r = '<a href="' + e + '"';
1151
+ return t && (r += ' title="' + R(t) + '"'), r += ">" + s + "</a>", r;
1152
+ }
1153
+ image({ href: e, title: t, text: n, tokens: s }) {
1154
+ s && (n = this.parser.parseInline(s, this.parser.textRenderer));
1155
+ let i = J(e);
1156
+ if (i === null) return R(n);
1157
+ e = i;
1158
+ let r = `<img src="${e}" alt="${n}"`;
1159
+ return t && (r += ` title="${R(t)}"`), r += ">", r;
1160
+ }
1161
+ text(e) {
1162
+ return "tokens" in e && e.tokens ? this.parser.parseInline(e.tokens) : "escaped" in e && e.escaped ? e.text : R(e.text);
1163
+ }
1164
+ };
1165
+ var _ = class {
1166
+ strong({ text: e }) {
1167
+ return e;
1168
+ }
1169
+ em({ text: e }) {
1170
+ return e;
1171
+ }
1172
+ codespan({ text: e }) {
1173
+ return e;
1174
+ }
1175
+ del({ text: e }) {
1176
+ return e;
1177
+ }
1178
+ html({ text: e }) {
1179
+ return e;
1180
+ }
1181
+ text({ text: e }) {
1182
+ return e;
1183
+ }
1184
+ link({ text: e }) {
1185
+ return "" + e;
1186
+ }
1187
+ image({ text: e }) {
1188
+ return "" + e;
1189
+ }
1190
+ br() {
1191
+ return "";
1192
+ }
1193
+ };
1194
+ var T = class a2 {
1195
+ constructor(e) {
1196
+ __publicField(this, "options");
1197
+ __publicField(this, "renderer");
1198
+ __publicField(this, "textRenderer");
1199
+ this.options = e || w, this.options.renderer = this.options.renderer || new $(), this.renderer = this.options.renderer, this.renderer.options = this.options, this.renderer.parser = this, this.textRenderer = new _();
1200
+ }
1201
+ static parse(e, t) {
1202
+ return new a2(t).parse(e);
1203
+ }
1204
+ static parseInline(e, t) {
1205
+ return new a2(t).parseInline(e);
1206
+ }
1207
+ parse(e, t = true) {
1208
+ let n = "";
1209
+ for (let s = 0; s < e.length; s++) {
1210
+ let i = e[s];
1211
+ if (this.options.extensions?.renderers?.[i.type]) {
1212
+ let o = i, l = this.options.extensions.renderers[o.type].call({ parser: this }, o);
1213
+ if (l !== false || !["space", "hr", "heading", "code", "table", "blockquote", "list", "html", "paragraph", "text"].includes(o.type)) {
1214
+ n += l || "";
1215
+ continue;
1216
+ }
1217
+ }
1218
+ let r = i;
1219
+ switch (r.type) {
1220
+ case "space": {
1221
+ n += this.renderer.space(r);
1222
+ continue;
1223
+ }
1224
+ case "hr": {
1225
+ n += this.renderer.hr(r);
1226
+ continue;
1227
+ }
1228
+ case "heading": {
1229
+ n += this.renderer.heading(r);
1230
+ continue;
1231
+ }
1232
+ case "code": {
1233
+ n += this.renderer.code(r);
1234
+ continue;
1235
+ }
1236
+ case "table": {
1237
+ n += this.renderer.table(r);
1238
+ continue;
1239
+ }
1240
+ case "blockquote": {
1241
+ n += this.renderer.blockquote(r);
1242
+ continue;
1243
+ }
1244
+ case "list": {
1245
+ n += this.renderer.list(r);
1246
+ continue;
1247
+ }
1248
+ case "html": {
1249
+ n += this.renderer.html(r);
1250
+ continue;
1251
+ }
1252
+ case "paragraph": {
1253
+ n += this.renderer.paragraph(r);
1254
+ continue;
1255
+ }
1256
+ case "text": {
1257
+ let o = r, l = this.renderer.text(o);
1258
+ for (; s + 1 < e.length && e[s + 1].type === "text"; ) o = e[++s], l += `
1259
+ ` + this.renderer.text(o);
1260
+ t ? n += this.renderer.paragraph({ type: "paragraph", raw: l, text: l, tokens: [{ type: "text", raw: l, text: l, escaped: true }] }) : n += l;
1261
+ continue;
1262
+ }
1263
+ default: {
1264
+ let o = 'Token with "' + r.type + '" type was not found.';
1265
+ if (this.options.silent) return console.error(o), "";
1266
+ throw new Error(o);
1267
+ }
1268
+ }
1269
+ }
1270
+ return n;
1271
+ }
1272
+ parseInline(e, t = this.renderer) {
1273
+ let n = "";
1274
+ for (let s = 0; s < e.length; s++) {
1275
+ let i = e[s];
1276
+ if (this.options.extensions?.renderers?.[i.type]) {
1277
+ let o = this.options.extensions.renderers[i.type].call({ parser: this }, i);
1278
+ if (o !== false || !["escape", "html", "link", "image", "strong", "em", "codespan", "br", "del", "text"].includes(i.type)) {
1279
+ n += o || "";
1280
+ continue;
1281
+ }
1282
+ }
1283
+ let r = i;
1284
+ switch (r.type) {
1285
+ case "escape": {
1286
+ n += t.text(r);
1287
+ break;
1288
+ }
1289
+ case "html": {
1290
+ n += t.html(r);
1291
+ break;
1292
+ }
1293
+ case "link": {
1294
+ n += t.link(r);
1295
+ break;
1296
+ }
1297
+ case "image": {
1298
+ n += t.image(r);
1299
+ break;
1300
+ }
1301
+ case "strong": {
1302
+ n += t.strong(r);
1303
+ break;
1304
+ }
1305
+ case "em": {
1306
+ n += t.em(r);
1307
+ break;
1308
+ }
1309
+ case "codespan": {
1310
+ n += t.codespan(r);
1311
+ break;
1312
+ }
1313
+ case "br": {
1314
+ n += t.br(r);
1315
+ break;
1316
+ }
1317
+ case "del": {
1318
+ n += t.del(r);
1319
+ break;
1320
+ }
1321
+ case "text": {
1322
+ n += t.text(r);
1323
+ break;
1324
+ }
1325
+ default: {
1326
+ let o = 'Token with "' + r.type + '" type was not found.';
1327
+ if (this.options.silent) return console.error(o), "";
1328
+ throw new Error(o);
1329
+ }
1330
+ }
1331
+ }
1332
+ return n;
1333
+ }
1334
+ };
1335
+ var _a;
1336
+ var L = (_a = class {
1337
+ constructor(e) {
1338
+ __publicField(this, "options");
1339
+ __publicField(this, "block");
1340
+ this.options = e || w;
1341
+ }
1342
+ preprocess(e) {
1343
+ return e;
1344
+ }
1345
+ postprocess(e) {
1346
+ return e;
1347
+ }
1348
+ processAllTokens(e) {
1349
+ return e;
1350
+ }
1351
+ provideLexer() {
1352
+ return this.block ? b.lex : b.lexInline;
1353
+ }
1354
+ provideParser() {
1355
+ return this.block ? T.parse : T.parseInline;
1356
+ }
1357
+ }, __publicField(_a, "passThroughHooks", /* @__PURE__ */ new Set(["preprocess", "postprocess", "processAllTokens"])), _a);
1358
+ var B = class {
1359
+ constructor(...e) {
1360
+ __publicField(this, "defaults", M());
1361
+ __publicField(this, "options", this.setOptions);
1362
+ __publicField(this, "parse", this.parseMarkdown(true));
1363
+ __publicField(this, "parseInline", this.parseMarkdown(false));
1364
+ __publicField(this, "Parser", T);
1365
+ __publicField(this, "Renderer", $);
1366
+ __publicField(this, "TextRenderer", _);
1367
+ __publicField(this, "Lexer", b);
1368
+ __publicField(this, "Tokenizer", S);
1369
+ __publicField(this, "Hooks", L);
1370
+ this.use(...e);
1371
+ }
1372
+ walkTokens(e, t) {
1373
+ let n = [];
1374
+ for (let s of e) switch (n = n.concat(t.call(this, s)), s.type) {
1375
+ case "table": {
1376
+ let i = s;
1377
+ for (let r of i.header) n = n.concat(this.walkTokens(r.tokens, t));
1378
+ for (let r of i.rows) for (let o of r) n = n.concat(this.walkTokens(o.tokens, t));
1379
+ break;
1380
+ }
1381
+ case "list": {
1382
+ let i = s;
1383
+ n = n.concat(this.walkTokens(i.items, t));
1384
+ break;
1385
+ }
1386
+ default: {
1387
+ let i = s;
1388
+ this.defaults.extensions?.childTokens?.[i.type] ? this.defaults.extensions.childTokens[i.type].forEach((r) => {
1389
+ let o = i[r].flat(1 / 0);
1390
+ n = n.concat(this.walkTokens(o, t));
1391
+ }) : i.tokens && (n = n.concat(this.walkTokens(i.tokens, t)));
1392
+ }
1393
+ }
1394
+ return n;
1395
+ }
1396
+ use(...e) {
1397
+ let t = this.defaults.extensions || { renderers: {}, childTokens: {} };
1398
+ return e.forEach((n) => {
1399
+ let s = { ...n };
1400
+ if (s.async = this.defaults.async || s.async || false, n.extensions && (n.extensions.forEach((i) => {
1401
+ if (!i.name) throw new Error("extension name required");
1402
+ if ("renderer" in i) {
1403
+ let r = t.renderers[i.name];
1404
+ r ? t.renderers[i.name] = function(...o) {
1405
+ let l = i.renderer.apply(this, o);
1406
+ return l === false && (l = r.apply(this, o)), l;
1407
+ } : t.renderers[i.name] = i.renderer;
1408
+ }
1409
+ if ("tokenizer" in i) {
1410
+ if (!i.level || i.level !== "block" && i.level !== "inline") throw new Error("extension level must be 'block' or 'inline'");
1411
+ let r = t[i.level];
1412
+ r ? r.unshift(i.tokenizer) : t[i.level] = [i.tokenizer], i.start && (i.level === "block" ? t.startBlock ? t.startBlock.push(i.start) : t.startBlock = [i.start] : i.level === "inline" && (t.startInline ? t.startInline.push(i.start) : t.startInline = [i.start]));
1413
+ }
1414
+ "childTokens" in i && i.childTokens && (t.childTokens[i.name] = i.childTokens);
1415
+ }), s.extensions = t), n.renderer) {
1416
+ let i = this.defaults.renderer || new $(this.defaults);
1417
+ for (let r in n.renderer) {
1418
+ if (!(r in i)) throw new Error(`renderer '${r}' does not exist`);
1419
+ if (["options", "parser"].includes(r)) continue;
1420
+ let o = r, l = n.renderer[o], c = i[o];
1421
+ i[o] = (...p) => {
1422
+ let u = l.apply(i, p);
1423
+ return u === false && (u = c.apply(i, p)), u || "";
1424
+ };
1425
+ }
1426
+ s.renderer = i;
1427
+ }
1428
+ if (n.tokenizer) {
1429
+ let i = this.defaults.tokenizer || new S(this.defaults);
1430
+ for (let r in n.tokenizer) {
1431
+ if (!(r in i)) throw new Error(`tokenizer '${r}' does not exist`);
1432
+ if (["options", "rules", "lexer"].includes(r)) continue;
1433
+ let o = r, l = n.tokenizer[o], c = i[o];
1434
+ i[o] = (...p) => {
1435
+ let u = l.apply(i, p);
1436
+ return u === false && (u = c.apply(i, p)), u;
1437
+ };
1438
+ }
1439
+ s.tokenizer = i;
1440
+ }
1441
+ if (n.hooks) {
1442
+ let i = this.defaults.hooks || new L();
1443
+ for (let r in n.hooks) {
1444
+ if (!(r in i)) throw new Error(`hook '${r}' does not exist`);
1445
+ if (["options", "block"].includes(r)) continue;
1446
+ let o = r, l = n.hooks[o], c = i[o];
1447
+ L.passThroughHooks.has(r) ? i[o] = (p) => {
1448
+ if (this.defaults.async) return Promise.resolve(l.call(i, p)).then((d) => c.call(i, d));
1449
+ let u = l.call(i, p);
1450
+ return c.call(i, u);
1451
+ } : i[o] = (...p) => {
1452
+ let u = l.apply(i, p);
1453
+ return u === false && (u = c.apply(i, p)), u;
1454
+ };
1455
+ }
1456
+ s.hooks = i;
1457
+ }
1458
+ if (n.walkTokens) {
1459
+ let i = this.defaults.walkTokens, r = n.walkTokens;
1460
+ s.walkTokens = function(o) {
1461
+ let l = [];
1462
+ return l.push(r.call(this, o)), i && (l = l.concat(i.call(this, o))), l;
1463
+ };
1464
+ }
1465
+ this.defaults = { ...this.defaults, ...s };
1466
+ }), this;
1467
+ }
1468
+ setOptions(e) {
1469
+ return this.defaults = { ...this.defaults, ...e }, this;
1470
+ }
1471
+ lexer(e, t) {
1472
+ return b.lex(e, t ?? this.defaults);
1473
+ }
1474
+ parser(e, t) {
1475
+ return T.parse(e, t ?? this.defaults);
1476
+ }
1477
+ parseMarkdown(e) {
1478
+ return (n, s) => {
1479
+ let i = { ...s }, r = { ...this.defaults, ...i }, o = this.onError(!!r.silent, !!r.async);
1480
+ if (this.defaults.async === true && i.async === false) return o(new Error("marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise."));
1481
+ if (typeof n > "u" || n === null) return o(new Error("marked(): input parameter is undefined or null"));
1482
+ if (typeof n != "string") return o(new Error("marked(): input parameter is of type " + Object.prototype.toString.call(n) + ", string expected"));
1483
+ r.hooks && (r.hooks.options = r, r.hooks.block = e);
1484
+ let l = r.hooks ? r.hooks.provideLexer() : e ? b.lex : b.lexInline, c = r.hooks ? r.hooks.provideParser() : e ? T.parse : T.parseInline;
1485
+ if (r.async) return Promise.resolve(r.hooks ? r.hooks.preprocess(n) : n).then((p) => l(p, r)).then((p) => r.hooks ? r.hooks.processAllTokens(p) : p).then((p) => r.walkTokens ? Promise.all(this.walkTokens(p, r.walkTokens)).then(() => p) : p).then((p) => c(p, r)).then((p) => r.hooks ? r.hooks.postprocess(p) : p).catch(o);
1486
+ try {
1487
+ r.hooks && (n = r.hooks.preprocess(n));
1488
+ let p = l(n, r);
1489
+ r.hooks && (p = r.hooks.processAllTokens(p)), r.walkTokens && this.walkTokens(p, r.walkTokens);
1490
+ let u = c(p, r);
1491
+ return r.hooks && (u = r.hooks.postprocess(u)), u;
1492
+ } catch (p) {
1493
+ return o(p);
1494
+ }
1495
+ };
1496
+ }
1497
+ onError(e, t) {
1498
+ return (n) => {
1499
+ if (n.message += `
1500
+ Please report this to https://github.com/markedjs/marked.`, e) {
1501
+ let s = "<p>An error occurred:</p><pre>" + R(n.message + "", true) + "</pre>";
1502
+ return t ? Promise.resolve(s) : s;
1503
+ }
1504
+ if (t) return Promise.reject(n);
1505
+ throw n;
1506
+ };
1507
+ }
1508
+ };
1509
+ var z = new B();
1510
+ function k(a3, e) {
1511
+ return z.parse(a3, e);
1512
+ }
1513
+ k.options = k.setOptions = function(a3) {
1514
+ return z.setOptions(a3), k.defaults = z.defaults, H(k.defaults), k;
1515
+ };
1516
+ k.getDefaults = M;
1517
+ k.defaults = w;
1518
+ k.use = function(...a3) {
1519
+ return z.use(...a3), k.defaults = z.defaults, H(k.defaults), k;
1520
+ };
1521
+ k.walkTokens = function(a3, e) {
1522
+ return z.walkTokens(a3, e);
1523
+ };
1524
+ k.parseInline = z.parseInline;
1525
+ k.Parser = T;
1526
+ k.parser = T.parse;
1527
+ k.Renderer = $;
1528
+ k.TextRenderer = _;
1529
+ k.Lexer = b;
1530
+ k.lexer = b.lex;
1531
+ k.Tokenizer = S;
1532
+ k.Hooks = L;
1533
+ k.parse = k;
1534
+ var Dt = k.options;
1535
+ var Zt = k.setOptions;
1536
+ var Gt = k.use;
1537
+ var Ht = k.walkTokens;
1538
+ var Nt = k.parseInline;
1539
+ var Ft = T.parse;
1540
+ var Qt = b.lex;
1541
+
1542
+ // src/helpers/markdownConverter.ts
1543
+ function convertMarkdownToHtml(markdownPath, htmlOutputPath, stepsError, resultError) {
1544
+ const hasMarkdown = import_fs3.default.existsSync(markdownPath);
1545
+ const markdownContent = hasMarkdown ? import_fs3.default.readFileSync(markdownPath, "utf-8") : "";
1546
+ const markdownHtml = hasMarkdown ? k(markdownContent) : "";
1547
+ const stepsHtml = stepsError.filter((step) => step.snippet?.trim()).map(
1548
+ (step) => `
1549
+ <div>
1550
+ <pre><code>${step.snippet}</code></pre>
1551
+ ${step.location ? `<p><em>Location: ${escapeHtml(step.location)}</em></p>` : ""}
1552
+ </div>`
1553
+ ).join("\n");
1554
+ const errorHtml = resultError.map((error) => `<pre><code>${error}</code></pre>`).join("\n");
1555
+ const fullHtml = `
1556
+ <!DOCTYPE html>
1557
+ <html lang="en">
1558
+ <head>
1559
+ <meta charset="UTF-8" />
1560
+ <title>Ortoni Error Report</title>
1561
+ <style>
1562
+ body { font-family: sans-serif; padding: 2rem; line-height: 1.6; max-width: 900px; margin: auto; }
1563
+ code, pre { background: #f4f4f4; padding: 0.5rem; border-radius: 5px; display: block; overflow-x: auto; }
1564
+ h1, h2, h3 { color: #444; }
1565
+ hr { margin: 2em 0; }
1566
+ </style>
1567
+ </head>
1568
+ <body>
1569
+ <h1>Instructions</h1>
1570
+ <ul>
1571
+ <li>Following Playwright test failed.</li>
1572
+ <li>Explain why, be concise, respect Playwright best practices.</li>
1573
+ <li>Provide a snippet of code with the fix, if possible.</li>
1574
+ </ul>
1575
+ <h1>Error Details</h1>
1576
+ ${errorHtml || "<p>No errors found.</p>"}
1577
+ ${stepsHtml || "<p>No step data available.</p>"}
1578
+ ${markdownHtml ? `${markdownHtml}` : ""}
1579
+ </body>
1580
+ </html>
1581
+ `;
1582
+ import_fs3.default.writeFileSync(htmlOutputPath, fullHtml, "utf-8");
1583
+ if (hasMarkdown) {
1584
+ import_fs3.default.unlinkSync(markdownPath);
1585
+ }
1586
+ }
1587
+
1588
+ // src/utils/attachFiles.ts
1589
+ function attachFiles(subFolder, result, testResult, config, steps, errors) {
361
1590
  const folderPath = config.folderPath || "ortoni-report";
362
- const attachmentsFolder = import_path4.default.join(folderPath, "ortoni-data", "attachments", subFolder);
363
- if (!import_fs3.default.existsSync(attachmentsFolder)) {
364
- import_fs3.default.mkdirSync(attachmentsFolder, { recursive: true });
1591
+ const attachmentsFolder = import_path4.default.join(
1592
+ folderPath,
1593
+ "ortoni-data",
1594
+ "attachments",
1595
+ subFolder
1596
+ );
1597
+ if (!import_fs4.default.existsSync(attachmentsFolder)) {
1598
+ import_fs4.default.mkdirSync(attachmentsFolder, { recursive: true });
365
1599
  }
366
1600
  if (!result.attachments) return;
367
1601
  const { base64Image } = config;
@@ -370,14 +1604,48 @@ function attachFiles(subFolder, result, testResult, config) {
370
1604
  const { contentType, name, path: attachmentPath, body } = attachment;
371
1605
  if (!attachmentPath && !body) return;
372
1606
  const fileName = attachmentPath ? import_path4.default.basename(attachmentPath) : `${name}.${getFileExtension(contentType)}`;
373
- const relativePath = import_path4.default.join("ortoni-data", "attachments", subFolder, fileName);
1607
+ const relativePath = import_path4.default.join(
1608
+ "ortoni-data",
1609
+ "attachments",
1610
+ subFolder,
1611
+ fileName
1612
+ );
374
1613
  const fullPath = import_path4.default.join(attachmentsFolder, fileName);
375
1614
  if (contentType === "image/png") {
376
- handleImage(attachmentPath, body, base64Image, fullPath, relativePath, testResult);
1615
+ handleImage(
1616
+ attachmentPath,
1617
+ body,
1618
+ base64Image,
1619
+ fullPath,
1620
+ relativePath,
1621
+ testResult
1622
+ );
377
1623
  } else if (name === "video") {
378
- handleAttachment(attachmentPath, fullPath, relativePath, "videoPath", testResult);
1624
+ handleAttachment(
1625
+ attachmentPath,
1626
+ fullPath,
1627
+ relativePath,
1628
+ "videoPath",
1629
+ testResult
1630
+ );
379
1631
  } else if (name === "trace") {
380
- handleAttachment(attachmentPath, fullPath, relativePath, "tracePath", testResult);
1632
+ handleAttachment(
1633
+ attachmentPath,
1634
+ fullPath,
1635
+ relativePath,
1636
+ "tracePath",
1637
+ testResult
1638
+ );
1639
+ } else if (name === "error-context") {
1640
+ handleAttachment(
1641
+ attachmentPath,
1642
+ fullPath,
1643
+ relativePath,
1644
+ "markdownPath",
1645
+ testResult,
1646
+ steps,
1647
+ errors
1648
+ );
381
1649
  }
382
1650
  });
383
1651
  }
@@ -385,13 +1653,19 @@ function handleImage(attachmentPath, body, base64Image, fullPath, relativePath,
385
1653
  let screenshotPath = "";
386
1654
  if (attachmentPath) {
387
1655
  try {
388
- const screenshotContent = import_fs3.default.readFileSync(attachmentPath, base64Image ? "base64" : void 0);
1656
+ const screenshotContent = import_fs4.default.readFileSync(
1657
+ attachmentPath,
1658
+ base64Image ? "base64" : void 0
1659
+ );
389
1660
  screenshotPath = base64Image ? `data:image/png;base64,${screenshotContent}` : relativePath;
390
1661
  if (!base64Image) {
391
- import_fs3.default.copyFileSync(attachmentPath, fullPath);
1662
+ import_fs4.default.copyFileSync(attachmentPath, fullPath);
392
1663
  }
393
1664
  } catch (error) {
394
- console.error(`OrtoniReport: Failed to read screenshot file: ${attachmentPath}`, error);
1665
+ console.error(
1666
+ `OrtoniReport: Failed to read screenshot file: ${attachmentPath}`,
1667
+ error
1668
+ );
395
1669
  }
396
1670
  } else if (body) {
397
1671
  screenshotPath = `data:image/png;base64,${body.toString("base64")}`;
@@ -400,17 +1674,25 @@ function handleImage(attachmentPath, body, base64Image, fullPath, relativePath,
400
1674
  testResult.screenshots?.push(screenshotPath);
401
1675
  }
402
1676
  }
403
- function handleAttachment(attachmentPath, fullPath, relativePath, resultKey, testResult) {
1677
+ function handleAttachment(attachmentPath, fullPath, relativePath, resultKey, testResult, steps, errors) {
404
1678
  if (attachmentPath) {
405
- import_fs3.default.copyFileSync(attachmentPath, fullPath);
1679
+ import_fs4.default.copyFileSync(attachmentPath, fullPath);
406
1680
  testResult[resultKey] = relativePath;
407
1681
  }
1682
+ if (resultKey === "markdownPath" && errors) {
1683
+ const htmlPath = fullPath.replace(/\.md$/, ".html");
1684
+ const htmlRelativePath = relativePath.replace(/\.md$/, ".html");
1685
+ convertMarkdownToHtml(fullPath, htmlPath, steps || [], errors || []);
1686
+ testResult[resultKey] = htmlRelativePath;
1687
+ return;
1688
+ }
408
1689
  }
409
1690
  function getFileExtension(contentType) {
410
1691
  const extensions = {
411
1692
  "image/png": "png",
412
1693
  "video/webm": "webm",
413
- "application/zip": "zip"
1694
+ "application/zip": "zip",
1695
+ "text/markdown": "md"
414
1696
  };
415
1697
  return extensions[contentType] || "unknown";
416
1698
  }
@@ -443,14 +1725,27 @@ var TestResultProcessor = class {
443
1725
  status,
444
1726
  flaky: test.outcome(),
445
1727
  duration: msToTime(result.duration),
446
- errors: result.errors.map((e) => this.ansiToHtml.toHtml(escapeHtml(e.stack || e.toString()))),
1728
+ errors: result.errors.map(
1729
+ (e) => this.ansiToHtml.toHtml(escapeHtml(e.stack || e.toString()))
1730
+ ),
447
1731
  steps: this.processSteps(result.steps),
448
- logs: this.ansiToHtml.toHtml(escapeHtml(result.stdout.concat(result.stderr).map((log) => log).join("\n"))),
1732
+ logs: this.ansiToHtml.toHtml(
1733
+ escapeHtml(
1734
+ result.stdout.concat(result.stderr).map((log) => log).join("\n")
1735
+ )
1736
+ ),
449
1737
  filePath,
450
1738
  filters: projectSet,
451
1739
  base64Image: ortoniConfig.base64Image
452
1740
  };
453
- attachFiles(test.id, result, testResult, ortoniConfig);
1741
+ attachFiles(
1742
+ test.id,
1743
+ result,
1744
+ testResult,
1745
+ ortoniConfig,
1746
+ testResult.steps,
1747
+ testResult.errors
1748
+ );
454
1749
  return testResult;
455
1750
  }
456
1751
  processSteps(steps) {
@@ -482,8 +1777,10 @@ function startReportServer(reportFolder, reportFilename, port = 2004, open2) {
482
1777
  });
483
1778
  try {
484
1779
  const server = app.listen(port, () => {
485
- console.log(`Server is running at http://localhost:${port}
486
- Press Ctrl+C to stop.`);
1780
+ console.log(
1781
+ `Server is running at http://localhost:${port}
1782
+ Press Ctrl+C to stop.`
1783
+ );
487
1784
  if (open2 === "always" || open2 === "on-failure") {
488
1785
  try {
489
1786
  openBrowser(`http://localhost:${port}`);
@@ -494,7 +1791,9 @@ Press Ctrl+C to stop.`);
494
1791
  });
495
1792
  server.on("error", (error) => {
496
1793
  if (error.code === "EADDRINUSE") {
497
- console.error(`Ortoni-Report: Port ${port} is already in use. Trying a different port...`);
1794
+ console.error(
1795
+ `Ortoni-Report: Port ${port} is already in use. Trying a different port...`
1796
+ );
498
1797
  } else {
499
1798
  console.error("Ortoni-Report: Server error:", error);
500
1799
  }
@@ -606,7 +1905,7 @@ var DatabaseManager = class {
606
1905
  return null;
607
1906
  }
608
1907
  try {
609
- const runDate = formatDateUTC(/* @__PURE__ */ new Date());
1908
+ const runDate = (/* @__PURE__ */ new Date()).toISOString();
610
1909
  const { lastID } = await this.db.run(
611
1910
  `
612
1911
  INSERT INTO test_runs (run_date)
@@ -684,6 +1983,130 @@ var DatabaseManager = class {
684
1983
  }
685
1984
  }
686
1985
  }
1986
+ async getSummaryData() {
1987
+ if (!this.db) {
1988
+ console.error("OrtoniReport: Database not initialized");
1989
+ return {
1990
+ totalRuns: 0,
1991
+ totalTests: 0,
1992
+ passed: 0,
1993
+ failed: 0,
1994
+ passRate: 0,
1995
+ avgDuration: 0
1996
+ };
1997
+ }
1998
+ try {
1999
+ const summary = await this.db.get(`
2000
+ SELECT
2001
+ (SELECT COUNT(*) FROM test_runs) as totalRuns,
2002
+ (SELECT COUNT(*) FROM test_results) as totalTests,
2003
+ (SELECT COUNT(*) FROM test_results WHERE status = 'passed') as passed,
2004
+ (SELECT COUNT(*) FROM test_results WHERE status = 'failed') as failed,
2005
+ (SELECT AVG(CAST(duration AS FLOAT)) FROM test_results) as avgDuration
2006
+ `);
2007
+ const passRate = summary.totalTests ? (summary.passed / summary.totalTests * 100).toFixed(2) : 0;
2008
+ return {
2009
+ totalRuns: summary.totalRuns,
2010
+ totalTests: summary.totalTests,
2011
+ passed: summary.passed,
2012
+ failed: summary.failed,
2013
+ passRate: parseFloat(passRate.toString()),
2014
+ avgDuration: Math.round(summary.avgDuration || 0)
2015
+ };
2016
+ } catch (error) {
2017
+ console.error("OrtoniReport: Error getting summary data:", error);
2018
+ return {
2019
+ totalRuns: 0,
2020
+ totalTests: 0,
2021
+ passed: 0,
2022
+ failed: 0,
2023
+ passRate: 0,
2024
+ avgDuration: 0
2025
+ };
2026
+ }
2027
+ }
2028
+ async getTrends(limit = 30) {
2029
+ if (!this.db) {
2030
+ console.error("OrtoniReport: Database not initialized");
2031
+ return [];
2032
+ }
2033
+ try {
2034
+ const rows = await this.db.all(
2035
+ `
2036
+ SELECT trun.run_date,
2037
+ SUM(CASE WHEN tr.status = 'passed' THEN 1 ELSE 0 END) AS passed,
2038
+ SUM(CASE WHEN tr.status = 'failed' THEN 1 ELSE 0 END) AS failed,
2039
+ AVG(CAST(tr.duration AS FLOAT)) AS avg_duration
2040
+ FROM test_results tr
2041
+ JOIN test_runs trun ON tr.run_id = trun.id
2042
+ GROUP BY trun.run_date
2043
+ ORDER BY trun.run_date ASC
2044
+ LIMIT ?
2045
+ `,
2046
+ [limit]
2047
+ );
2048
+ return rows.map((row) => ({
2049
+ ...row,
2050
+ run_date: formatDateLocal(row.run_date),
2051
+ avg_duration: Math.round(row.avg_duration || 0)
2052
+ }));
2053
+ } catch (error) {
2054
+ console.error("OrtoniReport: Error getting trends data:", error);
2055
+ return [];
2056
+ }
2057
+ }
2058
+ async getFlakyTests(limit = 10) {
2059
+ if (!this.db) {
2060
+ console.error("OrtoniReport: Database not initialized");
2061
+ return [];
2062
+ }
2063
+ try {
2064
+ return await this.db.all(
2065
+ `
2066
+ SELECT
2067
+ test_id,
2068
+ COUNT(*) AS total,
2069
+ SUM(CASE WHEN status = 'flaky' THEN 1 ELSE 0 END) AS flaky
2070
+ FROM test_results
2071
+ GROUP BY test_id
2072
+ HAVING flaky > 0
2073
+ ORDER BY flaky DESC
2074
+ LIMIT ?
2075
+ `,
2076
+ [limit]
2077
+ );
2078
+ } catch (error) {
2079
+ console.error("OrtoniReport: Error getting flaky tests:", error);
2080
+ return [];
2081
+ }
2082
+ }
2083
+ async getSlowTests(limit = 10) {
2084
+ if (!this.db) {
2085
+ console.error("OrtoniReport: Database not initialized");
2086
+ return [];
2087
+ }
2088
+ try {
2089
+ const rows = await this.db.all(
2090
+ `
2091
+ SELECT
2092
+ test_id,
2093
+ AVG(CAST(duration AS FLOAT)) AS avg_duration
2094
+ FROM test_results
2095
+ GROUP BY test_id
2096
+ ORDER BY avg_duration DESC
2097
+ LIMIT ?
2098
+ `,
2099
+ [limit]
2100
+ );
2101
+ return rows.map((row) => ({
2102
+ test_id: row.test_id,
2103
+ avg_duration: Math.round(row.avg_duration || 0)
2104
+ }));
2105
+ } catch (error) {
2106
+ console.error("OrtoniReport: Error getting slow tests:", error);
2107
+ return [];
2108
+ }
2109
+ }
687
2110
  };
688
2111
 
689
2112
  // src/ortoni-report.ts
@@ -695,9 +2118,12 @@ var OrtoniReport = class {
695
2118
  this.projectSet = /* @__PURE__ */ new Set();
696
2119
  this.shouldGenerateReport = true;
697
2120
  this.showConsoleLogs = true;
2121
+ this.skipTraceViewer = false;
698
2122
  this.reportsCount = 0;
699
2123
  this.folderPath = ortoniConfig.folderPath || "ortoni-report";
700
- this.outputFilename = ensureHtmlExtension(ortoniConfig.filename || "ortoni-report.html");
2124
+ this.outputFilename = ensureHtmlExtension(
2125
+ ortoniConfig.filename || "ortoni-report.html"
2126
+ );
701
2127
  this.dbManager = new DatabaseManager();
702
2128
  this.htmlGenerator = new HTMLGenerator(ortoniConfig, this.dbManager);
703
2129
  this.fileManager = new FileManager(this.folderPath);
@@ -706,11 +2132,17 @@ var OrtoniReport = class {
706
2132
  this.showConsoleLogs = ortoniConfig.stdIO !== false;
707
2133
  }
708
2134
  async onBegin(config, _suite) {
2135
+ this.skipTraceViewer = config.projects.every((project) => {
2136
+ const trace = project.use?.trace;
2137
+ return trace === void 0 || trace === "off";
2138
+ });
709
2139
  this.reportsCount = config.reporter.length;
710
2140
  this.results = [];
711
2141
  this.testResultProcessor = new TestResultProcessor(config.rootDir);
712
2142
  this.fileManager.ensureReportDirectory();
713
- await this.dbManager.initialize(import_path7.default.join(this.folderPath, "ortoni-data-history.sqlite"));
2143
+ await this.dbManager.initialize(
2144
+ import_path7.default.join(this.folderPath, "ortoni-data-history.sqlite")
2145
+ );
714
2146
  }
715
2147
  onStdOut(chunk, _test, _result) {
716
2148
  if (this.reportsCount == 1 && this.showConsoleLogs) {
@@ -719,7 +2151,12 @@ var OrtoniReport = class {
719
2151
  }
720
2152
  onTestEnd(test, result) {
721
2153
  try {
722
- const testResult = this.testResultProcessor.processTestResult(test, result, this.projectSet, this.ortoniConfig);
2154
+ const testResult = this.testResultProcessor.processTestResult(
2155
+ test,
2156
+ result,
2157
+ this.projectSet,
2158
+ this.ortoniConfig
2159
+ );
723
2160
  this.results.push(testResult);
724
2161
  } catch (error) {
725
2162
  console.error("OrtoniReport: Error processing test end:", error);
@@ -737,19 +2174,32 @@ var OrtoniReport = class {
737
2174
  try {
738
2175
  this.overAllStatus = result.status;
739
2176
  if (this.shouldGenerateReport) {
740
- const filteredResults = this.results.filter((r) => r.status !== "skipped" && !r.isRetry);
2177
+ const filteredResults = this.results.filter(
2178
+ (r) => r.status !== "skipped" && !r.isRetry
2179
+ );
741
2180
  const totalDuration = msToTime(result.duration);
742
2181
  const cssContent = this.fileManager.readCssContent();
743
2182
  const runId = await this.dbManager.saveTestRun();
744
2183
  if (runId !== null) {
745
2184
  await this.dbManager.saveTestResults(runId, this.results);
746
- const html = await this.htmlGenerator.generateHTML(filteredResults, totalDuration, cssContent, this.results, this.projectSet);
747
- this.outputPath = this.fileManager.writeReportFile(this.outputFilename, html);
2185
+ const html = await this.htmlGenerator.generateHTML(
2186
+ filteredResults,
2187
+ totalDuration,
2188
+ cssContent,
2189
+ this.results,
2190
+ this.projectSet
2191
+ );
2192
+ this.outputPath = this.fileManager.writeReportFile(
2193
+ this.outputFilename,
2194
+ html
2195
+ );
748
2196
  } else {
749
2197
  console.error("OrtoniReport: Error saving test run to database");
750
2198
  }
751
2199
  } else {
752
- console.error("OrtoniReport: Report generation skipped due to error in Playwright worker!");
2200
+ console.error(
2201
+ "OrtoniReport: Report generation skipped due to error in Playwright worker!"
2202
+ );
753
2203
  }
754
2204
  } catch (error) {
755
2205
  this.shouldGenerateReport = false;
@@ -760,9 +2210,13 @@ var OrtoniReport = class {
760
2210
  try {
761
2211
  await this.dbManager.close();
762
2212
  if (this.shouldGenerateReport) {
763
- this.fileManager.copyTraceViewerAssets();
2213
+ this.fileManager.copyTraceViewerAssets(this.skipTraceViewer);
764
2214
  console.info(`Ortoni HTML report generated at ${this.outputPath}`);
765
- this.serverManager.startServer(this.folderPath, this.outputFilename, this.overAllStatus);
2215
+ this.serverManager.startServer(
2216
+ this.folderPath,
2217
+ this.outputFilename,
2218
+ this.overAllStatus
2219
+ );
766
2220
  await new Promise((_resolve) => {
767
2221
  });
768
2222
  }