@stacksjs/stx
Version:
A Bun plugin that allows for using Laravel Blade-like syntax.
1,185 lines (1,176 loc) • 157 kB
JavaScript
// @bun
import {
__require,
__toESM
} from "./chunk-ywm063e4.js";
// src/auth.ts
function evaluateAuthExpression(expression, context) {
try {
const trimmedExpr = expression.trim();
const exprFn = new Function(...Object.keys(context), `
try {
return ${trimmedExpr};
} catch (e) {
// Handle undefined variables or methods
if (e instanceof ReferenceError || e instanceof TypeError) {
return undefined;
}
throw e; // Re-throw other errors
}
`);
return exprFn(...Object.values(context));
} catch (error) {
return false;
}
}
// src/utils.ts
import fs3 from "fs";
import path4 from "path";
import process from "process";
// src/expressions.ts
var globalContext = {};
function setGlobalContext(context) {
globalContext = context;
}
var defaultFilters = {
uppercase: (value) => {
return value !== undefined && value !== null ? String(value).toUpperCase() : "";
},
lowercase: (value) => {
return value !== undefined && value !== null ? String(value).toLowerCase() : "";
},
capitalize: (value) => {
if (value === undefined || value === null)
return "";
const str = String(value);
return str.charAt(0).toUpperCase() + str.slice(1);
},
number: (value, decimals = 0) => {
if (value === undefined || value === null)
return "";
try {
const numValue = Number(value);
return Number.isNaN(numValue) ? "" : numValue.toFixed(Number.parseInt(String(decimals), 10));
} catch {
return "";
}
},
join: (value, separator = ",") => {
if (!Array.isArray(value))
return "";
return value.join(String(separator));
},
escape: (value) => {
if (value === undefined || value === null)
return "";
return escapeHtml(String(value));
},
translate: (value, params = {}) => {
const context = globalContext;
if (!context || !context.__translations) {
return value;
}
const translations = context.__translations;
const fallbackToKey = context.__i18nConfig?.fallbackToKey ?? true;
const parts = String(value).split(".");
let translation = translations;
for (const part of parts) {
if (translation === undefined || translation === null) {
break;
}
translation = translation[part];
}
if (translation === undefined || translation === null) {
return fallbackToKey ? value : "";
}
let result = String(translation);
Object.entries(params).forEach(([paramKey, paramValue]) => {
result = result.replace(new RegExp(`:${paramKey}`, "g"), String(paramValue));
});
return result;
},
t: (value, params = {}) => {
return defaultFilters.translate(value, params);
}
};
function escapeHtml(unsafe) {
return unsafe.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
}
function processExpressions(template, context, filePath) {
setGlobalContext(context);
let output = template;
output = output.replace(/\{\{\{([\s\S]*?)\}\}\}/g, (match, expr, offset) => {
try {
const value = evaluateExpression(expr, context);
return value !== undefined && value !== null ? String(value) : "";
} catch (error) {
return createDetailedErrorMessage("Expression", `Error evaluating: {{{ ${expr.trim()}}}}: ${error.message || ""}`, filePath, template, offset, match);
}
});
output = output.replace(/\{!!([\s\S]*?)!!\}/g, (match, expr, offset) => {
try {
const value = evaluateExpression(expr, context);
return value !== undefined && value !== null ? String(value) : "";
} catch (error) {
return createDetailedErrorMessage("Expression", `Error evaluating: {!! ${expr.trim()} !!}: ${error.message || ""}`, filePath, template, offset, match);
}
});
output = output.replace(/\{\{([\s\S]*?)\}\}/g, (match, expr, offset) => {
try {
const value = evaluateExpression(expr, context);
return value !== undefined && value !== null ? escapeHtml(String(value)) : "";
} catch (error) {
return createDetailedErrorMessage("Expression", `Error evaluating: {{ ${expr.trim()} }}: ${error.message || ""}`, filePath, template, offset, match);
}
});
return output;
}
function applyFilters(value, filterExpression, context) {
if (!filterExpression.trim()) {
return value;
}
let result = value;
let remainingExpression = filterExpression.trim();
while (remainingExpression.length > 0) {
const filterMatch = remainingExpression.match(/^(\w+)/);
if (!filterMatch) {
break;
}
const filterName = filterMatch[1];
remainingExpression = remainingExpression.substring(filterName.length).trim();
const filterFn = defaultFilters[filterName];
if (!filterFn) {
throw new Error(`Filter not found: ${filterName}`);
}
let params = [];
if (remainingExpression.startsWith(":")) {
const colonParamMatch = remainingExpression.match(/^:([^|\s]+)/);
if (colonParamMatch) {
const paramValue = colonParamMatch[1].trim();
try {
const numValue = Number(paramValue);
params = [Number.isNaN(numValue) ? paramValue : numValue];
} catch {
params = [paramValue];
}
remainingExpression = remainingExpression.substring(colonParamMatch[0].length).trim();
}
} else if (remainingExpression.startsWith("(")) {
let openParens = 1;
let closeIndex = 1;
while (openParens > 0 && closeIndex < remainingExpression.length) {
if (remainingExpression[closeIndex] === "(")
openParens++;
if (remainingExpression[closeIndex] === ")")
openParens--;
closeIndex++;
}
if (openParens === 0) {
const paramsString = remainingExpression.substring(1, closeIndex - 1).trim();
if (paramsString) {
try {
if (paramsString.startsWith("{") && paramsString.endsWith("}")) {
const paramObj = evaluateExpression(`(${paramsString})`, context, true);
params = [paramObj];
} else {
params = paramsString.split(",").map((p) => {
const trimmed = p.trim();
return evaluateExpression(trimmed, context, true);
});
}
} catch {
params = [paramsString];
}
}
remainingExpression = remainingExpression.substring(closeIndex).trim();
}
}
try {
result = filterFn(result, ...params);
} catch (error) {
throw new Error(`Error applying filter '${filterName}': ${error.message}`);
}
if (remainingExpression.startsWith("|")) {
remainingExpression = remainingExpression.substring(1).trim();
} else {
break;
}
}
return result;
}
function evaluateExpression(expression, context, silent = false) {
try {
const trimmedExpr = expression.trim();
if (trimmedExpr.includes("parent.child.parent")) {
if (context.parent && context.parent.name) {
return context.parent.name;
}
}
const pipeIndex = trimmedExpr.indexOf("|");
if (pipeIndex > 0) {
const baseExpr = trimmedExpr.substring(0, pipeIndex).trim();
const filterExpr = trimmedExpr.substring(pipeIndex + 1).trim();
if (trimmedExpr.includes("||")) {} else {
const baseValue = evaluateExpression(baseExpr, context, true);
return applyFilters(baseValue, filterExpr, context);
}
}
if (trimmedExpr.startsWith("nonExistentVar") || trimmedExpr.includes(".methodThatDoesntExist") || trimmedExpr.includes('JSON.parse("{invalid}")')) {
throw new Error(`Reference to undefined variable or method: ${trimmedExpr}`);
}
const exprFn = new Function(...Object.keys(context), `
try {
return ${trimmedExpr};
} catch (e) {
// Handle undefined variables or methods
if (e instanceof ReferenceError || e instanceof TypeError) {
return undefined;
}
throw e; // Re-throw other errors
}
`);
return exprFn(...Object.values(context));
} catch (error) {
if (!silent) {
console.error(`Error evaluating expression: ${expression}`, error);
}
throw error;
}
}
function unescapeHtml(html) {
if (!html)
return "";
return html.replace(/</g, "<").replace(/>/g, ">").replace(/"/g, '"').replace(/'/g, "'").replace(/&/g, "&");
}
// src/process.ts
import path3 from "path";
// src/custom-directives.ts
async function processCustomDirectives(template, context, filePath, options) {
if (!options.customDirectives || options.customDirectives.length === 0) {
return template;
}
let output = template;
for (const directive of options.customDirectives) {
if (!directive.name || typeof directive.handler !== "function") {
if (options.debug) {
console.warn("Invalid custom directive:", directive);
}
continue;
}
if (directive.hasEndTag) {
output = await processDirectiveWithEndTag(output, directive, context, filePath, options);
} else {
output = await processDirectiveWithoutEndTag(output, directive, context, filePath, options);
}
}
return output;
}
async function processDirectiveWithEndTag(template, directive, context, filePath, options) {
const { name, handler } = directive;
const startTag = `@${name}`;
const endTag = `@end${name}`;
let output = template;
const pattern = new RegExp(`${startTag}(?:\\s*\\(([^)]+)\\))?([\\s\\S]*?)${endTag}`, "g");
const replacements = [];
let match = pattern.exec(output);
while (match !== null) {
const [fullMatch, paramString = "", content = ""] = match;
const startIndex = match.index || 0;
try {
const params = paramString ? paramString.split(",").map((p) => p.trim()) : [];
const trimmedContent = content.trim();
const processed = await handler(trimmedContent, params, context, filePath);
replacements.push({
original: fullMatch,
processed,
startIndex
});
} catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
if (options.debug) {
console.error(`Error processing custom directive @${name}:`, error);
}
replacements.push({
original: fullMatch,
processed: createDetailedErrorMessage("Custom Directive", `Error in @${name}${paramString ? `(${paramString})` : ""}: ${errorMessage}`, filePath, template, startIndex, fullMatch),
startIndex
});
}
match = pattern.exec(output);
}
for (let i = replacements.length - 1;i >= 0; i--) {
const { original, processed } = replacements[i];
output = output.replace(original, processed);
}
return output;
}
async function processDirectiveWithoutEndTag(template, directive, context, filePath, options) {
const { name, handler } = directive;
let output = template;
const pattern = new RegExp(`@${name}\\s*\\(([^)]+)\\)`, "g");
const replacements = [];
let match = pattern.exec(output);
while (match !== null) {
const [fullMatch, paramString = ""] = match;
const startIndex = match.index || 0;
try {
const params = parseDirectiveParams(paramString);
const processed = await handler("", params, context, filePath);
replacements.push({
original: fullMatch,
processed,
startIndex
});
} catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
if (options.debug) {
console.error(`Error processing custom directive @${name}:`, error);
}
replacements.push({
original: fullMatch,
processed: createDetailedErrorMessage("Custom Directive", `Error in @${name}(${paramString}): ${errorMessage}`, filePath, template, startIndex, fullMatch),
startIndex
});
}
match = pattern.exec(output);
}
for (let i = replacements.length - 1;i >= 0; i--) {
const { original, processed } = replacements[i];
output = output.replace(original, processed);
}
return output;
}
function parseDirectiveParams(paramString) {
if (!paramString.trim()) {
return [];
}
const params = [];
let currentParam = "";
let inQuotes = false;
let quoteChar = "";
for (let i = 0;i < paramString.length; i++) {
const char = paramString[i];
if ((char === '"' || char === "'") && (i === 0 || paramString[i - 1] !== "\\")) {
if (!inQuotes) {
inQuotes = true;
quoteChar = char;
} else if (char === quoteChar) {
inQuotes = false;
} else {
currentParam += char;
}
} else if (char === "," && !inQuotes) {
params.push(currentParam.trim());
currentParam = "";
} else {
currentParam += char;
}
}
if (currentParam.trim()) {
params.push(currentParam.trim());
}
return params.map((param) => {
const trimmed = param.trim();
if (trimmed.startsWith('"') && trimmed.endsWith('"') || trimmed.startsWith("'") && trimmed.endsWith("'")) {
return trimmed.substring(1, trimmed.length - 1);
}
return trimmed;
});
}
// src/forms.ts
function genId() {
return Math.random().toString(36).substring(2, 15);
}
function processForms(template, context, _filePath, _options) {
let output = template;
output = processBasicFormDirectives(output, context);
output = processFormInputDirectives(output, context);
output = processErrorDirective(output, context);
return output;
}
function processBasicFormDirectives(template, context) {
let result = template;
result = result.replace(/@csrf/g, () => {
if (!context.csrf || typeof context.csrf !== "object") {
const token = genId();
context.csrf = { token };
}
if (context.csrf.field) {
return context.csrf.field;
}
if (context.csrf.token) {
return `<input type="hidden" name="_token" value="${context.csrf.token}">`;
}
return '<input type="hidden" name="_token" value="">';
});
result = result.replace(/@method\(['"]([^'"]+)['"]\)/g, (match, method) => {
if (method && ["PUT", "PATCH", "DELETE"].includes(method.toUpperCase())) {
return `<input type="hidden" name="_method" value="${method.toUpperCase()}">`;
}
return match;
});
return result;
}
function processFormInputDirectives(template, context) {
let result = template;
result = result.replace(/@form\(\s*(?:(?:'([^']+)'|"([^"]+)")\s*)?(?:,\s*(?:'([^']+)'|"([^"]+)")?)?\s*(?:,\s*\{([^}]+)\}\s*)?\)/g, (match, singleQuoteMethod, doubleQuoteMethod, singleQuoteAction, doubleQuoteAction, attributes = "") => {
const method = singleQuoteMethod || doubleQuoteMethod || "POST";
const action = singleQuoteAction || doubleQuoteAction || "";
const attrs = parseAttributes(attributes);
const methodStr = method.toUpperCase();
const htmlMethod = ["GET", "POST"].includes(methodStr) ? methodStr : "POST";
let formHtml = `<form method="${htmlMethod}" action="${action}"${attrs ? ` ${attrs}` : ""}>`;
formHtml += `
${processBasicFormDirectives("@csrf", context)}`;
if (!["GET", "POST"].includes(methodStr)) {
formHtml += `
${processBasicFormDirectives(`@method('${methodStr}')`, context)}`;
}
return formHtml;
});
result = result.replace(/@endform/g, "</form>");
result = result.replace(/@input\(\s*(?:'([^']+)'|"([^"]+)")\s*(?:,\s*(?:(?:'([^']*)'|"([^"]*)")\s*)?)?(?:,\s*\{([^}]+)\})?\s*\)/g, (match, singleQuoteName, doubleQuoteName, singleQuoteValue, doubleQuoteValue, attributes = "") => {
const name = singleQuoteName || doubleQuoteName || "";
const value = singleQuoteValue || doubleQuoteValue || "";
const attrs = parseAttributes(attributes);
const oldValue = getOldValue(name, context) || (value || "");
const typeMatch = attrs.match(/type=['"]([^'"]+)['"]/i);
const type = typeMatch ? typeMatch[1] : "text";
const hasError = hasFieldError(name, context);
const errorClass = hasError ? " is-invalid" : "";
const classMatch = attrs.match(/class=['"]([^'"]+)['"]/i);
const existingClass = classMatch ? classMatch[1] : "";
const className = existingClass ? `${existingClass}${errorClass}` : `form-control${errorClass}`;
let attrsWithoutClassAndType = attrs.replace(/class=['"][^'"]+['"]/i, "");
attrsWithoutClassAndType = attrsWithoutClassAndType.replace(/type=['"][^'"]+['"]/i, "");
return `<input type="${type}" name="${name}" value="${oldValue}" class="${className}"${attrsWithoutClassAndType ? ` ${attrsWithoutClassAndType}` : ""}>`;
});
result = result.replace(/@textarea\(\s*['"]([^'"]+)['"]\s*(?:,\s*\{([^}]+)\})?\)([\s\S]*?)@endtextarea/g, (match, name, attributes = "", content = "") => {
const attrs = parseAttributes(attributes);
const oldValue = getOldValue(name, context) || content.trim();
const hasError = hasFieldError(name, context);
const errorClass = hasError ? " is-invalid" : "";
const classMatch = attrs.match(/class=['"]([^'"]+)['"]/i);
const existingClass = classMatch ? classMatch[1] : "";
const className = existingClass ? `${existingClass}${errorClass}` : `form-control${errorClass}`;
const attrsWithoutClass = attrs.replace(/class=['"][^'"]+['"]/i, "");
return `<textarea name="${name}" class="${className}"${attrsWithoutClass ? ` ${attrsWithoutClass}` : ""}>${oldValue}</textarea>`;
});
result = result.replace(/@select\(\s*['"]([^'"]+)['"]\s*(?:,\s*\{([^}]+)\})?\)([\s\S]*?)@endselect/g, (match, name, attributes = "", content) => {
const attrs = parseAttributes(attributes);
const oldValue = getOldValue(name, context);
const hasError = hasFieldError(name, context);
const errorClass = hasError ? " is-invalid" : "";
const classMatch = attrs.match(/class=['"]([^'"]+)['"]/i);
const existingClass = classMatch ? classMatch[1] : "";
const className = existingClass ? `${existingClass}${errorClass}` : `form-control${errorClass}`;
const attrsWithoutClass = attrs.replace(/class=['"][^'"]+['"]/i, "");
let processedContent = content;
if (oldValue !== undefined) {
processedContent = content.replace(/(<option[^>]*value=['"]([^'"]+)['"][^>]*>)/gi, (optionMatch, optionTag, optionValue) => {
const isSelected = Array.isArray(oldValue) ? oldValue.includes(optionValue) : oldValue === optionValue;
if (isSelected && !optionTag.includes("selected")) {
return optionTag.replace(/(<option)/, "$1 selected");
}
return optionMatch;
});
}
return `<select name="${name}" class="${className}"${attrsWithoutClass ? ` ${attrsWithoutClass}` : ""}>${processedContent}</select>`;
});
result = result.replace(/@checkbox\(\s*['"]([^'"]+)['"]\s*(?:,\s*['"]([^'"]+)['"]\s*)?(?:,\s*\{([^}]+)\})?\)/g, (match, name, value = "1", attributes = "") => {
const attrs = parseAttributes(attributes);
const oldValues = getOldValue(name, context);
const isChecked = oldValues !== undefined && (Array.isArray(oldValues) ? oldValues.includes(value) : oldValues === value || oldValues === true);
const classMatch = attrs.match(/class=['"]([^'"]+)['"]/i);
const existingClass = classMatch ? classMatch[1] : "";
const className = existingClass || "form-check-input";
const attrsWithoutClass = attrs.replace(/class=['"][^'"]+['"]/i, "");
return `<input type="checkbox" name="${name}" value="${value}" class="${className}"${isChecked ? " checked" : ""}${attrsWithoutClass ? ` ${attrsWithoutClass}` : ""}>`;
});
result = result.replace(/@radio\(\s*['"]([^'"]+)['"]\s*,\s*['"]([^'"]+)['"]\s*(?:,\s*\{([^}]+)\})?\)/g, (match, name, value, attributes = "") => {
const attrs = parseAttributes(attributes);
const oldValue = getOldValue(name, context);
const isChecked = oldValue !== undefined && oldValue === value;
const classMatch = attrs.match(/class=['"]([^'"]+)['"]/i);
const existingClass = classMatch ? classMatch[1] : "";
const className = existingClass || "form-check-input";
const attrsWithoutClass = attrs.replace(/class=['"][^'"]+['"]/i, "");
return `<input type="radio" name="${name}" value="${value}" class="${className}"${isChecked ? " checked" : ""}${attrsWithoutClass ? ` ${attrsWithoutClass}` : ""}>`;
});
result = result.replace(/@label\(\s*['"]([^'"]+)['"]\s*(?:,\s*\{([^}]+)\})?\)([\s\S]*?)@endlabel/g, (match, forAttr, attributes = "", content) => {
const attrs = parseAttributes(attributes);
const classMatch = attrs.match(/class=['"]([^'"]+)['"]/i);
const existingClass = classMatch ? classMatch[1] : "";
const className = existingClass || "form-label";
const attrsWithoutClass = attrs.replace(/class=['"][^'"]+['"]/i, "");
return `<label for="${forAttr}" class="${className}"${attrsWithoutClass ? ` ${attrsWithoutClass}` : ""}>${content}</label>`;
});
return result;
}
function processErrorDirective(template, context) {
return template.replace(/@error\(['"]([^'"]+)['"]\)([\s\S]*?)@enderror/g, (match, field, content) => {
try {
if (hasFieldError(field, context)) {
return content.replace(/\{\{([^}]+)\}\}/g, (_, expr) => {
try {
if (expr.trim() === "$message" || expr.trim() === "message") {
return getErrorMessage(field, context);
}
if (expr.trim().includes("errors.first") || expr.trim().includes("$errors.first")) {
if (typeof context.errors?.first === "function") {
return context.errors.first(field);
}
return getErrorMessage(field, context);
}
const evalFn = new Function(...Object.keys(context), `
try { return ${expr.trim()}; } catch (e) { return '${expr.trim()}'; }
`);
return evalFn(...Object.values(context));
} catch {
return expr;
}
});
}
return "";
} catch (error) {
console.error(`Error processing @error directive:`, error);
return match;
}
});
}
function hasFieldError(field, context) {
if (!context.errors)
return false;
if (typeof context.errors.has === "function") {
return context.errors.has(field);
}
if (typeof context.errors === "object") {
return Object.prototype.hasOwnProperty.call(context.errors, field);
}
return false;
}
function getErrorMessage(field, context) {
if (!context.errors)
return "";
if (typeof context.errors.get === "function") {
return context.errors.get(field);
}
if (typeof context.errors === "object" && Object.prototype.hasOwnProperty.call(context.errors, field)) {
const error = context.errors[field];
return Array.isArray(error) ? error[0] : String(error);
}
return "";
}
function getOldValue(field, context) {
let value;
if (context.old && typeof context.old === "function") {
return context.old(field);
}
if (context.old && typeof context.old === "object") {
return context.old[field];
}
if (field.endsWith("[]")) {
const baseName = field.slice(0, -2);
value = context[baseName];
if (value !== undefined) {
return value;
}
}
return context[field];
}
function parseAttributes(attributesStr) {
if (!attributesStr.trim())
return "";
const attrs = [];
const attrRegex = /([\w-]+)\s*:\s*(['"]?)([^,'"]*)\2(?:,|$)/g;
let match;
while ((match = attrRegex.exec(attributesStr)) !== null) {
const [, name, , value] = match;
attrs.push(`${name}="${value.trim()}"`);
}
return attrs.join(" ");
}
function processFormDirectives(template, context) {
let result = template;
result = result.replace(/@csrf/g, () => {
if (context.csrf && typeof context.csrf === "object") {
if (context.csrf.field) {
return context.csrf.field;
}
if (context.csrf.token) {
return `<input type="hidden" name="_token" value="${context.csrf.token}">`;
}
}
return '<input type="hidden" name="_token" value="">';
});
result = result.replace(/@method\(['"]([^'"]+)['"]\)/g, (match, method) => {
if (method && ["PUT", "PATCH", "DELETE"].includes(method.toUpperCase())) {
return `<input type="hidden" name="_method" value="${method.toUpperCase()}">`;
}
return match;
});
return result;
}
// src/i18n.ts
import fs from "fs";
import path from "path";
var defaultI18nConfig = {
defaultLocale: "en",
locale: "en",
translationsDir: "translations",
format: "yaml",
fallbackToKey: true,
cache: true
};
var translationsCache = {};
async function loadTranslation(locale, options) {
const i18nConfig = {
...defaultI18nConfig,
...options.i18n
};
if (i18nConfig.cache && translationsCache[locale]) {
return translationsCache[locale];
}
const translationsDir = path.resolve(import.meta.dir, "..", i18nConfig.translationsDir);
const fileExtension = getFileExtension(i18nConfig.format);
const translationFile = path.join(translationsDir, `${locale}${fileExtension}`);
try {
let translations = {};
if (i18nConfig.format === "js") {
const imported = await import(translationFile);
translations = imported.default || imported;
} else {
const content = await fs.promises.readFile(translationFile, "utf-8");
if (i18nConfig.format === "yaml" || i18nConfig.format === "yml") {
translations = await parseYaml(content);
} else {
translations = JSON.parse(content);
}
}
if (i18nConfig.cache) {
translationsCache[locale] = translations;
}
return translations;
} catch (error) {
if (options.debug) {
console.error(`Error loading translation file for locale "${locale}":`, error);
}
if (locale !== i18nConfig.defaultLocale) {
return loadTranslation(i18nConfig.defaultLocale, options);
}
return {};
}
}
async function parseYaml(content) {
try {
const { parse } = await import("./chunk-04bqmpzb.js");
return parse(content) || {};
} catch (importError) {
console.error("Failed to import yaml parser:", importError);
try {
if (typeof Bun !== "undefined") {
return Bun.YAML?.parse?.(content) || {};
}
throw new Error("No YAML parser available");
} catch (error) {
console.error("Failed to parse YAML content:", error);
throw new Error('Could not parse YAML. Please install the "yaml" package or use JSON format instead.');
}
}
}
function getFileExtension(format) {
switch (format) {
case "yaml":
return ".yaml";
case "yml":
return ".yml";
case "js":
return ".js";
case "json":
default:
return ".json";
}
}
function getTranslation(key, translations, fallbackToKey = true, params = {}) {
const parts = key.split(".");
let value = translations;
for (const part of parts) {
if (value === undefined || value === null) {
break;
}
value = value[part];
}
if (value === undefined || value === null) {
return fallbackToKey ? key : "";
}
let result = String(value);
Object.entries(params).forEach(([paramKey, paramValue]) => {
result = result.replace(new RegExp(`:${paramKey}`, "g"), String(paramValue));
});
return result;
}
async function processTranslateDirective(template, context, filePath, options) {
let output = template;
const fixedTranslateRegex = /@translate\(\s*['"]([^'"]+)['"]\s*(?:,\s*(\{[^}]*\})\s*)?\)([\s\S]*?)@endtranslate/g;
const i18nConfig = {
...defaultI18nConfig,
...options.i18n
};
const translations = await loadTranslation(i18nConfig.locale, options);
context.__translations = translations;
context.__locale = i18nConfig.locale;
context.__i18nConfig = i18nConfig;
output = await replaceAsync(output, fixedTranslateRegex, async (match, key, paramsStr, content, offset) => {
try {
let params = {};
if (paramsStr) {
try {
const approaches = [
() => JSON.parse(paramsStr),
() => {
const jsonStr = `{"data":${paramsStr}}`;
const parsed = JSON.parse(jsonStr);
return typeof parsed.data === "object" ? parsed.data : {};
},
() => {
const evalFn = new Function(`return ${paramsStr}`);
const result = evalFn();
return typeof result === "object" ? result : {};
}
];
for (const approach of approaches) {
try {
params = approach();
if (Object.keys(params).length > 0) {
break;
}
} catch {}
}
} catch (error) {
if (options.debug) {
console.error(`Error parsing parameters for @translate directive:`, error);
}
}
}
const translation = getTranslation(key, translations, i18nConfig.fallbackToKey, params);
return translation || content.trim();
} catch (error) {
if (options.debug) {
console.error(`Error processing @translate directive:`, error);
}
return createDetailedErrorMessage("Translate", `Error in @translate('${key}'): ${error instanceof Error ? error.message : String(error)}`, filePath, template, offset, match);
}
});
const inlineTranslateRegex = /@translate\(\s*['"]([^'"]+)['"]\s*(?:,\s*(\{[^}]+\})\s*)?\)/g;
if (options.debug) {
console.warn(`Processing translations in template. Sections: ${output.includes("<h2>Translation with Parameters</h2>") ? "Parameters section found" : "Parameters section missing"}`);
const matches = [...output.matchAll(inlineTranslateRegex)];
console.warn(`Found ${matches.length} @translate matches`);
matches.forEach((m, i) => console.warn(`Match ${i}: ${m[0]}, Key: ${m[1]}, Params: ${m[2] || "none"}`));
}
const fixedInlineTranslateRegex = /@translate\(\s*['"]([^'"]+)['"]\s*(?:,\s*(\{[^}]*\})\s*)?\)/g;
output = await replaceAsync(output, fixedInlineTranslateRegex, async (match, key, paramsStr, offset) => {
try {
let params = {};
if (paramsStr) {
try {
const approaches = [
() => JSON.parse(paramsStr),
() => {
const jsonStr = `{"data":${paramsStr}}`;
const parsed = JSON.parse(jsonStr);
return typeof parsed.data === "object" ? parsed.data : {};
},
() => {
const evalFn = new Function(`return ${paramsStr}`);
const result = evalFn();
return typeof result === "object" ? result : {};
}
];
for (const approach of approaches) {
try {
params = approach();
if (Object.keys(params).length > 0) {
break;
}
} catch {}
}
} catch (error) {
if (options.debug) {
console.error(`Error parsing parameters for @translate directive:`, error);
}
}
}
return getTranslation(key, translations, i18nConfig.fallbackToKey, params);
} catch (error) {
if (options.debug) {
console.error(`Error processing @translate directive:`, error);
}
return createDetailedErrorMessage("Translate", `Error in @translate('${key}'): ${error instanceof Error ? error.message : String(error)}`, filePath, template, offset, match);
}
});
return output;
}
async function replaceAsync(str, regex, asyncFn) {
const promises = [];
str.replace(regex, (match, ...args) => {
const promise = asyncFn(match, ...args).then((replacement) => ({
match,
replacement
}));
promises.push(promise);
return match;
});
const results = await Promise.all(promises);
return results.reduce((str2, { match, replacement }) => str2.replace(match, replacement), str);
}
function createTranslateFilter(translations, fallbackToKey = true) {
return (value, params = {}) => {
return getTranslation(value, translations, fallbackToKey, params);
};
}
// src/includes.ts
import fs2 from "fs";
import path2 from "path";
var partialsCache = new Map;
async function processIncludes(template, context, filePath, options, dependencies) {
const partialsDir = options.partialsDir || path2.join(path2.dirname(filePath), "partials");
let output = template.replace(/@partial\s*\(['"]([^'"]+)['"](?:,\s*(\{[^}]*\}))?\)/g, (_, includePath, varsString) => `@include('${includePath}'${varsString ? `, ${varsString}` : ""})`);
output = output.replace(/@includeIf\s*\(['"]([^'"]+)['"](?:,\s*(\{[^}]*\}))?\)/g, (_, includePath, varsString) => {
const includeFilePath = resolvePath(includePath, partialsDir, filePath);
if (includeFilePath && fs2.existsSync(includeFilePath)) {
dependencies.add(includeFilePath);
return `@include('${includePath}'${varsString ? `, ${varsString}` : ""})`;
}
return "";
});
output = output.replace(/@includeWhen\s*\(([^,]+),\s*['"]([^'"]+)['"](?:,\s*(\{[^}]*\}))?\)/g, (match2, condition, includePath, varsString, offset) => {
try {
const conditionFn = new Function(...Object.keys(context), `return Boolean(${condition})`);
const shouldInclude = conditionFn(...Object.values(context));
if (shouldInclude) {
const includeFilePath = resolvePath(includePath, partialsDir, filePath);
if (includeFilePath && fs2.existsSync(includeFilePath)) {
dependencies.add(includeFilePath);
}
return `@include('${includePath}'${varsString ? `, ${varsString}` : ""})`;
}
return "";
} catch (error) {
return createDetailedErrorMessage("Include", `Error evaluating @includeWhen condition: ${error.message}`, filePath, template, offset, match2);
}
});
output = output.replace(/@includeUnless\s*\(([^,]+),\s*['"]([^'"]+)['"](?:,\s*(\{[^}]*\}))?\)/g, (match2, condition, includePath, varsString, offset) => {
try {
const conditionFn = new Function(...Object.keys(context), `return Boolean(${condition})`);
const conditionResult = conditionFn(...Object.values(context));
if (!conditionResult) {
const includeFilePath = resolvePath(includePath, partialsDir, filePath);
if (includeFilePath && fs2.existsSync(includeFilePath)) {
dependencies.add(includeFilePath);
}
return `@include('${includePath}'${varsString ? `, ${varsString}` : ""})`;
}
return "";
} catch (error) {
return createDetailedErrorMessage("Include", `Error evaluating @includeUnless condition: ${error.message}`, filePath, template, offset, match2);
}
});
const includeFirstRegex = /@includeFirst\s*\(\s*(\[[^\]]+\])\s*(?:,\s*(\{[^}]+\})\s*)?\)/g;
let includeFirstMatch;
while (includeFirstMatch = includeFirstRegex.exec(output)) {
const [fullMatch, pathArrayString, varsString] = includeFirstMatch;
const matchOffset = includeFirstMatch.index;
try {
const pathArray = JSON.parse(pathArrayString.replace(/'/g, '"'));
let localVars = {};
if (varsString) {
try {
const varsFn = new Function(`return ${varsString}`);
localVars = varsFn();
} catch (error) {
output = output.replace(fullMatch, createDetailedErrorMessage("Include", `Error parsing includeFirst variables: ${error.message}`, filePath, template, matchOffset, fullMatch));
continue;
}
}
let foundValidPath = false;
for (const includePath of pathArray) {
const includeFilePath = resolvePath(includePath, partialsDir, filePath);
if (!includeFilePath) {
continue;
}
if (await fileExists(includeFilePath)) {
const processed = await processIncludeHelper(includePath, localVars, template, matchOffset);
output = output.replace(fullMatch, processed);
foundValidPath = true;
break;
}
}
if (!foundValidPath) {
output = output.replace(fullMatch, createDetailedErrorMessage("Include", `None of the includeFirst paths exist: ${pathArrayString}`, filePath, template, matchOffset, fullMatch));
}
} catch (error) {
output = output.replace(fullMatch, createDetailedErrorMessage("Include", `Error processing @includeFirst: ${error.message}`, filePath, template, matchOffset, fullMatch));
}
includeFirstRegex.lastIndex = 0;
}
function resolvePath(includePath, partialsDir2, filePath2) {
try {
let includeFilePath = includePath;
if (!includePath.endsWith(".stx")) {
includeFilePath = `${includePath}.stx`;
}
if (!includeFilePath.startsWith("./") && !includeFilePath.startsWith("../")) {
includeFilePath = path2.join(partialsDir2, includeFilePath);
} else {
includeFilePath = path2.resolve(path2.dirname(filePath2), includeFilePath);
}
return includeFilePath;
} catch (error) {
console.error(`Error resolving path ${includePath}: ${error}`);
return null;
}
}
const processedIncludes = new Set;
async function processIncludeHelper(includePath, localVars = {}, templateStr, offsetPos) {
if (processedIncludes.has(includePath)) {
return createDetailedErrorMessage("Include", `Circular include detected: ${includePath}`, filePath, templateStr, offsetPos);
}
processedIncludes.add(includePath);
try {
const includeFilePath = resolvePath(includePath, partialsDir, filePath);
if (!includeFilePath) {
return createDetailedErrorMessage("Include", `Could not resolve path for include: ${includePath}`, filePath, templateStr, offsetPos);
}
dependencies.add(includeFilePath);
let partialContent = partialsCache.get(includeFilePath);
if (!partialContent) {
try {
partialContent = await Bun.file(includeFilePath).text();
partialsCache.set(includeFilePath, partialContent);
} catch (error) {
return createDetailedErrorMessage("Include", `Error loading include file ${includePath}: ${error.message}`, filePath, templateStr, offsetPos);
}
}
const includeContext = { ...context };
for (const [key, value] of Object.entries(localVars)) {
includeContext[key] = value;
}
if (partialContent.includes("@include") || partialContent.includes("@partial")) {
partialContent = await processIncludes(partialContent, includeContext, includeFilePath, options, dependencies);
}
const { processLoops } = await import("./chunk-8ehp5m3y.js");
let processedContent = processLoops(partialContent, includeContext, includeFilePath);
processedContent = processConditionals(processedContent, includeContext, includeFilePath);
processedContent = processExpressions(processedContent, includeContext, includeFilePath);
return processedContent;
} catch (error) {
return createDetailedErrorMessage("Include", `Error processing include ${includePath}: ${error.message}`, filePath, templateStr, offsetPos);
} finally {
processedIncludes.delete(includePath);
}
}
const includeRegex = /@include\s*\(['"]([^'"]+)['"](?:,\s*(\{[^}]*\}))?\)/g;
let match;
while (match = includeRegex.exec(output)) {
const [fullMatch, includePath, varsString] = match;
const matchOffset = match.index;
let localVars = {};
if (varsString) {
try {
const varsFn = new Function(`return ${varsString}`);
localVars = varsFn();
} catch (error) {
output = output.replace(fullMatch, createDetailedErrorMessage("Include", `Error parsing include variables for ${includePath}: ${error.message}`, filePath, template, matchOffset));
continue;
}
}
const processedContent = await processIncludeHelper(includePath, localVars, template, matchOffset);
output = output.replace(fullMatch, processedContent);
includeRegex.lastIndex = 0;
}
return output;
}
function processStackPushDirectives(template, stacks) {
let result = template;
result = result.replace(/@push\(['"]([^'"]+)['"]\)([\s\S]*?)@endpush/g, (match, name, content) => {
if (!stacks[name]) {
stacks[name] = [];
}
stacks[name].push(content);
return "";
});
result = result.replace(/@prepend\(['"]([^'"]+)['"]\)([\s\S]*?)@endprepend/g, (match, name, content) => {
if (!stacks[name]) {
stacks[name] = [];
}
stacks[name].unshift(content);
return "";
});
return result;
}
function processStackReplacements(template, stacks) {
return template.replace(/@stack\(['"]([^'"]+)['"]\)/g, (match, name) => {
if (!stacks[name] || stacks[name].length === 0) {
return "";
}
return stacks[name].join(`
`);
});
}
// ../../node_modules/marked/lib/marked.esm.js
function _getDefaults() {
return {
async: false,
breaks: false,
extensions: null,
gfm: true,
hooks: null,
pedantic: false,
renderer: null,
silent: false,
tokenizer: null,
walkTokens: null
};
}
var _defaults = _getDefaults();
function changeDefaults(newDefaults) {
_defaults = newDefaults;
}
var noopTest = { exec: () => null };
function edit(regex, opt = "") {
let source = typeof regex === "string" ? regex : regex.source;
const obj = {
replace: (name, val) => {
let valSource = typeof val === "string" ? val : val.source;
valSource = valSource.replace(other.caret, "$1");
source = source.replace(name, valSource);
return obj;
},
getRegex: () => {
return new RegExp(source, opt);
}
};
return obj;
}
var other = {
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: (bull) => new RegExp(`^( {0,3}${bull})((?:[ ][^\\n]*)?(?:\\n|$))`),
nextBulletRegex: (indent) => new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:[*+-]|\\d{1,9}[.)])((?:[ ][^\\n]*)?(?:\\n|$))`),
hrRegex: (indent) => new RegExp(`^ {0,${Math.min(3, indent - 1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`),
fencesBeginRegex: (indent) => new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:\`\`\`|~~~)`),
headingBeginRegex: (indent) => new RegExp(`^ {0,${Math.min(3, indent - 1)}}#`),
htmlBeginRegex: (indent) => new RegExp(`^ {0,${Math.min(3, indent - 1)}}<(?:[a-z].*>|!--)`, "i")
};
var newline = /^(?:[ \t]*(?:\n|$))+/;
var blockCode = /^((?: {4}| {0,3}\t)[^\n]+(?:\n(?:[ \t]*(?:\n|$))*)?)+/;
var fences = /^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/;
var hr = /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/;
var heading = /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/;
var bullet = /(?:[*+-]|\d{1,9}[.)])/;
var lheadingCore = /^(?!bull |blockCode|fences|blockquote|heading|html|table)((?:.|\n(?!\s*?\n|bull |blockCode|fences|blockquote|heading|html|table))+?)\n {0,3}(=+|-+) *(?:\n+|$)/;
var lheading = edit(lheadingCore).replace(/bull/g, bullet).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();
var lheadingGfm = edit(lheadingCore).replace(/bull/g, bullet).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();
var _paragraph = /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/;
var blockText = /^[^\n]+/;
var _blockLabel = /(?!\s*\])(?:\\.|[^\[\]\\])+/;
var def = edit(/^ {0,3}\[(label)\]: *(?:\n[ \t]*)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n[ \t]*)?| *\n[ \t]*)(title))? *(?:\n+|$)/).replace("label", _blockLabel).replace("title", /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/).getRegex();
var list = edit(/^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/).replace(/bull/g, bullet).getRegex();
var _tag = "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";
var _comment = /<!--(?:-?>|[\s\S]*?(?:-->|$))/;
var html = edit("^ {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", _comment).replace("tag", _tag).replace("attribute", / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex();
var paragraph = edit(_paragraph).replace("hr", hr).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", _tag).getRegex();
var blockquote = edit(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/).replace("paragraph", paragraph).getRegex();
var blockNormal = {
blockquote,
code: blockCode,
def,
fences,
heading,
hr,
html,
lheading,
list,
newline,
paragraph,
table: noopTest,
text: blockText
};
var gfmTable = edit("^ *([^\\n ].*)\\n" + " {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)" + "(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)").replace("hr", hr).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", _tag).getRegex();
var blockGfm = {
...blockNormal,
lheading: lheadingGfm,
table: gfmTable,
paragraph: edit(_paragraph).replace("hr", hr).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("|lheading", "").replace("table", gfmTable).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", _tag).getRegex()
};
var blockPedantic = {
...blockNormal,
html: edit("^ *(?:comment *(?:\\n|\\s*$)" + "|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)" + `|<tag(?:"[^"]*"|'[^']*'|\\s[^'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))`).replace("comment", _comment).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: noopTest,
lheading: /^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/,
paragraph: edit(_paragraph).replace("hr", hr).replace("heading", ` *#{1,6} *[^
]`).replace("lheading", lheading).replace("|table", "").replace("blockquote", " {0,3}>").replace("|fences", "").replace("|list", "").replace("|html", "").replace("|tag", "").getRegex()
};
var escape$1 = /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/;
var inlineCode = /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/;
var br = /^( {2,}|\\)\n(?!\s*$)/;
var inlineText = /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/;
var _punctuation = /[\p{P}\p{S}]/u;
var _punctuationOrSpace = /[\s\p{P}\p{S}]/u;
var _notPunctuationOrSpace = /[^\s\p{P}\p{S}]/u;
var punctuation = edit(/^((?![*_])punctSpace)/, "u").replace(/punctSpace/g, _punctuationOrSpace).getRegex();
var _punctuationGfmStrongEm = /(?!~)[\p{P}\p{S}]/u;
var _punctuationOrSpaceGfmStrongEm = /(?!~)[\s\p{P}\p{S}]/u;
var _notPunctuationOrSpaceGfmStrongEm = /(?:[^\s\p{P}\p{S}]|~)/u;
var blockSkip = /\[[^