Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@mdit/plugin-embed

Package Overview
Dependencies
Maintainers
1
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@mdit/plugin-embed - npm Package Compare versions

Comparing version
0.22.0
to
0.22.1
+1
-1
lib/browser.js

@@ -1,2 +0,2 @@

function b(t){switch(t){case 9:case 32:return!0}return!1}const h=(t,e)=>{if(t.charCodeAt(e)!==123||t.charCodeAt(e+1)!==37)return!1;let c=e-1,l=0;for(;c>=0&&t.charCodeAt(c)===92;)l++,c--;return l%2!==1},m=(t,e)=>t.charCodeAt(e)===37&&t.charCodeAt(e+1)===125,_=t=>(e,c)=>{const l=e.pos,a=e.src.length;if(a-l<5||!h(e.src,l))return!1;let r=l+2;for(;r<a&&b(e.src.charCodeAt(r));)r++;let s=r,o=!1;for(;s+1<a;s++){if(h(e.src,s))return!1;if(m(e.src,s)){o=!0;break}}if(!o)return!1;let n=r+1;for(;n<s&&!b(e.src.charCodeAt(n));)n++;const f=e.src.slice(r,n);if(!t.has(f))return!1;if(!c){const i=e.push("embed_inline","embed",0),p=n?e.src.slice(n+1,s).trim().replace(/\\{%/g,"{%").replace(/%\\}/g,"%}"):"";i.markup="{% %}",i.info=f,i.content=p}return e.pos=s+2,!0},g=t=>(e,c,l,a)=>{const r=e.bMarks[c]+e.tShift[c];let s=e.eMarks[c];const{src:o}=e;if(s-r<5||e.src.charCodeAt(r)!==123||e.src.charCodeAt(r+1)!==37)return!1;s=e.skipSpacesBack(s,r);const n=s-2;if(!m(o,n))return!1;let f=r+2;for(;f<n&&b(e.src.charCodeAt(f));)f++;let i=0;for(let u=f;u+1<n;u++){if(h(e.src,u)||m(e.src,u))return!1;i||b(e.src.charCodeAt(u))&&(i=u)}const p=i?e.src.slice(f,i):e.src.slice(f,n+1).trimEnd();if(!t.has(p))return!1;if(a)return!0;const k=i?e.src.slice(i+1,n).trim().replace(/\\{%/g,"{%").replace(/%\\}/g,"%}"):"",d=e.push("embed_block","embed",0);return d.block=!0,d.info=p,d.content=k,d.map=[c,c+1],d.markup="{% %}",e.line=c+1,!0},A=(t,{config:e=[]}={})=>{const c=t,l=c.__embedMap??=new Map,a=c.__inlineEmbedMap??=new Map;e.forEach(r=>{l.set(r.name,r),r.allowInline&&a.set(r.name,r)}),"embed_block"in t.renderer.rules||(t.block.ruler.before("paragraph","embed_block",g(l),{alt:["paragraph","reference","blockquote","list"]}),t.renderer.rules.embed_block=(r,s)=>{const o=r[s];return l.get(o.info).setup(o.content)}),a.size&&!("embed_inline"in t.renderer.rules)&&(t.inline.ruler.before("emphasis","embed_inline",_(a)),t.renderer.rules.embed_inline=(r,s)=>{const o=r[s];return a.get(o.info).setup(o.content)})};export{A as embed};
function p(t){switch(t){case 9:case 32:return!0}return!1}const m=(t,e)=>{if(t.charCodeAt(e)!==123||t.charCodeAt(e+1)!==37)return!1;let c=e-1,a=0;for(;c>=0&&t.charCodeAt(c)===92;)a++,c--;return a%2!==1},h=(t,e)=>t.charCodeAt(e)===37&&t.charCodeAt(e+1)===125,g=t=>(e,c)=>{const a=e.pos,o=e.src.length;if(o-a<5||!m(e.src,a))return!1;let r=a+2;for(;r<o&&p(e.src.charCodeAt(r));)r++;let s=r,l=!1;for(;s+1<o;s++){if(m(e.src,s))return!1;if(h(e.src,s)){l=!0;break}}if(!l)return!1;let n=r+1;for(;n<s&&!p(e.src.charCodeAt(n));)n++;const f=e.src.slice(r,n);if(!t.has(f))return!1;if(!c){const i=e.push("embed_inline","embed",0),b=n?e.src.slice(n+1,s).trim().replace(/\\{%/g,"{%").replace(/%\\}/g,"%}"):"";i.markup="{% %}",i.info=f,i.content=b}return e.pos=s+2,!0},A=t=>(e,c,a,o)=>{const r=e.bMarks[c]+e.tShift[c];let s=e.eMarks[c];const{src:l}=e;if(s-r<5||e.src.charCodeAt(r)!==123||e.src.charCodeAt(r+1)!==37)return!1;s=e.skipSpacesBack(s,r);const n=s-2;if(!h(l,n))return!1;let f=r+2;for(;f<n&&p(e.src.charCodeAt(f));)f++;let i=-1;for(let u=f;u+1<n;u++){if(m(e.src,u)||h(e.src,u))return!1;i===-1&&p(e.src.charCodeAt(u))&&(i=u)}const b=i===-1?e.src.slice(f,n+1).trimEnd():e.src.slice(f,i);if(!t.has(b))return!1;if(o)return!0;const k=i===-1?"":e.src.slice(i+1,n).trim().replace(/\\{%/g,"{%").replace(/%\\}/g,"%}"),d=e.push("embed_block","embed",0);return d.block=!0,d.info=b,d.content=k,d.map=[c,c+1],d.markup="{% %}",e.line=c+1,!0},_=(t,e)=>{if(typeof e!="object"||!Array.isArray(e.config))throw new Error("[@mdit/plugin-embed]: config is required and must be an array.");const c=t,a=c.__embedMap??=new Map,o=c.__inlineEmbedMap??=new Map;e.config.forEach(r=>{a.set(r.name,r),r.allowInline&&o.set(r.name,r)}),"embed_block"in t.renderer.rules||(t.block.ruler.before("paragraph","embed_block",A(a),{alt:["paragraph","reference","blockquote","list"]}),t.renderer.rules.embed_block=(r,s)=>{const l=r[s];return a.get(l.info).setup(l.content)}),o.size&&!("embed_inline"in t.renderer.rules)&&(t.inline.ruler.before("emphasis","embed_inline",g(o)),t.renderer.rules.embed_inline=(r,s)=>{const l=r[s];return o.get(l.info).setup(l.content)})};export{_ as embed};
//# sourceMappingURL=browser.js.map

@@ -1,1 +0,1 @@

{"version":3,"file":"browser.js","sources":["../../../node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/common/utils.mjs","../src/plugin.ts"],"sourcesContent":["// Utilities\n//\n\nimport * as mdurl from 'mdurl'\nimport * as ucmicro from 'uc.micro'\nimport { decodeHTML } from 'entities'\n\nfunction _class (obj) { return Object.prototype.toString.call(obj) }\n\nfunction isString (obj) { return _class(obj) === '[object String]' }\n\nconst _hasOwnProperty = Object.prototype.hasOwnProperty\n\nfunction has (object, key) {\n return _hasOwnProperty.call(object, key)\n}\n\n// Merge objects\n//\nfunction assign (obj /* from1, from2, from3, ... */) {\n const sources = Array.prototype.slice.call(arguments, 1)\n\n sources.forEach(function (source) {\n if (!source) { return }\n\n if (typeof source !== 'object') {\n throw new TypeError(source + 'must be object')\n }\n\n Object.keys(source).forEach(function (key) {\n obj[key] = source[key]\n })\n })\n\n return obj\n}\n\n// Remove element from array and put another array at those position.\n// Useful for some operations with tokens\nfunction arrayReplaceAt (src, pos, newElements) {\n return [].concat(src.slice(0, pos), newElements, src.slice(pos + 1))\n}\n\nfunction isValidEntityCode (c) {\n /* eslint no-bitwise:0 */\n // broken sequence\n if (c >= 0xD800 && c <= 0xDFFF) { return false }\n // never used\n if (c >= 0xFDD0 && c <= 0xFDEF) { return false }\n if ((c & 0xFFFF) === 0xFFFF || (c & 0xFFFF) === 0xFFFE) { return false }\n // control codes\n if (c >= 0x00 && c <= 0x08) { return false }\n if (c === 0x0B) { return false }\n if (c >= 0x0E && c <= 0x1F) { return false }\n if (c >= 0x7F && c <= 0x9F) { return false }\n // out of range\n if (c > 0x10FFFF) { return false }\n return true\n}\n\nfunction fromCodePoint (c) {\n /* eslint no-bitwise:0 */\n if (c > 0xffff) {\n c -= 0x10000\n const surrogate1 = 0xd800 + (c >> 10)\n const surrogate2 = 0xdc00 + (c & 0x3ff)\n\n return String.fromCharCode(surrogate1, surrogate2)\n }\n return String.fromCharCode(c)\n}\n\nconst UNESCAPE_MD_RE = /\\\\([!\"#$%&'()*+,\\-./:;<=>?@[\\\\\\]^_`{|}~])/g\nconst ENTITY_RE = /&([a-z#][a-z0-9]{1,31});/gi\nconst UNESCAPE_ALL_RE = new RegExp(UNESCAPE_MD_RE.source + '|' + ENTITY_RE.source, 'gi')\n\nconst DIGITAL_ENTITY_TEST_RE = /^#((?:x[a-f0-9]{1,8}|[0-9]{1,8}))$/i\n\nfunction replaceEntityPattern (match, name) {\n if (name.charCodeAt(0) === 0x23/* # */ && DIGITAL_ENTITY_TEST_RE.test(name)) {\n const code = name[1].toLowerCase() === 'x'\n ? parseInt(name.slice(2), 16)\n : parseInt(name.slice(1), 10)\n\n if (isValidEntityCode(code)) {\n return fromCodePoint(code)\n }\n\n return match\n }\n\n const decoded = decodeHTML(match)\n if (decoded !== match) {\n return decoded\n }\n\n return match\n}\n\n/* function replaceEntities(str) {\n if (str.indexOf('&') < 0) { return str; }\n\n return str.replace(ENTITY_RE, replaceEntityPattern);\n} */\n\nfunction unescapeMd (str) {\n if (str.indexOf('\\\\') < 0) { return str }\n return str.replace(UNESCAPE_MD_RE, '$1')\n}\n\nfunction unescapeAll (str) {\n if (str.indexOf('\\\\') < 0 && str.indexOf('&') < 0) { return str }\n\n return str.replace(UNESCAPE_ALL_RE, function (match, escaped, entity) {\n if (escaped) { return escaped }\n return replaceEntityPattern(match, entity)\n })\n}\n\nconst HTML_ESCAPE_TEST_RE = /[&<>\"]/\nconst HTML_ESCAPE_REPLACE_RE = /[&<>\"]/g\nconst HTML_REPLACEMENTS = {\n '&': '&amp;',\n '<': '&lt;',\n '>': '&gt;',\n '\"': '&quot;'\n}\n\nfunction replaceUnsafeChar (ch) {\n return HTML_REPLACEMENTS[ch]\n}\n\nfunction escapeHtml (str) {\n if (HTML_ESCAPE_TEST_RE.test(str)) {\n return str.replace(HTML_ESCAPE_REPLACE_RE, replaceUnsafeChar)\n }\n return str\n}\n\nconst REGEXP_ESCAPE_RE = /[.?*+^$[\\]\\\\(){}|-]/g\n\nfunction escapeRE (str) {\n return str.replace(REGEXP_ESCAPE_RE, '\\\\$&')\n}\n\nfunction isSpace (code) {\n switch (code) {\n case 0x09:\n case 0x20:\n return true\n }\n return false\n}\n\n// Zs (unicode class) || [\\t\\f\\v\\r\\n]\nfunction isWhiteSpace (code) {\n if (code >= 0x2000 && code <= 0x200A) { return true }\n switch (code) {\n case 0x09: // \\t\n case 0x0A: // \\n\n case 0x0B: // \\v\n case 0x0C: // \\f\n case 0x0D: // \\r\n case 0x20:\n case 0xA0:\n case 0x1680:\n case 0x202F:\n case 0x205F:\n case 0x3000:\n return true\n }\n return false\n}\n\n/* eslint-disable max-len */\n\n// Currently without astral characters support.\nfunction isPunctChar (ch) {\n return ucmicro.P.test(ch) || ucmicro.S.test(ch)\n}\n\n// Markdown ASCII punctuation characters.\n//\n// !, \", #, $, %, &, ', (, ), *, +, ,, -, ., /, :, ;, <, =, >, ?, @, [, \\, ], ^, _, `, {, |, }, or ~\n// http://spec.commonmark.org/0.15/#ascii-punctuation-character\n//\n// Don't confuse with unicode punctuation !!! It lacks some chars in ascii range.\n//\nfunction isMdAsciiPunct (ch) {\n switch (ch) {\n case 0x21/* ! */:\n case 0x22/* \" */:\n case 0x23/* # */:\n case 0x24/* $ */:\n case 0x25/* % */:\n case 0x26/* & */:\n case 0x27/* ' */:\n case 0x28/* ( */:\n case 0x29/* ) */:\n case 0x2A/* * */:\n case 0x2B/* + */:\n case 0x2C/* , */:\n case 0x2D/* - */:\n case 0x2E/* . */:\n case 0x2F/* / */:\n case 0x3A/* : */:\n case 0x3B/* ; */:\n case 0x3C/* < */:\n case 0x3D/* = */:\n case 0x3E/* > */:\n case 0x3F/* ? */:\n case 0x40/* @ */:\n case 0x5B/* [ */:\n case 0x5C/* \\ */:\n case 0x5D/* ] */:\n case 0x5E/* ^ */:\n case 0x5F/* _ */:\n case 0x60/* ` */:\n case 0x7B/* { */:\n case 0x7C/* | */:\n case 0x7D/* } */:\n case 0x7E/* ~ */:\n return true\n default:\n return false\n }\n}\n\n// Hepler to unify [reference labels].\n//\nfunction normalizeReference (str) {\n // Trim and collapse whitespace\n //\n str = str.trim().replace(/\\s+/g, ' ')\n\n // In node v10 'ẞ'.toLowerCase() === 'Ṿ', which is presumed to be a bug\n // fixed in v12 (couldn't find any details).\n //\n // So treat this one as a special case\n // (remove this when node v10 is no longer supported).\n //\n if ('ẞ'.toLowerCase() === 'Ṿ') {\n str = str.replace(/ẞ/g, 'ß')\n }\n\n // .toLowerCase().toUpperCase() should get rid of all differences\n // between letter variants.\n //\n // Simple .toLowerCase() doesn't normalize 125 code points correctly,\n // and .toUpperCase doesn't normalize 6 of them (list of exceptions:\n // İ, ϴ, ẞ, Ω, K, Å - those are already uppercased, but have differently\n // uppercased versions).\n //\n // Here's an example showing how it happens. Lets take greek letter omega:\n // uppercase U+0398 (Θ), U+03f4 (ϴ) and lowercase U+03b8 (θ), U+03d1 (ϑ)\n //\n // Unicode entries:\n // 0398;GREEK CAPITAL LETTER THETA;Lu;0;L;;;;;N;;;;03B8;\n // 03B8;GREEK SMALL LETTER THETA;Ll;0;L;;;;;N;;;0398;;0398\n // 03D1;GREEK THETA SYMBOL;Ll;0;L;<compat> 03B8;;;;N;GREEK SMALL LETTER SCRIPT THETA;;0398;;0398\n // 03F4;GREEK CAPITAL THETA SYMBOL;Lu;0;L;<compat> 0398;;;;N;;;;03B8;\n //\n // Case-insensitive comparison should treat all of them as equivalent.\n //\n // But .toLowerCase() doesn't change ϑ (it's already lowercase),\n // and .toUpperCase() doesn't change ϴ (already uppercase).\n //\n // Applying first lower then upper case normalizes any character:\n // '\\u0398\\u03f4\\u03b8\\u03d1'.toLowerCase().toUpperCase() === '\\u0398\\u0398\\u0398\\u0398'\n //\n // Note: this is equivalent to unicode case folding; unicode normalization\n // is a different step that is not required here.\n //\n // Final result should be uppercased, because it's later stored in an object\n // (this avoid a conflict with Object.prototype members,\n // most notably, `__proto__`)\n //\n return str.toLowerCase().toUpperCase()\n}\n\n// Re-export libraries commonly used in both markdown-it and its plugins,\n// so plugins won't have to depend on them explicitly, which reduces their\n// bundled size (e.g. a browser build).\n//\nconst lib = { mdurl, ucmicro }\n\nexport {\n lib,\n assign,\n isString,\n has,\n unescapeMd,\n unescapeAll,\n isValidEntityCode,\n fromCodePoint,\n escapeHtml,\n arrayReplaceAt,\n isSpace,\n isWhiteSpace,\n isMdAsciiPunct,\n isPunctChar,\n escapeRE,\n normalizeReference\n}\n","import type MarkdownIt from \"markdown-it\";\nimport type { PluginWithOptions } from \"markdown-it\";\nimport { isSpace } from \"markdown-it/lib/common/utils.mjs\";\nimport type { RuleBlock } from \"markdown-it/lib/parser_block.mjs\";\nimport type { RuleInline } from \"markdown-it/lib/parser_inline.mjs\";\nimport type Token from \"markdown-it/lib/token.mjs\";\n\nimport type { EmbedConfig, MarkdownItEmbedOptions } from \"./options.js\";\n\nconst checkInlineOpeningMarker = (src: string, current: number): boolean => {\n if (\n src.charCodeAt(current) !== 123 /* { */ ||\n src.charCodeAt(current + 1) !== 37 /* % */\n )\n return false;\n\n // Check if the opening marker was escaped\n let pos = current - 1;\n let backslashCount = 0;\n\n while (pos >= 0 && src.charCodeAt(pos) === 92 /* \\ */) {\n backslashCount++;\n pos--;\n }\n\n // If opening {% is escaped (odd number of preceding backslashes), don't parse\n if (backslashCount % 2 === 1) return false;\n\n return true;\n};\n\nconst checkClosingMarker = (src: string, current: number): boolean =>\n src.charCodeAt(current) === 37 /* % */ &&\n src.charCodeAt(current + 1) === 125; /* } */\n\n/*\n * Parse inline embed with bracket syntax: {%...%}\n */\nconst getEmbedInline =\n (inlineEmbedMap: Map<string, EmbedConfig>): RuleInline =>\n (state, silent) => {\n const start = state.pos;\n const max = state.src.length;\n\n // minimum length check for inline embed - at least 5 characters: {%x%}\n if (max - start < 5) return false;\n\n // check opening marker\n if (!checkInlineOpeningMarker(state.src, start)) return false;\n\n let contentStart = start + 2; // Move past the opening {% marker\n\n // skip spaces\n while (contentStart < max) {\n if (!isSpace(state.src.charCodeAt(contentStart))) break;\n contentStart++;\n }\n\n let contentEnd = contentStart;\n let found = false;\n\n for (; contentEnd + 1 < max; contentEnd++) {\n // must not include opening marker\n if (checkInlineOpeningMarker(state.src, contentEnd)) return false;\n if (checkClosingMarker(state.src, contentEnd)) {\n found = true;\n break;\n }\n }\n\n // No closing marker found\n if (!found) return false;\n\n // get first space\n let spacer = contentStart + 1;\n\n while (spacer < contentEnd) {\n if (isSpace(state.src.charCodeAt(spacer))) break;\n spacer++;\n }\n\n // Extract embed name\n const name = state.src.slice(contentStart, spacer);\n\n // Check if embed name exists in the map\n if (!inlineEmbedMap.has(name)) return false;\n\n if (!silent) {\n const token = state.push(\"embed_inline\", \"embed\", 0);\n const params = spacer\n ? state.src\n .slice(spacer + 1, contentEnd)\n .trim()\n .replace(/\\\\{%/g, \"{%\")\n .replace(/%\\\\}/g, \"%}\")\n : \"\";\n\n token.markup = \"{% %}\";\n token.info = name;\n token.content = params;\n }\n\n // Move past the closing %} marker\n state.pos = contentEnd + 2;\n\n return true;\n };\n\n/*\n * Parse block embed with syntax: {% ... %}\n */\nconst getEmbedBlock =\n (embedMap: Map<string, EmbedConfig>): RuleBlock =>\n (state, startLine, _, silent) => {\n const start = state.bMarks[startLine] + state.tShift[startLine];\n let max = state.eMarks[startLine];\n const { src } = state;\n\n // minimum length check for block embed - at least 5 characters: {%x%}\n if (max - start < 5) return false;\n\n // check opening marker\n if (\n state.src.charCodeAt(start) !== 123 /* { */ ||\n state.src.charCodeAt(start + 1) !== 37 /* % */\n )\n return false;\n\n max = state.skipSpacesBack(max, start);\n\n const contentEnd = max - 2;\n\n if (!checkClosingMarker(src, contentEnd)) return false;\n\n let contentStart = start + 2;\n\n // skip spaces\n while (contentStart < contentEnd) {\n if (!isSpace(state.src.charCodeAt(contentStart))) break;\n contentStart++;\n }\n\n let spacer = 0;\n\n for (let pos = contentStart; pos + 1 < contentEnd; pos++) {\n // must not include unescaped opening marker or closing marker\n if (checkInlineOpeningMarker(state.src, pos)) return false;\n if (checkClosingMarker(state.src, pos)) return false;\n if (spacer) continue;\n if (isSpace(state.src.charCodeAt(pos))) spacer = pos;\n }\n\n // Extract content between {% and %}\n const name = spacer\n ? state.src.slice(contentStart, spacer)\n : state.src.slice(contentStart, contentEnd + 1).trimEnd();\n\n // Check if embed name exists in the map\n if (!embedMap.has(name)) return false;\n\n if (silent) return true;\n\n const params = spacer\n ? state.src\n .slice(spacer + 1, contentEnd)\n .trim()\n .replace(/\\\\{%/g, \"{%\")\n .replace(/%\\\\}/g, \"%}\")\n : \"\";\n\n const token = state.push(\"embed_block\", \"embed\", 0);\n\n token.block = true;\n token.info = name;\n token.content = params;\n token.map = [startLine, startLine + 1];\n token.markup = \"{% %}\";\n\n // Advance to the next line\n state.line = startLine + 1;\n\n return true;\n };\n\nexport const embed: PluginWithOptions<MarkdownItEmbedOptions> = (\n md: MarkdownIt,\n { config = [] }: MarkdownItEmbedOptions = {},\n) => {\n // Get existing maps or create new ones to support multiple plugin instances\n const mdWithMaps = md as MarkdownIt & {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n __embedMap?: Map<string, EmbedConfig>;\n // eslint-disable-next-line @typescript-eslint/naming-convention\n __inlineEmbedMap?: Map<string, EmbedConfig>;\n };\n\n const embedMap = (mdWithMaps.__embedMap ??= new Map<string, EmbedConfig>());\n const inlineEmbedMap = (mdWithMaps.__inlineEmbedMap ??= new Map<\n string,\n EmbedConfig\n >());\n\n config.forEach((item) => {\n embedMap.set(item.name, item);\n // Inline embeds are only supported when allowInline is true\n if (item.allowInline) inlineEmbedMap.set(item.name, item);\n });\n\n // Only register rules if not already registered\n // check embed_block rules here\n if (!(\"embed_block\" in md.renderer.rules)) {\n // Register the block rule\n md.block.ruler.before(\"paragraph\", \"embed_block\", getEmbedBlock(embedMap), {\n alt: [\"paragraph\", \"reference\", \"blockquote\", \"list\"],\n });\n\n // Register the renderers\n md.renderer.rules.embed_block = (\n tokens: Token[],\n index: number,\n ): string => {\n const token = tokens[index];\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return embedMap.get(token.info)!.setup(token.content);\n };\n }\n\n // only register embed_inline rules if inline embeds are allowed\n if (inlineEmbedMap.size && !(\"embed_inline\" in md.renderer.rules)) {\n // Register the inline rule\n md.inline.ruler.before(\n \"emphasis\",\n \"embed_inline\",\n getEmbedInline(inlineEmbedMap),\n );\n\n md.renderer.rules.embed_inline = (\n tokens: Token[],\n index: number,\n ): string => {\n const token = tokens[index];\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return inlineEmbedMap.get(token.info)!.setup(token.content);\n };\n }\n};\n"],"names":["isSpace","code","checkInlineOpeningMarker","src","current","pos","backslashCount","checkClosingMarker","getEmbedInline","inlineEmbedMap","state","silent","start","max","contentStart","contentEnd","found","spacer","name","token","params","getEmbedBlock","embedMap","startLine","_","embed","md","config","mdWithMaps","item","tokens","index"],"mappings":"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","x_google_ignoreList":[0]}
{"version":3,"file":"browser.js","sources":["../../../node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/common/utils.mjs","../src/plugin.ts"],"sourcesContent":["// Utilities\n//\n\nimport * as mdurl from 'mdurl'\nimport * as ucmicro from 'uc.micro'\nimport { decodeHTML } from 'entities'\n\nfunction _class (obj) { return Object.prototype.toString.call(obj) }\n\nfunction isString (obj) { return _class(obj) === '[object String]' }\n\nconst _hasOwnProperty = Object.prototype.hasOwnProperty\n\nfunction has (object, key) {\n return _hasOwnProperty.call(object, key)\n}\n\n// Merge objects\n//\nfunction assign (obj /* from1, from2, from3, ... */) {\n const sources = Array.prototype.slice.call(arguments, 1)\n\n sources.forEach(function (source) {\n if (!source) { return }\n\n if (typeof source !== 'object') {\n throw new TypeError(source + 'must be object')\n }\n\n Object.keys(source).forEach(function (key) {\n obj[key] = source[key]\n })\n })\n\n return obj\n}\n\n// Remove element from array and put another array at those position.\n// Useful for some operations with tokens\nfunction arrayReplaceAt (src, pos, newElements) {\n return [].concat(src.slice(0, pos), newElements, src.slice(pos + 1))\n}\n\nfunction isValidEntityCode (c) {\n /* eslint no-bitwise:0 */\n // broken sequence\n if (c >= 0xD800 && c <= 0xDFFF) { return false }\n // never used\n if (c >= 0xFDD0 && c <= 0xFDEF) { return false }\n if ((c & 0xFFFF) === 0xFFFF || (c & 0xFFFF) === 0xFFFE) { return false }\n // control codes\n if (c >= 0x00 && c <= 0x08) { return false }\n if (c === 0x0B) { return false }\n if (c >= 0x0E && c <= 0x1F) { return false }\n if (c >= 0x7F && c <= 0x9F) { return false }\n // out of range\n if (c > 0x10FFFF) { return false }\n return true\n}\n\nfunction fromCodePoint (c) {\n /* eslint no-bitwise:0 */\n if (c > 0xffff) {\n c -= 0x10000\n const surrogate1 = 0xd800 + (c >> 10)\n const surrogate2 = 0xdc00 + (c & 0x3ff)\n\n return String.fromCharCode(surrogate1, surrogate2)\n }\n return String.fromCharCode(c)\n}\n\nconst UNESCAPE_MD_RE = /\\\\([!\"#$%&'()*+,\\-./:;<=>?@[\\\\\\]^_`{|}~])/g\nconst ENTITY_RE = /&([a-z#][a-z0-9]{1,31});/gi\nconst UNESCAPE_ALL_RE = new RegExp(UNESCAPE_MD_RE.source + '|' + ENTITY_RE.source, 'gi')\n\nconst DIGITAL_ENTITY_TEST_RE = /^#((?:x[a-f0-9]{1,8}|[0-9]{1,8}))$/i\n\nfunction replaceEntityPattern (match, name) {\n if (name.charCodeAt(0) === 0x23/* # */ && DIGITAL_ENTITY_TEST_RE.test(name)) {\n const code = name[1].toLowerCase() === 'x'\n ? parseInt(name.slice(2), 16)\n : parseInt(name.slice(1), 10)\n\n if (isValidEntityCode(code)) {\n return fromCodePoint(code)\n }\n\n return match\n }\n\n const decoded = decodeHTML(match)\n if (decoded !== match) {\n return decoded\n }\n\n return match\n}\n\n/* function replaceEntities(str) {\n if (str.indexOf('&') < 0) { return str; }\n\n return str.replace(ENTITY_RE, replaceEntityPattern);\n} */\n\nfunction unescapeMd (str) {\n if (str.indexOf('\\\\') < 0) { return str }\n return str.replace(UNESCAPE_MD_RE, '$1')\n}\n\nfunction unescapeAll (str) {\n if (str.indexOf('\\\\') < 0 && str.indexOf('&') < 0) { return str }\n\n return str.replace(UNESCAPE_ALL_RE, function (match, escaped, entity) {\n if (escaped) { return escaped }\n return replaceEntityPattern(match, entity)\n })\n}\n\nconst HTML_ESCAPE_TEST_RE = /[&<>\"]/\nconst HTML_ESCAPE_REPLACE_RE = /[&<>\"]/g\nconst HTML_REPLACEMENTS = {\n '&': '&amp;',\n '<': '&lt;',\n '>': '&gt;',\n '\"': '&quot;'\n}\n\nfunction replaceUnsafeChar (ch) {\n return HTML_REPLACEMENTS[ch]\n}\n\nfunction escapeHtml (str) {\n if (HTML_ESCAPE_TEST_RE.test(str)) {\n return str.replace(HTML_ESCAPE_REPLACE_RE, replaceUnsafeChar)\n }\n return str\n}\n\nconst REGEXP_ESCAPE_RE = /[.?*+^$[\\]\\\\(){}|-]/g\n\nfunction escapeRE (str) {\n return str.replace(REGEXP_ESCAPE_RE, '\\\\$&')\n}\n\nfunction isSpace (code) {\n switch (code) {\n case 0x09:\n case 0x20:\n return true\n }\n return false\n}\n\n// Zs (unicode class) || [\\t\\f\\v\\r\\n]\nfunction isWhiteSpace (code) {\n if (code >= 0x2000 && code <= 0x200A) { return true }\n switch (code) {\n case 0x09: // \\t\n case 0x0A: // \\n\n case 0x0B: // \\v\n case 0x0C: // \\f\n case 0x0D: // \\r\n case 0x20:\n case 0xA0:\n case 0x1680:\n case 0x202F:\n case 0x205F:\n case 0x3000:\n return true\n }\n return false\n}\n\n/* eslint-disable max-len */\n\n// Currently without astral characters support.\nfunction isPunctChar (ch) {\n return ucmicro.P.test(ch) || ucmicro.S.test(ch)\n}\n\n// Markdown ASCII punctuation characters.\n//\n// !, \", #, $, %, &, ', (, ), *, +, ,, -, ., /, :, ;, <, =, >, ?, @, [, \\, ], ^, _, `, {, |, }, or ~\n// http://spec.commonmark.org/0.15/#ascii-punctuation-character\n//\n// Don't confuse with unicode punctuation !!! It lacks some chars in ascii range.\n//\nfunction isMdAsciiPunct (ch) {\n switch (ch) {\n case 0x21/* ! */:\n case 0x22/* \" */:\n case 0x23/* # */:\n case 0x24/* $ */:\n case 0x25/* % */:\n case 0x26/* & */:\n case 0x27/* ' */:\n case 0x28/* ( */:\n case 0x29/* ) */:\n case 0x2A/* * */:\n case 0x2B/* + */:\n case 0x2C/* , */:\n case 0x2D/* - */:\n case 0x2E/* . */:\n case 0x2F/* / */:\n case 0x3A/* : */:\n case 0x3B/* ; */:\n case 0x3C/* < */:\n case 0x3D/* = */:\n case 0x3E/* > */:\n case 0x3F/* ? */:\n case 0x40/* @ */:\n case 0x5B/* [ */:\n case 0x5C/* \\ */:\n case 0x5D/* ] */:\n case 0x5E/* ^ */:\n case 0x5F/* _ */:\n case 0x60/* ` */:\n case 0x7B/* { */:\n case 0x7C/* | */:\n case 0x7D/* } */:\n case 0x7E/* ~ */:\n return true\n default:\n return false\n }\n}\n\n// Hepler to unify [reference labels].\n//\nfunction normalizeReference (str) {\n // Trim and collapse whitespace\n //\n str = str.trim().replace(/\\s+/g, ' ')\n\n // In node v10 'ẞ'.toLowerCase() === 'Ṿ', which is presumed to be a bug\n // fixed in v12 (couldn't find any details).\n //\n // So treat this one as a special case\n // (remove this when node v10 is no longer supported).\n //\n if ('ẞ'.toLowerCase() === 'Ṿ') {\n str = str.replace(/ẞ/g, 'ß')\n }\n\n // .toLowerCase().toUpperCase() should get rid of all differences\n // between letter variants.\n //\n // Simple .toLowerCase() doesn't normalize 125 code points correctly,\n // and .toUpperCase doesn't normalize 6 of them (list of exceptions:\n // İ, ϴ, ẞ, Ω, K, Å - those are already uppercased, but have differently\n // uppercased versions).\n //\n // Here's an example showing how it happens. Lets take greek letter omega:\n // uppercase U+0398 (Θ), U+03f4 (ϴ) and lowercase U+03b8 (θ), U+03d1 (ϑ)\n //\n // Unicode entries:\n // 0398;GREEK CAPITAL LETTER THETA;Lu;0;L;;;;;N;;;;03B8;\n // 03B8;GREEK SMALL LETTER THETA;Ll;0;L;;;;;N;;;0398;;0398\n // 03D1;GREEK THETA SYMBOL;Ll;0;L;<compat> 03B8;;;;N;GREEK SMALL LETTER SCRIPT THETA;;0398;;0398\n // 03F4;GREEK CAPITAL THETA SYMBOL;Lu;0;L;<compat> 0398;;;;N;;;;03B8;\n //\n // Case-insensitive comparison should treat all of them as equivalent.\n //\n // But .toLowerCase() doesn't change ϑ (it's already lowercase),\n // and .toUpperCase() doesn't change ϴ (already uppercase).\n //\n // Applying first lower then upper case normalizes any character:\n // '\\u0398\\u03f4\\u03b8\\u03d1'.toLowerCase().toUpperCase() === '\\u0398\\u0398\\u0398\\u0398'\n //\n // Note: this is equivalent to unicode case folding; unicode normalization\n // is a different step that is not required here.\n //\n // Final result should be uppercased, because it's later stored in an object\n // (this avoid a conflict with Object.prototype members,\n // most notably, `__proto__`)\n //\n return str.toLowerCase().toUpperCase()\n}\n\n// Re-export libraries commonly used in both markdown-it and its plugins,\n// so plugins won't have to depend on them explicitly, which reduces their\n// bundled size (e.g. a browser build).\n//\nconst lib = { mdurl, ucmicro }\n\nexport {\n lib,\n assign,\n isString,\n has,\n unescapeMd,\n unescapeAll,\n isValidEntityCode,\n fromCodePoint,\n escapeHtml,\n arrayReplaceAt,\n isSpace,\n isWhiteSpace,\n isMdAsciiPunct,\n isPunctChar,\n escapeRE,\n normalizeReference\n}\n","import type MarkdownIt from \"markdown-it\";\nimport type { PluginWithOptions } from \"markdown-it\";\nimport { isSpace } from \"markdown-it/lib/common/utils.mjs\";\nimport type { RuleBlock } from \"markdown-it/lib/parser_block.mjs\";\nimport type { RuleInline } from \"markdown-it/lib/parser_inline.mjs\";\nimport type Token from \"markdown-it/lib/token.mjs\";\n\nimport type { EmbedConfig, MarkdownItEmbedOptions } from \"./options.js\";\n\nconst checkInlineOpeningMarker = (src: string, current: number): boolean => {\n if (\n src.charCodeAt(current) !== 123 /* { */ ||\n src.charCodeAt(current + 1) !== 37 /* % */\n )\n return false;\n\n // Check if the opening marker was escaped\n let pos = current - 1;\n let backslashCount = 0;\n\n while (pos >= 0 && src.charCodeAt(pos) === 92 /* \\ */) {\n backslashCount++;\n pos--;\n }\n\n // If opening {% is escaped (odd number of preceding backslashes), don't parse\n if (backslashCount % 2 === 1) return false;\n\n return true;\n};\n\nconst checkClosingMarker = (src: string, current: number): boolean =>\n src.charCodeAt(current) === 37 /* % */ &&\n src.charCodeAt(current + 1) === 125; /* } */\n\n/*\n * Parse inline embed with bracket syntax: {%...%}\n */\nconst getEmbedInline =\n (inlineEmbedMap: Map<string, EmbedConfig>): RuleInline =>\n (state, silent) => {\n const start = state.pos;\n const max = state.src.length;\n\n // minimum length check for inline embed - at least 5 characters: {%x%}\n if (max - start < 5) return false;\n\n // check opening marker\n if (!checkInlineOpeningMarker(state.src, start)) return false;\n\n let contentStart = start + 2; // Move past the opening {% marker\n\n // skip spaces\n while (contentStart < max) {\n if (!isSpace(state.src.charCodeAt(contentStart))) break;\n contentStart++;\n }\n\n let contentEnd = contentStart;\n let found = false;\n\n for (; contentEnd + 1 < max; contentEnd++) {\n // must not include opening marker\n if (checkInlineOpeningMarker(state.src, contentEnd)) return false;\n if (checkClosingMarker(state.src, contentEnd)) {\n found = true;\n break;\n }\n }\n\n // No closing marker found\n if (!found) return false;\n\n // get first space\n let spacer = contentStart + 1;\n\n while (spacer < contentEnd) {\n if (isSpace(state.src.charCodeAt(spacer))) break;\n spacer++;\n }\n\n // Extract embed name\n const name = state.src.slice(contentStart, spacer);\n\n // Check if embed name exists in the map\n if (!inlineEmbedMap.has(name)) return false;\n\n if (!silent) {\n const token = state.push(\"embed_inline\", \"embed\", 0);\n const params = spacer\n ? state.src\n .slice(spacer + 1, contentEnd)\n .trim()\n .replace(/\\\\{%/g, \"{%\")\n .replace(/%\\\\}/g, \"%}\")\n : \"\";\n\n token.markup = \"{% %}\";\n token.info = name;\n token.content = params;\n }\n\n // Move past the closing %} marker\n state.pos = contentEnd + 2;\n\n return true;\n };\n\n/*\n * Parse block embed with syntax: {% ... %}\n */\nconst getEmbedBlock =\n (embedMap: Map<string, EmbedConfig>): RuleBlock =>\n (state, startLine, _, silent) => {\n const start = state.bMarks[startLine] + state.tShift[startLine];\n let max = state.eMarks[startLine];\n const { src } = state;\n\n // minimum length check for block embed - at least 5 characters: {%x%}\n if (max - start < 5) return false;\n\n // check opening marker\n if (\n state.src.charCodeAt(start) !== 123 /* { */ ||\n state.src.charCodeAt(start + 1) !== 37 /* % */\n )\n return false;\n\n max = state.skipSpacesBack(max, start);\n\n const contentEnd = max - 2;\n\n if (!checkClosingMarker(src, contentEnd)) return false;\n\n let contentStart = start + 2;\n\n // skip spaces\n while (contentStart < contentEnd) {\n if (!isSpace(state.src.charCodeAt(contentStart))) break;\n contentStart++;\n }\n\n let spacer = -1;\n\n for (let pos = contentStart; pos + 1 < contentEnd; pos++) {\n // must not include unescaped opening marker or closing marker\n if (checkInlineOpeningMarker(state.src, pos)) return false;\n if (checkClosingMarker(state.src, pos)) return false;\n if (spacer !== -1) continue;\n if (isSpace(state.src.charCodeAt(pos))) spacer = pos;\n }\n\n // Extract content between {% and %}\n const name =\n spacer === -1\n ? state.src.slice(contentStart, contentEnd + 1).trimEnd()\n : state.src.slice(contentStart, spacer);\n\n // Check if embed name exists in the map\n if (!embedMap.has(name)) return false;\n\n if (silent) return true;\n\n const params =\n spacer === -1\n ? \"\"\n : state.src\n .slice(spacer + 1, contentEnd)\n .trim()\n .replace(/\\\\{%/g, \"{%\")\n .replace(/%\\\\}/g, \"%}\");\n\n const token = state.push(\"embed_block\", \"embed\", 0);\n\n token.block = true;\n token.info = name;\n token.content = params;\n token.map = [startLine, startLine + 1];\n token.markup = \"{% %}\";\n\n // Advance to the next line\n state.line = startLine + 1;\n\n return true;\n };\n\nexport const embed: PluginWithOptions<MarkdownItEmbedOptions> = (\n md,\n options,\n) => {\n if (typeof options !== \"object\" || !Array.isArray(options.config))\n throw new Error(\n \"[@mdit/plugin-embed]: config is required and must be an array.\",\n );\n\n // Get existing maps or create new ones to support multiple plugin instances\n const mdWithMaps = md as MarkdownIt & {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n __embedMap?: Map<string, EmbedConfig>;\n // eslint-disable-next-line @typescript-eslint/naming-convention\n __inlineEmbedMap?: Map<string, EmbedConfig>;\n };\n\n const embedMap = (mdWithMaps.__embedMap ??= new Map<string, EmbedConfig>());\n const inlineEmbedMap = (mdWithMaps.__inlineEmbedMap ??= new Map<\n string,\n EmbedConfig\n >());\n\n options.config.forEach((item) => {\n embedMap.set(item.name, item);\n // Inline embeds are only supported when allowInline is true\n if (item.allowInline) inlineEmbedMap.set(item.name, item);\n });\n\n // Only register rules if not already registered\n // check embed_block rules here\n if (!(\"embed_block\" in md.renderer.rules)) {\n // Register the block rule\n md.block.ruler.before(\"paragraph\", \"embed_block\", getEmbedBlock(embedMap), {\n alt: [\"paragraph\", \"reference\", \"blockquote\", \"list\"],\n });\n\n // Register the renderers\n md.renderer.rules.embed_block = (\n tokens: Token[],\n index: number,\n ): string => {\n const token = tokens[index];\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return embedMap.get(token.info)!.setup(token.content);\n };\n }\n\n // only register embed_inline rules if inline embeds are allowed\n if (inlineEmbedMap.size && !(\"embed_inline\" in md.renderer.rules)) {\n // Register the inline rule\n md.inline.ruler.before(\n \"emphasis\",\n \"embed_inline\",\n getEmbedInline(inlineEmbedMap),\n );\n\n md.renderer.rules.embed_inline = (\n tokens: Token[],\n index: number,\n ): string => {\n const token = tokens[index];\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return inlineEmbedMap.get(token.info)!.setup(token.content);\n };\n }\n};\n"],"names":["isSpace","code","checkInlineOpeningMarker","src","current","pos","backslashCount","checkClosingMarker","getEmbedInline","inlineEmbedMap","state","silent","start","max","contentStart","contentEnd","found","spacer","name","token","params","getEmbedBlock","embedMap","startLine","_","embed","md","options","mdWithMaps","item","tokens","index"],"mappings":"AAiJA,SAASA,EAASC,EAAM,CACtB,OAAQA,EAAI,CACV,IAAK,GACL,IAAK,IACH,MAAO,EACb,CACE,MAAO,EACT,CC/IA,MAAMC,EAA2B,CAACC,EAAaC,IAA6B,CAC1E,GACED,EAAI,WAAWC,CAAO,IAAM,KAC5BD,EAAI,WAAWC,EAAU,CAAC,IAAM,GAEhC,MAAO,GAGT,IAAIC,EAAMD,EAAU,EAChBE,EAAiB,EAErB,KAAOD,GAAO,GAAKF,EAAI,WAAWE,CAAG,IAAM,IACzCC,IACAD,IAIF,OAAIC,EAAiB,IAAM,CAG7B,EAEMC,EAAqB,CAACJ,EAAaC,IACvCD,EAAI,WAAWC,CAAO,IAAM,IAC5BD,EAAI,WAAWC,EAAU,CAAC,IAAM,IAK5BI,EACHC,GACD,CAACC,EAAOC,IAAW,CACjB,MAAMC,EAAQF,EAAM,IACdG,EAAMH,EAAM,IAAI,OAMtB,GAHIG,EAAMD,EAAQ,GAGd,CAACV,EAAyBQ,EAAM,IAAKE,CAAK,EAAG,MAAO,GAExD,IAAIE,EAAeF,EAAQ,EAG3B,KAAOE,EAAeD,GACfb,EAAQU,EAAM,IAAI,WAAWI,CAAY,CAAC,GAC/CA,IAGF,IAAIC,EAAaD,EACbE,EAAQ,GAEZ,KAAOD,EAAa,EAAIF,EAAKE,IAAc,CAEzC,GAAIb,EAAyBQ,EAAM,IAAKK,CAAU,EAAG,MAAO,GAC5D,GAAIR,EAAmBG,EAAM,IAAKK,CAAU,EAAG,CAC7CC,EAAQ,GACR,KACF,CACF,CAGA,GAAI,CAACA,EAAO,MAAO,GAGnB,IAAIC,EAASH,EAAe,EAE5B,KAAOG,EAASF,GACV,CAAAf,EAAQU,EAAM,IAAI,WAAWO,CAAM,CAAC,GACxCA,IAIF,MAAMC,EAAOR,EAAM,IAAI,MAAMI,EAAcG,CAAM,EAGjD,GAAI,CAACR,EAAe,IAAIS,CAAI,EAAG,MAE/B,GAAA,GAAI,CAACP,EAAQ,CACX,MAAMQ,EAAQT,EAAM,KAAK,eAAgB,QAAS,CAAC,EAC7CU,EAASH,EACXP,EAAM,IACH,MAAMO,EAAS,EAAGF,CAAU,EAC5B,KACA,EAAA,QAAQ,QAAS,IAAI,EACrB,QAAQ,QAAS,IAAI,EACxB,GAEJI,EAAM,OAAS,QACfA,EAAM,KAAOD,EACbC,EAAM,QAAUC,CAClB,CAGA,OAAAV,EAAM,IAAMK,EAAa,EAElB,EACT,EAKIM,EACHC,GACD,CAACZ,EAAOa,EAAWC,EAAGb,IAAW,CAC/B,MAAMC,EAAQF,EAAM,OAAOa,CAAS,EAAIb,EAAM,OAAOa,CAAS,EAC9D,IAAIV,EAAMH,EAAM,OAAOa,CAAS,EAChC,KAAM,CAAE,IAAApB,CAAI,EAAIO,EAMhB,GAHIG,EAAMD,EAAQ,GAIhBF,EAAM,IAAI,WAAWE,CAAK,IAAM,KAChCF,EAAM,IAAI,WAAWE,EAAQ,CAAC,IAAM,GAEpC,MAEFC,GAAAA,EAAMH,EAAM,eAAeG,EAAKD,CAAK,EAErC,MAAMG,EAAaF,EAAM,EAEzB,GAAI,CAACN,EAAmBJ,EAAKY,CAAU,EAAG,MAAO,GAEjD,IAAID,EAAeF,EAAQ,EAG3B,KAAOE,EAAeC,GACff,EAAQU,EAAM,IAAI,WAAWI,CAAY,CAAC,GAC/CA,IAGF,IAAIG,EAAS,GAEb,QAASZ,EAAMS,EAAcT,EAAM,EAAIU,EAAYV,IAAO,CAGxD,GADIH,EAAyBQ,EAAM,IAAKL,CAAG,GACvCE,EAAmBG,EAAM,IAAKL,CAAG,EAAG,SACpCY,IAAW,IACXjB,EAAQU,EAAM,IAAI,WAAWL,CAAG,CAAC,IAAGY,EAASZ,EACnD,CAGA,MAAMa,EACJD,IAAW,GACPP,EAAM,IAAI,MAAMI,EAAcC,EAAa,CAAC,EAAE,QAC9CL,EAAAA,EAAM,IAAI,MAAMI,EAAcG,CAAM,EAG1C,GAAI,CAACK,EAAS,IAAIJ,CAAI,EAAG,MAAO,GAEhC,GAAIP,EAAQ,MAAO,GAEnB,MAAMS,EACJH,IAAW,GACP,GACAP,EAAM,IACH,MAAMO,EAAS,EAAGF,CAAU,EAC5B,KAAK,EACL,QAAQ,QAAS,IAAI,EACrB,QAAQ,QAAS,IAAI,EAExBI,EAAQT,EAAM,KAAK,cAAe,QAAS,CAAC,EAElD,OAAAS,EAAM,MAAQ,GACdA,EAAM,KAAOD,EACbC,EAAM,QAAUC,EAChBD,EAAM,IAAM,CAACI,EAAWA,EAAY,CAAC,EACrCJ,EAAM,OAAS,QAGfT,EAAM,KAAOa,EAAY,EAElB,EACT,EAEWE,EAAmD,CAC9DC,EACAC,IACG,CACH,GAAI,OAAOA,GAAY,UAAY,CAAC,MAAM,QAAQA,EAAQ,MAAM,EAC9D,MAAM,IAAI,MACR,gEACF,EAGF,MAAMC,EAAaF,EAObJ,EAAYM,EAAW,aAAe,IAAI,IAC1CnB,EAAkBmB,EAAW,mBAAqB,IAAI,IAK5DD,EAAQ,OAAO,QAASE,GAAS,CAC/BP,EAAS,IAAIO,EAAK,KAAMA,CAAI,EAExBA,EAAK,aAAapB,EAAe,IAAIoB,EAAK,KAAMA,CAAI,CAC1D,CAAC,EAIK,gBAAiBH,EAAG,SAAS,QAEjCA,EAAG,MAAM,MAAM,OAAO,YAAa,cAAeL,EAAcC,CAAQ,EAAG,CACzE,IAAK,CAAC,YAAa,YAAa,aAAc,MAAM,CACtD,CAAC,EAGDI,EAAG,SAAS,MAAM,YAAc,CAC9BI,EACAC,IACW,CACX,MAAMZ,EAAQW,EAAOC,CAAK,EAG1B,OAAOT,EAAS,IAAIH,EAAM,IAAI,EAAG,MAAMA,EAAM,OAAO,CACtD,GAIEV,EAAe,MAAQ,EAAE,iBAAkBiB,EAAG,SAAS,SAEzDA,EAAG,OAAO,MAAM,OACd,WACA,eACAlB,EAAeC,CAAc,CAC/B,EAEAiB,EAAG,SAAS,MAAM,aAAe,CAC/BI,EACAC,IACW,CACX,MAAMZ,EAAQW,EAAOC,CAAK,EAG1B,OAAOtB,EAAe,IAAIU,EAAM,IAAI,EAAG,MAAMA,EAAM,OAAO,CAC5D,EAEJ","x_google_ignoreList":[0]}

@@ -1,2 +0,2 @@

import{isSpace as b}from"markdown-it/lib/common/utils.mjs";const m=(t,e)=>{if(t.charCodeAt(e)!==123||t.charCodeAt(e+1)!==37)return!1;let c=e-1,o=0;for(;c>=0&&t.charCodeAt(c)===92;)o++,c--;return o%2!==1},h=(t,e)=>t.charCodeAt(e)===37&&t.charCodeAt(e+1)===125,_=t=>(e,c)=>{const o=e.pos,l=e.src.length;if(l-o<5||!m(e.src,o))return!1;let r=o+2;for(;r<l&&b(e.src.charCodeAt(r));)r++;let s=r,a=!1;for(;s+1<l;s++){if(m(e.src,s))return!1;if(h(e.src,s)){a=!0;break}}if(!a)return!1;let n=r+1;for(;n<s&&!b(e.src.charCodeAt(n));)n++;const f=e.src.slice(r,n);if(!t.has(f))return!1;if(!c){const i=e.push("embed_inline","embed",0),p=n?e.src.slice(n+1,s).trim().replace(/\\{%/g,"{%").replace(/%\\}/g,"%}"):"";i.markup="{% %}",i.info=f,i.content=p}return e.pos=s+2,!0},g=t=>(e,c,o,l)=>{const r=e.bMarks[c]+e.tShift[c];let s=e.eMarks[c];const{src:a}=e;if(s-r<5||e.src.charCodeAt(r)!==123||e.src.charCodeAt(r+1)!==37)return!1;s=e.skipSpacesBack(s,r);const n=s-2;if(!h(a,n))return!1;let f=r+2;for(;f<n&&b(e.src.charCodeAt(f));)f++;let i=0;for(let u=f;u+1<n;u++){if(m(e.src,u)||h(e.src,u))return!1;i||b(e.src.charCodeAt(u))&&(i=u)}const p=i?e.src.slice(f,i):e.src.slice(f,n+1).trimEnd();if(!t.has(p))return!1;if(l)return!0;const k=i?e.src.slice(i+1,n).trim().replace(/\\{%/g,"{%").replace(/%\\}/g,"%}"):"",d=e.push("embed_block","embed",0);return d.block=!0,d.info=p,d.content=k,d.map=[c,c+1],d.markup="{% %}",e.line=c+1,!0},A=(t,{config:e=[]}={})=>{const c=t,o=c.__embedMap??=new Map,l=c.__inlineEmbedMap??=new Map;e.forEach(r=>{o.set(r.name,r),r.allowInline&&l.set(r.name,r)}),"embed_block"in t.renderer.rules||(t.block.ruler.before("paragraph","embed_block",g(o),{alt:["paragraph","reference","blockquote","list"]}),t.renderer.rules.embed_block=(r,s)=>{const a=r[s];return o.get(a.info).setup(a.content)}),l.size&&!("embed_inline"in t.renderer.rules)&&(t.inline.ruler.before("emphasis","embed_inline",_(l)),t.renderer.rules.embed_inline=(r,s)=>{const a=r[s];return l.get(a.info).setup(a.content)})};export{A as embed};
import{isSpace as b}from"markdown-it/lib/common/utils.mjs";const m=(t,r)=>{if(t.charCodeAt(r)!==123||t.charCodeAt(r+1)!==37)return!1;let c=r-1,o=0;for(;c>=0&&t.charCodeAt(c)===92;)o++,c--;return o%2!==1},h=(t,r)=>t.charCodeAt(r)===37&&t.charCodeAt(r+1)===125,g=t=>(r,c)=>{const o=r.pos,a=r.src.length;if(a-o<5||!m(r.src,o))return!1;let e=o+2;for(;e<a&&b(r.src.charCodeAt(e));)e++;let s=e,l=!1;for(;s+1<a;s++){if(m(r.src,s))return!1;if(h(r.src,s)){l=!0;break}}if(!l)return!1;let n=e+1;for(;n<s&&!b(r.src.charCodeAt(n));)n++;const f=r.src.slice(e,n);if(!t.has(f))return!1;if(!c){const i=r.push("embed_inline","embed",0),p=n?r.src.slice(n+1,s).trim().replace(/\\{%/g,"{%").replace(/%\\}/g,"%}"):"";i.markup="{% %}",i.info=f,i.content=p}return r.pos=s+2,!0},A=t=>(r,c,o,a)=>{const e=r.bMarks[c]+r.tShift[c];let s=r.eMarks[c];const{src:l}=r;if(s-e<5||r.src.charCodeAt(e)!==123||r.src.charCodeAt(e+1)!==37)return!1;s=r.skipSpacesBack(s,e);const n=s-2;if(!h(l,n))return!1;let f=e+2;for(;f<n&&b(r.src.charCodeAt(f));)f++;let i=-1;for(let u=f;u+1<n;u++){if(m(r.src,u)||h(r.src,u))return!1;i===-1&&b(r.src.charCodeAt(u))&&(i=u)}const p=i===-1?r.src.slice(f,n+1).trimEnd():r.src.slice(f,i);if(!t.has(p))return!1;if(a)return!0;const k=i===-1?"":r.src.slice(i+1,n).trim().replace(/\\{%/g,"{%").replace(/%\\}/g,"%}"),d=r.push("embed_block","embed",0);return d.block=!0,d.info=p,d.content=k,d.map=[c,c+1],d.markup="{% %}",r.line=c+1,!0},_=(t,r)=>{if(typeof r!="object"||!Array.isArray(r.config))throw new Error("[@mdit/plugin-embed]: config is required and must be an array.");const c=t,o=c.__embedMap??=new Map,a=c.__inlineEmbedMap??=new Map;r.config.forEach(e=>{o.set(e.name,e),e.allowInline&&a.set(e.name,e)}),"embed_block"in t.renderer.rules||(t.block.ruler.before("paragraph","embed_block",A(o),{alt:["paragraph","reference","blockquote","list"]}),t.renderer.rules.embed_block=(e,s)=>{const l=e[s];return o.get(l.info).setup(l.content)}),a.size&&!("embed_inline"in t.renderer.rules)&&(t.inline.ruler.before("emphasis","embed_inline",g(a)),t.renderer.rules.embed_inline=(e,s)=>{const l=e[s];return a.get(l.info).setup(l.content)})};export{_ as embed};
//# sourceMappingURL=index.js.map

@@ -1,1 +0,1 @@

{"version":3,"file":"index.js","sources":["../src/plugin.ts"],"sourcesContent":["import type MarkdownIt from \"markdown-it\";\nimport type { PluginWithOptions } from \"markdown-it\";\nimport { isSpace } from \"markdown-it/lib/common/utils.mjs\";\nimport type { RuleBlock } from \"markdown-it/lib/parser_block.mjs\";\nimport type { RuleInline } from \"markdown-it/lib/parser_inline.mjs\";\nimport type Token from \"markdown-it/lib/token.mjs\";\n\nimport type { EmbedConfig, MarkdownItEmbedOptions } from \"./options.js\";\n\nconst checkInlineOpeningMarker = (src: string, current: number): boolean => {\n if (\n src.charCodeAt(current) !== 123 /* { */ ||\n src.charCodeAt(current + 1) !== 37 /* % */\n )\n return false;\n\n // Check if the opening marker was escaped\n let pos = current - 1;\n let backslashCount = 0;\n\n while (pos >= 0 && src.charCodeAt(pos) === 92 /* \\ */) {\n backslashCount++;\n pos--;\n }\n\n // If opening {% is escaped (odd number of preceding backslashes), don't parse\n if (backslashCount % 2 === 1) return false;\n\n return true;\n};\n\nconst checkClosingMarker = (src: string, current: number): boolean =>\n src.charCodeAt(current) === 37 /* % */ &&\n src.charCodeAt(current + 1) === 125; /* } */\n\n/*\n * Parse inline embed with bracket syntax: {%...%}\n */\nconst getEmbedInline =\n (inlineEmbedMap: Map<string, EmbedConfig>): RuleInline =>\n (state, silent) => {\n const start = state.pos;\n const max = state.src.length;\n\n // minimum length check for inline embed - at least 5 characters: {%x%}\n if (max - start < 5) return false;\n\n // check opening marker\n if (!checkInlineOpeningMarker(state.src, start)) return false;\n\n let contentStart = start + 2; // Move past the opening {% marker\n\n // skip spaces\n while (contentStart < max) {\n if (!isSpace(state.src.charCodeAt(contentStart))) break;\n contentStart++;\n }\n\n let contentEnd = contentStart;\n let found = false;\n\n for (; contentEnd + 1 < max; contentEnd++) {\n // must not include opening marker\n if (checkInlineOpeningMarker(state.src, contentEnd)) return false;\n if (checkClosingMarker(state.src, contentEnd)) {\n found = true;\n break;\n }\n }\n\n // No closing marker found\n if (!found) return false;\n\n // get first space\n let spacer = contentStart + 1;\n\n while (spacer < contentEnd) {\n if (isSpace(state.src.charCodeAt(spacer))) break;\n spacer++;\n }\n\n // Extract embed name\n const name = state.src.slice(contentStart, spacer);\n\n // Check if embed name exists in the map\n if (!inlineEmbedMap.has(name)) return false;\n\n if (!silent) {\n const token = state.push(\"embed_inline\", \"embed\", 0);\n const params = spacer\n ? state.src\n .slice(spacer + 1, contentEnd)\n .trim()\n .replace(/\\\\{%/g, \"{%\")\n .replace(/%\\\\}/g, \"%}\")\n : \"\";\n\n token.markup = \"{% %}\";\n token.info = name;\n token.content = params;\n }\n\n // Move past the closing %} marker\n state.pos = contentEnd + 2;\n\n return true;\n };\n\n/*\n * Parse block embed with syntax: {% ... %}\n */\nconst getEmbedBlock =\n (embedMap: Map<string, EmbedConfig>): RuleBlock =>\n (state, startLine, _, silent) => {\n const start = state.bMarks[startLine] + state.tShift[startLine];\n let max = state.eMarks[startLine];\n const { src } = state;\n\n // minimum length check for block embed - at least 5 characters: {%x%}\n if (max - start < 5) return false;\n\n // check opening marker\n if (\n state.src.charCodeAt(start) !== 123 /* { */ ||\n state.src.charCodeAt(start + 1) !== 37 /* % */\n )\n return false;\n\n max = state.skipSpacesBack(max, start);\n\n const contentEnd = max - 2;\n\n if (!checkClosingMarker(src, contentEnd)) return false;\n\n let contentStart = start + 2;\n\n // skip spaces\n while (contentStart < contentEnd) {\n if (!isSpace(state.src.charCodeAt(contentStart))) break;\n contentStart++;\n }\n\n let spacer = 0;\n\n for (let pos = contentStart; pos + 1 < contentEnd; pos++) {\n // must not include unescaped opening marker or closing marker\n if (checkInlineOpeningMarker(state.src, pos)) return false;\n if (checkClosingMarker(state.src, pos)) return false;\n if (spacer) continue;\n if (isSpace(state.src.charCodeAt(pos))) spacer = pos;\n }\n\n // Extract content between {% and %}\n const name = spacer\n ? state.src.slice(contentStart, spacer)\n : state.src.slice(contentStart, contentEnd + 1).trimEnd();\n\n // Check if embed name exists in the map\n if (!embedMap.has(name)) return false;\n\n if (silent) return true;\n\n const params = spacer\n ? state.src\n .slice(spacer + 1, contentEnd)\n .trim()\n .replace(/\\\\{%/g, \"{%\")\n .replace(/%\\\\}/g, \"%}\")\n : \"\";\n\n const token = state.push(\"embed_block\", \"embed\", 0);\n\n token.block = true;\n token.info = name;\n token.content = params;\n token.map = [startLine, startLine + 1];\n token.markup = \"{% %}\";\n\n // Advance to the next line\n state.line = startLine + 1;\n\n return true;\n };\n\nexport const embed: PluginWithOptions<MarkdownItEmbedOptions> = (\n md: MarkdownIt,\n { config = [] }: MarkdownItEmbedOptions = {},\n) => {\n // Get existing maps or create new ones to support multiple plugin instances\n const mdWithMaps = md as MarkdownIt & {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n __embedMap?: Map<string, EmbedConfig>;\n // eslint-disable-next-line @typescript-eslint/naming-convention\n __inlineEmbedMap?: Map<string, EmbedConfig>;\n };\n\n const embedMap = (mdWithMaps.__embedMap ??= new Map<string, EmbedConfig>());\n const inlineEmbedMap = (mdWithMaps.__inlineEmbedMap ??= new Map<\n string,\n EmbedConfig\n >());\n\n config.forEach((item) => {\n embedMap.set(item.name, item);\n // Inline embeds are only supported when allowInline is true\n if (item.allowInline) inlineEmbedMap.set(item.name, item);\n });\n\n // Only register rules if not already registered\n // check embed_block rules here\n if (!(\"embed_block\" in md.renderer.rules)) {\n // Register the block rule\n md.block.ruler.before(\"paragraph\", \"embed_block\", getEmbedBlock(embedMap), {\n alt: [\"paragraph\", \"reference\", \"blockquote\", \"list\"],\n });\n\n // Register the renderers\n md.renderer.rules.embed_block = (\n tokens: Token[],\n index: number,\n ): string => {\n const token = tokens[index];\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return embedMap.get(token.info)!.setup(token.content);\n };\n }\n\n // only register embed_inline rules if inline embeds are allowed\n if (inlineEmbedMap.size && !(\"embed_inline\" in md.renderer.rules)) {\n // Register the inline rule\n md.inline.ruler.before(\n \"emphasis\",\n \"embed_inline\",\n getEmbedInline(inlineEmbedMap),\n );\n\n md.renderer.rules.embed_inline = (\n tokens: Token[],\n index: number,\n ): string => {\n const token = tokens[index];\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return inlineEmbedMap.get(token.info)!.setup(token.content);\n };\n }\n};\n"],"names":["checkInlineOpeningMarker","src","current","pos","backslashCount","checkClosingMarker","getEmbedInline","inlineEmbedMap","state","silent","start","max","contentStart","isSpace","contentEnd","found","spacer","name","token","params","getEmbedBlock","embedMap","startLine","_","embed","md","config","mdWithMaps","item","tokens","index"],"mappings":"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"}
{"version":3,"file":"index.js","sources":["../src/plugin.ts"],"sourcesContent":["import type MarkdownIt from \"markdown-it\";\nimport type { PluginWithOptions } from \"markdown-it\";\nimport { isSpace } from \"markdown-it/lib/common/utils.mjs\";\nimport type { RuleBlock } from \"markdown-it/lib/parser_block.mjs\";\nimport type { RuleInline } from \"markdown-it/lib/parser_inline.mjs\";\nimport type Token from \"markdown-it/lib/token.mjs\";\n\nimport type { EmbedConfig, MarkdownItEmbedOptions } from \"./options.js\";\n\nconst checkInlineOpeningMarker = (src: string, current: number): boolean => {\n if (\n src.charCodeAt(current) !== 123 /* { */ ||\n src.charCodeAt(current + 1) !== 37 /* % */\n )\n return false;\n\n // Check if the opening marker was escaped\n let pos = current - 1;\n let backslashCount = 0;\n\n while (pos >= 0 && src.charCodeAt(pos) === 92 /* \\ */) {\n backslashCount++;\n pos--;\n }\n\n // If opening {% is escaped (odd number of preceding backslashes), don't parse\n if (backslashCount % 2 === 1) return false;\n\n return true;\n};\n\nconst checkClosingMarker = (src: string, current: number): boolean =>\n src.charCodeAt(current) === 37 /* % */ &&\n src.charCodeAt(current + 1) === 125; /* } */\n\n/*\n * Parse inline embed with bracket syntax: {%...%}\n */\nconst getEmbedInline =\n (inlineEmbedMap: Map<string, EmbedConfig>): RuleInline =>\n (state, silent) => {\n const start = state.pos;\n const max = state.src.length;\n\n // minimum length check for inline embed - at least 5 characters: {%x%}\n if (max - start < 5) return false;\n\n // check opening marker\n if (!checkInlineOpeningMarker(state.src, start)) return false;\n\n let contentStart = start + 2; // Move past the opening {% marker\n\n // skip spaces\n while (contentStart < max) {\n if (!isSpace(state.src.charCodeAt(contentStart))) break;\n contentStart++;\n }\n\n let contentEnd = contentStart;\n let found = false;\n\n for (; contentEnd + 1 < max; contentEnd++) {\n // must not include opening marker\n if (checkInlineOpeningMarker(state.src, contentEnd)) return false;\n if (checkClosingMarker(state.src, contentEnd)) {\n found = true;\n break;\n }\n }\n\n // No closing marker found\n if (!found) return false;\n\n // get first space\n let spacer = contentStart + 1;\n\n while (spacer < contentEnd) {\n if (isSpace(state.src.charCodeAt(spacer))) break;\n spacer++;\n }\n\n // Extract embed name\n const name = state.src.slice(contentStart, spacer);\n\n // Check if embed name exists in the map\n if (!inlineEmbedMap.has(name)) return false;\n\n if (!silent) {\n const token = state.push(\"embed_inline\", \"embed\", 0);\n const params = spacer\n ? state.src\n .slice(spacer + 1, contentEnd)\n .trim()\n .replace(/\\\\{%/g, \"{%\")\n .replace(/%\\\\}/g, \"%}\")\n : \"\";\n\n token.markup = \"{% %}\";\n token.info = name;\n token.content = params;\n }\n\n // Move past the closing %} marker\n state.pos = contentEnd + 2;\n\n return true;\n };\n\n/*\n * Parse block embed with syntax: {% ... %}\n */\nconst getEmbedBlock =\n (embedMap: Map<string, EmbedConfig>): RuleBlock =>\n (state, startLine, _, silent) => {\n const start = state.bMarks[startLine] + state.tShift[startLine];\n let max = state.eMarks[startLine];\n const { src } = state;\n\n // minimum length check for block embed - at least 5 characters: {%x%}\n if (max - start < 5) return false;\n\n // check opening marker\n if (\n state.src.charCodeAt(start) !== 123 /* { */ ||\n state.src.charCodeAt(start + 1) !== 37 /* % */\n )\n return false;\n\n max = state.skipSpacesBack(max, start);\n\n const contentEnd = max - 2;\n\n if (!checkClosingMarker(src, contentEnd)) return false;\n\n let contentStart = start + 2;\n\n // skip spaces\n while (contentStart < contentEnd) {\n if (!isSpace(state.src.charCodeAt(contentStart))) break;\n contentStart++;\n }\n\n let spacer = -1;\n\n for (let pos = contentStart; pos + 1 < contentEnd; pos++) {\n // must not include unescaped opening marker or closing marker\n if (checkInlineOpeningMarker(state.src, pos)) return false;\n if (checkClosingMarker(state.src, pos)) return false;\n if (spacer !== -1) continue;\n if (isSpace(state.src.charCodeAt(pos))) spacer = pos;\n }\n\n // Extract content between {% and %}\n const name =\n spacer === -1\n ? state.src.slice(contentStart, contentEnd + 1).trimEnd()\n : state.src.slice(contentStart, spacer);\n\n // Check if embed name exists in the map\n if (!embedMap.has(name)) return false;\n\n if (silent) return true;\n\n const params =\n spacer === -1\n ? \"\"\n : state.src\n .slice(spacer + 1, contentEnd)\n .trim()\n .replace(/\\\\{%/g, \"{%\")\n .replace(/%\\\\}/g, \"%}\");\n\n const token = state.push(\"embed_block\", \"embed\", 0);\n\n token.block = true;\n token.info = name;\n token.content = params;\n token.map = [startLine, startLine + 1];\n token.markup = \"{% %}\";\n\n // Advance to the next line\n state.line = startLine + 1;\n\n return true;\n };\n\nexport const embed: PluginWithOptions<MarkdownItEmbedOptions> = (\n md,\n options,\n) => {\n if (typeof options !== \"object\" || !Array.isArray(options.config))\n throw new Error(\n \"[@mdit/plugin-embed]: config is required and must be an array.\",\n );\n\n // Get existing maps or create new ones to support multiple plugin instances\n const mdWithMaps = md as MarkdownIt & {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n __embedMap?: Map<string, EmbedConfig>;\n // eslint-disable-next-line @typescript-eslint/naming-convention\n __inlineEmbedMap?: Map<string, EmbedConfig>;\n };\n\n const embedMap = (mdWithMaps.__embedMap ??= new Map<string, EmbedConfig>());\n const inlineEmbedMap = (mdWithMaps.__inlineEmbedMap ??= new Map<\n string,\n EmbedConfig\n >());\n\n options.config.forEach((item) => {\n embedMap.set(item.name, item);\n // Inline embeds are only supported when allowInline is true\n if (item.allowInline) inlineEmbedMap.set(item.name, item);\n });\n\n // Only register rules if not already registered\n // check embed_block rules here\n if (!(\"embed_block\" in md.renderer.rules)) {\n // Register the block rule\n md.block.ruler.before(\"paragraph\", \"embed_block\", getEmbedBlock(embedMap), {\n alt: [\"paragraph\", \"reference\", \"blockquote\", \"list\"],\n });\n\n // Register the renderers\n md.renderer.rules.embed_block = (\n tokens: Token[],\n index: number,\n ): string => {\n const token = tokens[index];\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return embedMap.get(token.info)!.setup(token.content);\n };\n }\n\n // only register embed_inline rules if inline embeds are allowed\n if (inlineEmbedMap.size && !(\"embed_inline\" in md.renderer.rules)) {\n // Register the inline rule\n md.inline.ruler.before(\n \"emphasis\",\n \"embed_inline\",\n getEmbedInline(inlineEmbedMap),\n );\n\n md.renderer.rules.embed_inline = (\n tokens: Token[],\n index: number,\n ): string => {\n const token = tokens[index];\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return inlineEmbedMap.get(token.info)!.setup(token.content);\n };\n }\n};\n"],"names":["checkInlineOpeningMarker","src","current","pos","backslashCount","checkClosingMarker","getEmbedInline","inlineEmbedMap","state","silent","start","max","contentStart","isSpace","contentEnd","found","spacer","name","token","params","getEmbedBlock","embedMap","startLine","_","embed","md","options","mdWithMaps","item","tokens","index"],"mappings":"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"}
{
"name": "@mdit/plugin-embed",
"version": "0.22.0",
"version": "0.22.1",
"description": "embed plugin for MarkdownIt",

@@ -5,0 +5,0 @@ "keywords": [