hintorium-react 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +104 -0
- package/dist/components/Tooltip.d.ts +15 -0
- package/dist/components/Tooltip.d.ts.map +1 -0
- package/dist/components/TooltipProvider.d.ts +36 -0
- package/dist/components/TooltipProvider.d.ts.map +1 -0
- package/dist/components/Tour.d.ts +42 -0
- package/dist/components/Tour.d.ts.map +1 -0
- package/dist/context/TooltipContext.d.ts +16 -0
- package/dist/context/TooltipContext.d.ts.map +1 -0
- package/dist/hooks/useAnalytics.d.ts +8 -0
- package/dist/hooks/useAnalytics.d.ts.map +1 -0
- package/dist/hooks/useHintoriumI18n.d.ts +26 -0
- package/dist/hooks/useHintoriumI18n.d.ts.map +1 -0
- package/dist/hooks/useInlineHint.d.ts +40 -0
- package/dist/hooks/useInlineHint.d.ts.map +1 -0
- package/dist/hooks/useTooltip.d.ts +43 -0
- package/dist/hooks/useTooltip.d.ts.map +1 -0
- package/dist/hooks/useTooltipAnalytics.d.ts +4 -0
- package/dist/hooks/useTooltipAnalytics.d.ts.map +1 -0
- package/dist/hooks/useTooltipManager.d.ts +23 -0
- package/dist/hooks/useTooltipManager.d.ts.map +1 -0
- package/dist/hooks/useTour.d.ts +31 -0
- package/dist/hooks/useTour.d.ts.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2826 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +69 -0
- package/dist/types.d.ts.map +1 -0
- package/package.json +49 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,2826 @@
|
|
|
1
|
+
var ot = Object.defineProperty;
|
|
2
|
+
var at = (r, e, t) => e in r ? ot(r, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : r[e] = t;
|
|
3
|
+
var u = (r, e, t) => at(r, typeof e != "symbol" ? e + "" : e, t);
|
|
4
|
+
import { jsx as ye, Fragment as qe } from "react/jsx-runtime";
|
|
5
|
+
import { createContext as lt, useContext as ct, useRef as R, useEffect as z, useCallback as w, isValidElement as ht, cloneElement as ut, useState as ne } from "react";
|
|
6
|
+
const Me = [
|
|
7
|
+
"top",
|
|
8
|
+
"bottom",
|
|
9
|
+
"left",
|
|
10
|
+
"right"
|
|
11
|
+
], g = {
|
|
12
|
+
ATTRIBUTES: {
|
|
13
|
+
TOOLTIP: "data-hintorium-tooltip",
|
|
14
|
+
HINT_TOOLTIP: "data-hintorium-hint",
|
|
15
|
+
TOOLTIP_POSITION: "data-hintorium-tooltip-position",
|
|
16
|
+
TOOLTIP_THEME: "data-hintorium-tooltip-theme",
|
|
17
|
+
TOOLTIP_ANIMATION: "data-hintorium-tooltip-animation",
|
|
18
|
+
TOOLTIP_DELAY: "data-hintorium-tooltip-delay"
|
|
19
|
+
},
|
|
20
|
+
STORAGE_KEYS: {
|
|
21
|
+
TOOLTIP_ANALYTICS: "tooltip-hintorium_analytics"
|
|
22
|
+
},
|
|
23
|
+
CSS_CLASSES: {
|
|
24
|
+
BASE: "hintorium-tooltip",
|
|
25
|
+
HINT: "hintorium-inline-hint",
|
|
26
|
+
RTL: "hintorium-tooltip-rtl",
|
|
27
|
+
WRAPPER: "hintorium-tooltip-inner",
|
|
28
|
+
HINTORIUM_TOUR: "hintorium-tooltip-tour",
|
|
29
|
+
SHOW: "show",
|
|
30
|
+
HIDDEN: "hidden",
|
|
31
|
+
MOBILE: "mobile"
|
|
32
|
+
},
|
|
33
|
+
ARIA: {
|
|
34
|
+
ROLE_TOOLTIP: "tooltip"
|
|
35
|
+
},
|
|
36
|
+
KEYS: {
|
|
37
|
+
ESCAPE: "Escape",
|
|
38
|
+
ENTER: "Enter",
|
|
39
|
+
SPACE: " ",
|
|
40
|
+
TAB: "Tab"
|
|
41
|
+
},
|
|
42
|
+
EVENTS: {
|
|
43
|
+
MOUSE_DOWN: "mousedown",
|
|
44
|
+
KEYDOWN: "keydown"
|
|
45
|
+
},
|
|
46
|
+
DEFAULT: {
|
|
47
|
+
POSITION: "top",
|
|
48
|
+
THEME: "dark",
|
|
49
|
+
ANIMATION: "fade",
|
|
50
|
+
ID_PREFIX: "hintorium-tooltip-",
|
|
51
|
+
ANIMATION_PREFIX: "anim-",
|
|
52
|
+
MOBILE_BREAKPOINT: 768,
|
|
53
|
+
TOUCH_DELAY: 500,
|
|
54
|
+
DEFAULT_OFFSET: 8,
|
|
55
|
+
VIEWPORT_PADDING: 4,
|
|
56
|
+
DELAY: 0
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
class N {
|
|
60
|
+
static init() {
|
|
61
|
+
typeof document > "u" || (this.setupKeyboardDetection(), this.setupFocusListeners());
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Detects whether the user is using the keyboard (e.g., Tab vs. Mouse).
|
|
65
|
+
*/
|
|
66
|
+
static setupKeyboardDetection() {
|
|
67
|
+
document.addEventListener(
|
|
68
|
+
g.EVENTS.KEYDOWN,
|
|
69
|
+
(e) => {
|
|
70
|
+
e.key === g.KEYS.TAB && (this.isKeyboardUser = !0);
|
|
71
|
+
},
|
|
72
|
+
!0
|
|
73
|
+
), document.addEventListener(
|
|
74
|
+
g.EVENTS.MOUSE_DOWN,
|
|
75
|
+
() => {
|
|
76
|
+
this.isKeyboardUser = !1;
|
|
77
|
+
},
|
|
78
|
+
!0
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Returns whether the user is currently using the keyboard.
|
|
83
|
+
*/
|
|
84
|
+
static isKeyboardMode() {
|
|
85
|
+
return this.isKeyboardUser;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Checks whether a given element can be focused.
|
|
89
|
+
* @param element - the element to check
|
|
90
|
+
*/
|
|
91
|
+
static isFocusable(e) {
|
|
92
|
+
return [
|
|
93
|
+
"a[href]",
|
|
94
|
+
"button",
|
|
95
|
+
"input",
|
|
96
|
+
"textarea",
|
|
97
|
+
"select",
|
|
98
|
+
'[tabindex]:not([tabindex="-1"])',
|
|
99
|
+
'[contenteditable="true"]'
|
|
100
|
+
].some((t) => e.matches(t)) || e.hasAttribute("tabindex") && e.getAttribute("tabindex") !== "-1";
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Configures the ARIA relationship between the tooltip and the target element.
|
|
104
|
+
* @param tooltip - the tooltip element
|
|
105
|
+
* @param target - the element to which the tooltip is assigned
|
|
106
|
+
* @param options - tooltip options (from section a11y)
|
|
107
|
+
*/
|
|
108
|
+
static setupTooltipAccessibility(e, t, i) {
|
|
109
|
+
var n;
|
|
110
|
+
e.setAttribute("role", g.ARIA.ROLE_TOOLTIP);
|
|
111
|
+
const s = (t.getAttribute("aria-describedby") || "").split(/\s+/).filter(Boolean);
|
|
112
|
+
s.includes(e.id) || (s.push(e.id), t.setAttribute("aria-describedby", s.join(" "))), ((n = i.a11y) == null ? void 0 : n.keyboard) !== !1 && this.addKeyboardSupport(t), this.ensureFocusable(t, i);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Sets a global focus event listener for the document,
|
|
116
|
+
* to add and remove the visual focus class (`.keyboard-focus`)
|
|
117
|
+
* only when the user is using the keyboard (e.g., pressing Tab).
|
|
118
|
+
*/
|
|
119
|
+
static setupFocusListeners() {
|
|
120
|
+
typeof document > "u" || (document.addEventListener("focusin", (e) => {
|
|
121
|
+
const t = e.target;
|
|
122
|
+
t && this.isKeyboardUser && t.classList.add(this.FOCUS_VISIBLE_CLASS);
|
|
123
|
+
}), document.addEventListener("focusout", (e) => {
|
|
124
|
+
const t = e.target;
|
|
125
|
+
t && t.classList.remove(this.FOCUS_VISIBLE_CLASS);
|
|
126
|
+
}));
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Adds keyboard support to the tooltip's target element.
|
|
130
|
+
* Responds to the following keys: ESC (close), Enter / Space (toggle).
|
|
131
|
+
* @param target - the element to which the tooltip is assigned
|
|
132
|
+
*/
|
|
133
|
+
static addKeyboardSupport(e) {
|
|
134
|
+
if (e.getAttribute("data-has-keyboard-support") === "true") return;
|
|
135
|
+
const t = (i) => {
|
|
136
|
+
switch (i.key) {
|
|
137
|
+
case g.KEYS.ESCAPE:
|
|
138
|
+
e.dispatchEvent(
|
|
139
|
+
new CustomEvent("tooltip:hide", { bubbles: !0 })
|
|
140
|
+
), i.preventDefault();
|
|
141
|
+
break;
|
|
142
|
+
case g.KEYS.ENTER:
|
|
143
|
+
case g.KEYS.SPACE:
|
|
144
|
+
e.dispatchEvent(
|
|
145
|
+
new CustomEvent("tooltip:toggle", { bubbles: !0 })
|
|
146
|
+
), i.preventDefault();
|
|
147
|
+
break;
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
e.addEventListener("keydown", t), e.setAttribute("data-has-keyboard-support", "true");
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Removes ARIA relationships after the tooltip is destroyed.
|
|
154
|
+
* @param tooltip - tooltip element
|
|
155
|
+
* @param target - target element
|
|
156
|
+
*/
|
|
157
|
+
static removeTooltipAccessibility(e, t) {
|
|
158
|
+
const i = t.getAttribute("aria-describedby");
|
|
159
|
+
if (i) {
|
|
160
|
+
const s = i.split(" ").filter((n) => n !== e.id);
|
|
161
|
+
s.length > 0 ? t.setAttribute("aria-describedby", s.join(" ")) : t.removeAttribute("aria-describedby");
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Sends a message to the screen reader (aria-live).
|
|
166
|
+
* @param message - the message content to be announced
|
|
167
|
+
*/
|
|
168
|
+
static announceToScreenReader(e) {
|
|
169
|
+
const t = document.createElement("div");
|
|
170
|
+
t.setAttribute("aria-live", "polite"), t.setAttribute("aria-atomic", "true"), t.className = "sr-only", t.textContent = e, document.body.appendChild(t), setTimeout(() => t.remove(), 1e3);
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Ensures that the tooltip target is focusable.
|
|
174
|
+
* @param target - tooltip target
|
|
175
|
+
* @param options - tooltip options
|
|
176
|
+
*/
|
|
177
|
+
static ensureFocusable(e, t) {
|
|
178
|
+
var i;
|
|
179
|
+
!this.isFocusable(e) && ((i = t.a11y) == null ? void 0 : i.focusable) !== !1 && e.setAttribute("tabindex", "0");
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
/** CSS class added when keyboard focus is applied. */
|
|
183
|
+
u(N, "FOCUS_VISIBLE_CLASS", "keyboard-focus"), /** Flag indicating whether the user is currently using the keyboard. */
|
|
184
|
+
u(N, "isKeyboardUser", !1);
|
|
185
|
+
class B {
|
|
186
|
+
constructor(e, t, i) {
|
|
187
|
+
u(this, "manager");
|
|
188
|
+
u(this, "icon");
|
|
189
|
+
this.manager = ee.getInstance(), this.icon = this.createHintIcon(), e.appendChild(this.icon);
|
|
190
|
+
const s = i ?? B.extractOptionsFromElement(e, this.manager);
|
|
191
|
+
this.manager.add(this.icon, t, s);
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Initializes all inline hints in the DOM with [data-hintorium-hint].
|
|
195
|
+
*/
|
|
196
|
+
static initFromDOM() {
|
|
197
|
+
const e = ee.getInstance();
|
|
198
|
+
document.querySelectorAll(
|
|
199
|
+
`[${g.ATTRIBUTES.HINT_TOOLTIP}]`
|
|
200
|
+
).forEach((t) => {
|
|
201
|
+
if (t.querySelector(`.${g.CSS_CLASSES.HINT}`))
|
|
202
|
+
return;
|
|
203
|
+
const i = t.getAttribute(
|
|
204
|
+
g.ATTRIBUTES.HINT_TOOLTIP
|
|
205
|
+
);
|
|
206
|
+
if (!i) return;
|
|
207
|
+
const s = B.extractOptionsFromElement(
|
|
208
|
+
t,
|
|
209
|
+
e
|
|
210
|
+
);
|
|
211
|
+
new B(t, i, s);
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Remove hint from DOM and TooltipManager
|
|
216
|
+
*/
|
|
217
|
+
destroy() {
|
|
218
|
+
this.manager.remove(this.icon), this.icon.remove();
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Reuseable hintorium options on hint tooltip.
|
|
222
|
+
*/
|
|
223
|
+
static extractOptionsFromElement(e, t) {
|
|
224
|
+
return typeof t.extractOptions == "function" ? t.extractOptions(e) : {};
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Create Hint Icon with custom css class and a11y.
|
|
228
|
+
*/
|
|
229
|
+
createHintIcon() {
|
|
230
|
+
const e = document.createElement("span");
|
|
231
|
+
return e.classList.add(g.CSS_CLASSES.HINT), e.setAttribute("tabindex", "0"), e.setAttribute("aria-label", "Show hint"), e.innerHTML = `
|
|
232
|
+
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
233
|
+
<circle cx="12" cy="12" r="10"/>
|
|
234
|
+
<path d="M9 9a3 3 0 0 1 6 0c0 2-3 2-3 4"/>
|
|
235
|
+
<line x1="12" y1="17" x2="12" y2="17"/>
|
|
236
|
+
</svg>
|
|
237
|
+
`, e;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
const G = class G {
|
|
241
|
+
/**
|
|
242
|
+
* Checks whether the current environment is a mobile or touch-enabled device.
|
|
243
|
+
* Uses several heuristics: window width, presence of `ontouchstart`, and `maxTouchPoints`.
|
|
244
|
+
*
|
|
245
|
+
* @returns {boolean} `true` if the device supports touch or has a small viewport.
|
|
246
|
+
*/
|
|
247
|
+
static isMobile() {
|
|
248
|
+
return typeof window > "u" ? !1 : window.innerWidth <= g.DEFAULT.MOBILE_BREAKPOINT || "ontouchstart" in window || navigator.maxTouchPoints > 0;
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Resolves mobile configuration for tooltip behavior.
|
|
252
|
+
* Decides whether mobile support should be enabled based on user options and environment.
|
|
253
|
+
*
|
|
254
|
+
* @param globalOptions - The global tooltip options provided by the user.
|
|
255
|
+
* @returns A normalized mobile options object.
|
|
256
|
+
*/
|
|
257
|
+
static resolveMobileOptions(e) {
|
|
258
|
+
return {
|
|
259
|
+
enabled: (e == null ? void 0 : e.enabled) !== void 0 ? e.enabled : G.isMobile(),
|
|
260
|
+
longPress: (e == null ? void 0 : e.longPress) ?? !0,
|
|
261
|
+
touchDelay: (e == null ? void 0 : e.touchDelay) ?? g.DEFAULT.TOUCH_DELAY
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Initializes touch support for a specific tooltip.
|
|
266
|
+
* Adds classes and listens for gestures (tap, long-press).
|
|
267
|
+
*
|
|
268
|
+
* @param tooltip - Tooltip instance.
|
|
269
|
+
* @param target - Element on which the tooltip is activated.
|
|
270
|
+
* @param options - Tooltip options (including mobile).
|
|
271
|
+
*/
|
|
272
|
+
static setupMobileSupport(e, t, i) {
|
|
273
|
+
!(i.mobile ?? this.resolveMobileOptions()).enabled || !this.isMobile() || t.getAttribute("data-mobile-handlers") !== "true" && (e.element.classList.add(g.CSS_CLASSES.MOBILE), this.addTouchEvents(e, t, i), t.addEventListener("contextmenu", this.handleContextMenu), t.setAttribute("data-mobile-handlers", "true"));
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Adds touch event handling to the target element.
|
|
277
|
+
* Supports both long-presses (after the specified `touchDelay`)
|
|
278
|
+
* and single taps if `longPress` is disabled.
|
|
279
|
+
*
|
|
280
|
+
* @private
|
|
281
|
+
*/
|
|
282
|
+
static addTouchEvents(e, t, i) {
|
|
283
|
+
const { mobile: { longPress: s, touchDelay: n } = {} } = i, a = () => {
|
|
284
|
+
this.touchTimer && (clearTimeout(this.touchTimer), this.touchTimer = null);
|
|
285
|
+
}, o = () => {
|
|
286
|
+
a(), this.activeTouchTooltip && this.activeTouchTooltip !== e && (this.activeTouchTooltip.hide(), this.activeTouchTooltip = null), s ? this.touchTimer = window.setTimeout(() => {
|
|
287
|
+
e.element.classList.contains(
|
|
288
|
+
g.CSS_CLASSES.SHOW
|
|
289
|
+
) ? (e.hide(), this.activeTouchTooltip = null) : (e.show(), this.activeTouchTooltip = e), this.touchTimer = null;
|
|
290
|
+
}, n) : e.element.classList.contains(
|
|
291
|
+
g.CSS_CLASSES.SHOW
|
|
292
|
+
) ? (e.hide(), this.activeTouchTooltip = null) : (e.show(), this.activeTouchTooltip = e);
|
|
293
|
+
}, h = () => a(), l = () => a(), p = window.PointerEvent ? "pointerdown" : "touchstart", m = window.PointerEvent ? "pointerup" : "touchend", c = window.PointerEvent ? "pointercancel" : "touchcancel";
|
|
294
|
+
t.addEventListener(p, o, { passive: !0 }), t.addEventListener(m, h, { passive: !0 }), t.addEventListener(c, l, { passive: !0 }), this.touchHandlers.set(t, {
|
|
295
|
+
start: o,
|
|
296
|
+
end: h,
|
|
297
|
+
cancel: l
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Blocks the display of the context menu (long-press menu).
|
|
302
|
+
* @private
|
|
303
|
+
*/
|
|
304
|
+
static handleContextMenu(e) {
|
|
305
|
+
e.preventDefault();
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Hides the currently active touch tooltip (if any)
|
|
309
|
+
* and clears any active long-press timer.
|
|
310
|
+
*/
|
|
311
|
+
static hideMobileTooltips() {
|
|
312
|
+
this.activeTouchTooltip && (this.activeTouchTooltip.hide(), this.activeTouchTooltip = null), this.touchTimer && clearTimeout(this.touchTimer), this.touchTimer = null;
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Removes all event listeners and clears the touch state
|
|
316
|
+
* assigned to the target element.
|
|
317
|
+
*
|
|
318
|
+
* @param target - The element for which cleanup should be performed.
|
|
319
|
+
*/
|
|
320
|
+
static cleanup(e) {
|
|
321
|
+
e.removeEventListener("contextmenu", this.handleContextMenu);
|
|
322
|
+
const t = this.touchHandlers.get(e);
|
|
323
|
+
if (t) {
|
|
324
|
+
const i = window.PointerEvent ? "pointerdown" : "touchstart", s = window.PointerEvent ? "pointerup" : "touchend", n = window.PointerEvent ? "pointercancel" : "touchcancel";
|
|
325
|
+
e.removeEventListener(i, t.start), e.removeEventListener(s, t.end), e.removeEventListener(n, t.cancel), this.touchHandlers.delete(e);
|
|
326
|
+
}
|
|
327
|
+
e.removeAttribute("data-mobile-handlers"), this.touchTimer && (clearTimeout(this.touchTimer), this.touchTimer = null), this.activeTouchTooltip = null;
|
|
328
|
+
}
|
|
329
|
+
};
|
|
330
|
+
/** Timer that supports long-press / touch-delay */
|
|
331
|
+
u(G, "touchTimer", null), /** Currently active tooltip triggered by touch */
|
|
332
|
+
u(G, "activeTouchTooltip", null), /** Stores assigned event handlers for a given element */
|
|
333
|
+
u(G, "touchHandlers", /* @__PURE__ */ new WeakMap());
|
|
334
|
+
let j = G;
|
|
335
|
+
const he = class he {
|
|
336
|
+
constructor(e) {
|
|
337
|
+
u(this, "cache", {});
|
|
338
|
+
u(this, "keyPrefix");
|
|
339
|
+
this.keyPrefix = e, this.load();
|
|
340
|
+
}
|
|
341
|
+
static getInstance(e) {
|
|
342
|
+
return this.instances.has(e) || this.instances.set(e, new he(e)), this.instances.get(e);
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Save a value under a key
|
|
346
|
+
* @param key - key to store value
|
|
347
|
+
* @param value - any JSON-serializable value
|
|
348
|
+
*/
|
|
349
|
+
set(e, t) {
|
|
350
|
+
this.cache[e] = t, this.save();
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* Get the full data object
|
|
354
|
+
*/
|
|
355
|
+
getAll() {
|
|
356
|
+
return { ...this.cache };
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Remove a key from storage
|
|
360
|
+
*/
|
|
361
|
+
remove(e) {
|
|
362
|
+
delete this.cache[e], this.save();
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* Get all keys stored in this namespace
|
|
366
|
+
*/
|
|
367
|
+
keys() {
|
|
368
|
+
return Object.keys(this.cache);
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* Clear all data in this namespace
|
|
372
|
+
*/
|
|
373
|
+
clear() {
|
|
374
|
+
this.cache = {}, this.save();
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Retrieve a value by key, optionally with a default
|
|
378
|
+
* @param key - key to retrieve
|
|
379
|
+
* @param defaultValue - value if key not found
|
|
380
|
+
*/
|
|
381
|
+
get(e, t) {
|
|
382
|
+
if (e in this.cache) return this.cache[e];
|
|
383
|
+
if (t)
|
|
384
|
+
return t;
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Save data to localStorage
|
|
388
|
+
*/
|
|
389
|
+
save() {
|
|
390
|
+
try {
|
|
391
|
+
localStorage.setItem(this.keyPrefix, JSON.stringify(this.cache));
|
|
392
|
+
} catch (e) {
|
|
393
|
+
console.warn(
|
|
394
|
+
`[StorageManager:${this.keyPrefix}] Failed to save to LocalStorage`,
|
|
395
|
+
e
|
|
396
|
+
);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Load data from localStorage
|
|
401
|
+
*/
|
|
402
|
+
load() {
|
|
403
|
+
try {
|
|
404
|
+
const e = localStorage.getItem(this.keyPrefix);
|
|
405
|
+
e && (this.cache = JSON.parse(e));
|
|
406
|
+
} catch (e) {
|
|
407
|
+
console.warn(
|
|
408
|
+
`[StorageManager:${this.keyPrefix}] Failed to load from LocalStorage`,
|
|
409
|
+
e
|
|
410
|
+
), this.cache = {};
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
};
|
|
414
|
+
/**
|
|
415
|
+
* Get singleton instance for a given namespace
|
|
416
|
+
* @param keyPrefix - unique namespace key
|
|
417
|
+
*/
|
|
418
|
+
u(he, "instances", /* @__PURE__ */ new Map());
|
|
419
|
+
let oe = he;
|
|
420
|
+
const ue = class ue {
|
|
421
|
+
constructor() {
|
|
422
|
+
u(this, "storage");
|
|
423
|
+
this.storage = oe.getInstance(
|
|
424
|
+
g.STORAGE_KEYS.TOOLTIP_ANALYTICS
|
|
425
|
+
);
|
|
426
|
+
}
|
|
427
|
+
static getInstance() {
|
|
428
|
+
return this.instance || (this.instance = new ue()), this.instance;
|
|
429
|
+
}
|
|
430
|
+
/**
|
|
431
|
+
* Increment tooltip show count
|
|
432
|
+
* @param tooltipId - unique identifier for the tooltip
|
|
433
|
+
*/
|
|
434
|
+
increment(e) {
|
|
435
|
+
const t = (this.storage.get(e, 0) ?? 0) + 1;
|
|
436
|
+
this.storage.set(e, t);
|
|
437
|
+
}
|
|
438
|
+
/**
|
|
439
|
+
* Get the number of times a tooltip has been shown
|
|
440
|
+
* @param tooltipId - unique identifier for the tooltip
|
|
441
|
+
*/
|
|
442
|
+
getCount(e) {
|
|
443
|
+
return this.storage.get(e, 0) || 0;
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* Get all tooltip counts as an object
|
|
447
|
+
*/
|
|
448
|
+
getAll() {
|
|
449
|
+
return this.storage.getAll();
|
|
450
|
+
}
|
|
451
|
+
/**
|
|
452
|
+
* Reset all tooltip counts
|
|
453
|
+
*/
|
|
454
|
+
resetAll() {
|
|
455
|
+
this.storage.clear();
|
|
456
|
+
}
|
|
457
|
+
};
|
|
458
|
+
u(ue, "instance", null);
|
|
459
|
+
let me = ue;
|
|
460
|
+
const K = me.getInstance();
|
|
461
|
+
class ze {
|
|
462
|
+
/**
|
|
463
|
+
* Removes all existing animation classes from the tooltip and
|
|
464
|
+
* applies the new animation class based on the given animation type.
|
|
465
|
+
*
|
|
466
|
+
* @private
|
|
467
|
+
* @param {HTMLElement} tooltip - The tooltip element to prepare.
|
|
468
|
+
* @param {TooltipAnimation} animation - The animation type (e.g., `'fade'`, `'scale'`, `'slide'`).
|
|
469
|
+
*
|
|
470
|
+
* @example
|
|
471
|
+
* ```ts
|
|
472
|
+
* AnimationManager.prepareAnimation(tooltip, 'scale');
|
|
473
|
+
* ```
|
|
474
|
+
*/
|
|
475
|
+
static prepareAnimation(e, t) {
|
|
476
|
+
e.classList.forEach((i) => {
|
|
477
|
+
i.startsWith(g.DEFAULT.ANIMATION_PREFIX) && e.classList.remove(i);
|
|
478
|
+
}), e.classList.add(
|
|
479
|
+
`${g.DEFAULT.ANIMATION_PREFIX}${t}`
|
|
480
|
+
);
|
|
481
|
+
}
|
|
482
|
+
/**
|
|
483
|
+
* Displays the tooltip with the specified animation effect.
|
|
484
|
+
* Automatically removes the `hidden` class, adds the `show` class,
|
|
485
|
+
* and waits for the CSS transition to finish before resolving.
|
|
486
|
+
*
|
|
487
|
+
* @async
|
|
488
|
+
* @param {HTMLDivElement} tooltip - The tooltip element to animate.
|
|
489
|
+
* @param {TooltipAnimation} [animation='fade'] - The animation style to apply.
|
|
490
|
+
* @param {number} [delay=0] - The delay (in milliseconds) before starting the animation.
|
|
491
|
+
* @returns {Promise<void>} Resolves once the animation completes.
|
|
492
|
+
*
|
|
493
|
+
* @example
|
|
494
|
+
* ```ts
|
|
495
|
+
* await AnimationManager.show(tooltip, 'fade', 150);
|
|
496
|
+
* ```
|
|
497
|
+
*/
|
|
498
|
+
static async show(e, t = "fade", i = 0) {
|
|
499
|
+
if (!e) return Promise.resolve();
|
|
500
|
+
this.prepareAnimation(e, t), await this.wait(i), e.classList.remove(g.CSS_CLASSES.HIDDEN), e.classList.add(g.CSS_CLASSES.SHOW), await this.waitForTransition(e);
|
|
501
|
+
}
|
|
502
|
+
/**
|
|
503
|
+
* Hides the tooltip with the currently active animation effect.
|
|
504
|
+
* Removes the `show` class, waits for the transition to complete,
|
|
505
|
+
* and finally adds the `hidden` class.
|
|
506
|
+
*
|
|
507
|
+
* @async
|
|
508
|
+
* @param {HTMLDivElement} tooltip - The tooltip element to hide.
|
|
509
|
+
* @param {number} [delay=0] - Optional delay (in milliseconds) before hiding.
|
|
510
|
+
* @returns {Promise<void>} Resolves once the hide transition finishes.
|
|
511
|
+
*
|
|
512
|
+
* @example
|
|
513
|
+
* ```ts
|
|
514
|
+
* await AnimationManager.hide(tooltip, 200);
|
|
515
|
+
* ```
|
|
516
|
+
*/
|
|
517
|
+
static async hide(e, t = 0) {
|
|
518
|
+
e && (await this.wait(t), e.classList.remove(g.CSS_CLASSES.SHOW), await this.waitForTransition(e), e.classList.add(g.CSS_CLASSES.HIDDEN));
|
|
519
|
+
}
|
|
520
|
+
/**
|
|
521
|
+
* Waits for the CSS transition on the given element to complete.
|
|
522
|
+
* If no `transitionend` event is fired, it resolves automatically after
|
|
523
|
+
* the computed transition duration (as a safety fallback).
|
|
524
|
+
*
|
|
525
|
+
* @private
|
|
526
|
+
* @param {HTMLElement} element - The element undergoing a CSS transition.
|
|
527
|
+
* @returns {Promise<void>} Resolves after the transition completes or timeout elapses.
|
|
528
|
+
*/
|
|
529
|
+
static waitForTransition(e) {
|
|
530
|
+
return new Promise((t) => {
|
|
531
|
+
const i = this.getTransitionDuration(e);
|
|
532
|
+
e.addEventListener("transitionend", () => t(), {
|
|
533
|
+
once: !0
|
|
534
|
+
}), setTimeout(t, i);
|
|
535
|
+
});
|
|
536
|
+
}
|
|
537
|
+
/**
|
|
538
|
+
* Reads the element’s computed transition duration and delay from CSS.
|
|
539
|
+
* Returns the total transition time in milliseconds.
|
|
540
|
+
*
|
|
541
|
+
* @private
|
|
542
|
+
* @param {HTMLElement} element - The element whose transition timing is computed.
|
|
543
|
+
* @returns {number} Total transition time (duration + delay) in milliseconds.
|
|
544
|
+
*/
|
|
545
|
+
static getTransitionDuration(e) {
|
|
546
|
+
const t = getComputedStyle(e), i = parseFloat(t.transitionDuration) || 0, s = parseFloat(t.transitionDelay) || 0;
|
|
547
|
+
return (i + s) * 1e3;
|
|
548
|
+
}
|
|
549
|
+
/**
|
|
550
|
+
* A simple delay helper that pauses execution for the specified time.
|
|
551
|
+
*
|
|
552
|
+
* @private
|
|
553
|
+
* @param {number} ms - Time in milliseconds to wait.
|
|
554
|
+
* @returns {Promise<void>} Resolves after the delay.
|
|
555
|
+
*
|
|
556
|
+
* @example
|
|
557
|
+
* ```ts
|
|
558
|
+
* await AnimationManager.wait(300) ;
|
|
559
|
+
* console.log('Waited 300ms');
|
|
560
|
+
* ```
|
|
561
|
+
*/
|
|
562
|
+
static wait(e) {
|
|
563
|
+
return new Promise((t) => setTimeout(t, e));
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
function Se() {
|
|
567
|
+
return { async: !1, breaks: !1, extensions: null, gfm: !0, hooks: null, pedantic: !1, renderer: null, silent: !1, tokenizer: null, walkTokens: null };
|
|
568
|
+
}
|
|
569
|
+
var q = Se();
|
|
570
|
+
function We(r) {
|
|
571
|
+
q = r;
|
|
572
|
+
}
|
|
573
|
+
var Q = { exec: () => null };
|
|
574
|
+
function k(r, e = "") {
|
|
575
|
+
let t = typeof r == "string" ? r : r.source, i = { replace: (s, n) => {
|
|
576
|
+
let a = typeof n == "string" ? n : n.source;
|
|
577
|
+
return a = a.replace(x.caret, "$1"), t = t.replace(s, a), i;
|
|
578
|
+
}, getRegex: () => new RegExp(t, e) };
|
|
579
|
+
return i;
|
|
580
|
+
}
|
|
581
|
+
var x = { 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: (r) => new RegExp(`^( {0,3}${r})((?:[ ][^\\n]*)?(?:\\n|$))`), nextBulletRegex: (r) => new RegExp(`^ {0,${Math.min(3, r - 1)}}(?:[*+-]|\\d{1,9}[.)])((?:[ ][^\\n]*)?(?:\\n|$))`), hrRegex: (r) => new RegExp(`^ {0,${Math.min(3, r - 1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`), fencesBeginRegex: (r) => new RegExp(`^ {0,${Math.min(3, r - 1)}}(?:\`\`\`|~~~)`), headingBeginRegex: (r) => new RegExp(`^ {0,${Math.min(3, r - 1)}}#`), htmlBeginRegex: (r) => new RegExp(`^ {0,${Math.min(3, r - 1)}}<(?:[a-z].*>|!--)`, "i") }, pt = /^(?:[ \t]*(?:\n|$))+/, dt = /^((?: {4}| {0,3}\t)[^\n]+(?:\n(?:[ \t]*(?:\n|$))*)?)+/, gt = /^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/, te = /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/, mt = /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/, Ae = /(?:[*+-]|\d{1,9}[.)])/, Ke = /^(?!bull |blockCode|fences|blockquote|heading|html|table)((?:.|\n(?!\s*?\n|bull |blockCode|fences|blockquote|heading|html|table))+?)\n {0,3}(=+|-+) *(?:\n+|$)/, Ge = k(Ke).replace(/bull/g, Ae).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(), ft = k(Ke).replace(/bull/g, Ae).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(), Ee = /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/, kt = /^[^\n]+/, Le = /(?!\s*\])(?:\\[\s\S]|[^\[\]\\])+/, bt = k(/^ {0,3}\[(label)\]: *(?:\n[ \t]*)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n[ \t]*)?| *\n[ \t]*)(title))? *(?:\n+|$)/).replace("label", Le).replace("title", /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/).getRegex(), Tt = k(/^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/).replace(/bull/g, Ae).getRegex(), de = "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", ve = /<!--(?:-?>|[\s\S]*?(?:-->|$))/, wt = k("^ {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", ve).replace("tag", de).replace("attribute", / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(), Ve = k(Ee).replace("hr", te).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", de).getRegex(), xt = k(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/).replace("paragraph", Ve).getRegex(), Pe = { blockquote: xt, code: dt, def: bt, fences: gt, heading: mt, hr: te, html: wt, lheading: Ge, list: Tt, newline: pt, paragraph: Ve, table: Q, text: kt }, _e = k("^ *([^\\n ].*)\\n {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)").replace("hr", te).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", de).getRegex(), yt = { ...Pe, lheading: ft, table: _e, paragraph: k(Ee).replace("hr", te).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("|lheading", "").replace("table", _e).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", de).getRegex() }, St = { ...Pe, html: k(`^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)|<tag(?:"[^"]*"|'[^']*'|\\s[^'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))`).replace("comment", ve).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: Q, lheading: /^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/, paragraph: k(Ee).replace("hr", te).replace("heading", ` *#{1,6} *[^
|
|
582
|
+
]`).replace("lheading", Ge).replace("|table", "").replace("blockquote", " {0,3}>").replace("|fences", "").replace("|list", "").replace("|html", "").replace("|tag", "").getRegex() }, At = /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/, Et = /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/, je = /^( {2,}|\\)\n(?!\s*$)/, Lt = /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/, ge = /[\p{P}\p{S}]/u, Ie = /[\s\p{P}\p{S}]/u, Ze = /[^\s\p{P}\p{S}]/u, vt = k(/^((?![*_])punctSpace)/, "u").replace(/punctSpace/g, Ie).getRegex(), Ye = /(?!~)[\p{P}\p{S}]/u, Pt = /(?!~)[\s\p{P}\p{S}]/u, It = /(?:[^\s\p{P}\p{S}]|~)/u, Rt = k(/link|code|html/, "g").replace("link", new RegExp("\\[(?:[^\\[\\]`]|(?<!`)(?<a>`+)[^`]+\\k<a>(?!`))*?\\]\\((?:\\\\[\\s\\S]|[^\\\\\\(\\)]|\\((?:\\\\[\\s\\S]|[^\\\\\\(\\)])*\\))*\\)")).replace("code", new RegExp("(?<!`)(?<b>`+)[^`]+\\k<b>(?!`)")).replace("html", /<(?! )[^<>]*?>/).getRegex(), Xe = /^(?:\*+(?:((?!\*)punct)|[^\s*]))|^_+(?:((?!_)punct)|([^\s_]))/, $t = k(Xe, "u").replace(/punct/g, ge).getRegex(), Ct = k(Xe, "u").replace(/punct/g, Ye).getRegex(), Qe = "^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\*)punct(\\*+)(?=[\\s]|$)|notPunctSpace(\\*+)(?!\\*)(?=punctSpace|$)|(?!\\*)punctSpace(\\*+)(?=notPunctSpace)|[\\s](\\*+)(?!\\*)(?=punct)|(?!\\*)punct(\\*+)(?!\\*)(?=punct)|notPunctSpace(\\*+)(?=notPunctSpace)", Ot = k(Qe, "gu").replace(/notPunctSpace/g, Ze).replace(/punctSpace/g, Ie).replace(/punct/g, ge).getRegex(), Dt = k(Qe, "gu").replace(/notPunctSpace/g, It).replace(/punctSpace/g, Pt).replace(/punct/g, Ye).getRegex(), Mt = k("^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)|[^_]+(?=[^_])|(?!_)punct(_+)(?=[\\s]|$)|notPunctSpace(_+)(?!_)(?=punctSpace|$)|(?!_)punctSpace(_+)(?=notPunctSpace)|[\\s](_+)(?!_)(?=punct)|(?!_)punct(_+)(?!_)(?=punct)", "gu").replace(/notPunctSpace/g, Ze).replace(/punctSpace/g, Ie).replace(/punct/g, ge).getRegex(), zt = k(/\\(punct)/, "gu").replace(/punct/g, ge).getRegex(), _t = k(/^<(scheme:[^\s\x00-\x1f<>]*|email)>/).replace("scheme", /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/).replace("email", /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/).getRegex(), Ft = k(ve).replace("(?:-->|$)", "-->").getRegex(), Nt = k("^comment|^</[a-zA-Z][\\w:-]*\\s*>|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^<![a-zA-Z]+\\s[\\s\\S]*?>|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>").replace("comment", Ft).replace("attribute", /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/).getRegex(), ae = /(?:\[(?:\\[\s\S]|[^\[\]\\])*\]|\\[\s\S]|`+[^`]*?`+(?!`)|[^\[\]\\`])*?/, Bt = k(/^!?\[(label)\]\(\s*(href)(?:(?:[ \t]*(?:\n[ \t]*)?)(title))?\s*\)/).replace("label", ae).replace("href", /<(?:\\.|[^\n<>\\])+>|[^ \t\n\x00-\x1f]*/).replace("title", /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/).getRegex(), Je = k(/^!?\[(label)\]\[(ref)\]/).replace("label", ae).replace("ref", Le).getRegex(), et = k(/^!?\[(ref)\](?:\[\])?/).replace("ref", Le).getRegex(), Ht = k("reflink|nolink(?!\\()", "g").replace("reflink", Je).replace("nolink", et).getRegex(), Fe = /[hH][tT][tT][pP][sS]?|[fF][tT][pP]/, Re = { _backpedal: Q, anyPunctuation: zt, autolink: _t, blockSkip: Rt, br: je, code: Et, del: Q, emStrongLDelim: $t, emStrongRDelimAst: Ot, emStrongRDelimUnd: Mt, escape: At, link: Bt, nolink: et, punctuation: vt, reflink: Je, reflinkSearch: Ht, tag: Nt, text: Lt, url: Q }, Ut = { ...Re, link: k(/^!?\[(label)\]\((.*?)\)/).replace("label", ae).getRegex(), reflink: k(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label", ae).getRegex() }, fe = { ...Re, emStrongRDelimAst: Dt, emStrongLDelim: Ct, url: k(/^((?:protocol):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/).replace("protocol", Fe).replace("email", /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/).getRegex(), _backpedal: /(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/, del: /^(~~?)(?=[^\s~])((?:\\[\s\S]|[^\\])*?(?:\\[\s\S]|[^\s~\\]))\1(?=[^~]|$)/, text: k(/^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|protocol:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/).replace("protocol", Fe).getRegex() }, qt = { ...fe, br: k(je).replace("{2,}", "*").getRegex(), text: k(fe.text).replace("\\b_", "\\b_| {2,}\\n").replace(/\{2,\}/g, "*").getRegex() }, se = { normal: Pe, gfm: yt, pedantic: St }, Z = { normal: Re, gfm: fe, breaks: qt, pedantic: Ut }, Wt = { "&": "&", "<": "<", ">": ">", '"': """, "'": "'" }, Ne = (r) => Wt[r];
|
|
583
|
+
function v(r, e) {
|
|
584
|
+
if (e) {
|
|
585
|
+
if (x.escapeTest.test(r)) return r.replace(x.escapeReplace, Ne);
|
|
586
|
+
} else if (x.escapeTestNoEncode.test(r)) return r.replace(x.escapeReplaceNoEncode, Ne);
|
|
587
|
+
return r;
|
|
588
|
+
}
|
|
589
|
+
function Be(r) {
|
|
590
|
+
try {
|
|
591
|
+
r = encodeURI(r).replace(x.percentDecode, "%");
|
|
592
|
+
} catch {
|
|
593
|
+
return null;
|
|
594
|
+
}
|
|
595
|
+
return r;
|
|
596
|
+
}
|
|
597
|
+
function He(r, e) {
|
|
598
|
+
var n;
|
|
599
|
+
let t = r.replace(x.findPipe, (a, o, h) => {
|
|
600
|
+
let l = !1, p = o;
|
|
601
|
+
for (; --p >= 0 && h[p] === "\\"; ) l = !l;
|
|
602
|
+
return l ? "|" : " |";
|
|
603
|
+
}), i = t.split(x.splitPipe), s = 0;
|
|
604
|
+
if (i[0].trim() || i.shift(), i.length > 0 && !((n = i.at(-1)) != null && n.trim()) && i.pop(), e) if (i.length > e) i.splice(e);
|
|
605
|
+
else for (; i.length < e; ) i.push("");
|
|
606
|
+
for (; s < i.length; s++) i[s] = i[s].trim().replace(x.slashPipe, "|");
|
|
607
|
+
return i;
|
|
608
|
+
}
|
|
609
|
+
function Y(r, e, t) {
|
|
610
|
+
let i = r.length;
|
|
611
|
+
if (i === 0) return "";
|
|
612
|
+
let s = 0;
|
|
613
|
+
for (; s < i && r.charAt(i - s - 1) === e; )
|
|
614
|
+
s++;
|
|
615
|
+
return r.slice(0, i - s);
|
|
616
|
+
}
|
|
617
|
+
function Kt(r, e) {
|
|
618
|
+
if (r.indexOf(e[1]) === -1) return -1;
|
|
619
|
+
let t = 0;
|
|
620
|
+
for (let i = 0; i < r.length; i++) if (r[i] === "\\") i++;
|
|
621
|
+
else if (r[i] === e[0]) t++;
|
|
622
|
+
else if (r[i] === e[1] && (t--, t < 0)) return i;
|
|
623
|
+
return t > 0 ? -2 : -1;
|
|
624
|
+
}
|
|
625
|
+
function Ue(r, e, t, i, s) {
|
|
626
|
+
let n = e.href, a = e.title || null, o = r[1].replace(s.other.outputLinkReplace, "$1");
|
|
627
|
+
i.state.inLink = !0;
|
|
628
|
+
let h = { type: r[0].charAt(0) === "!" ? "image" : "link", raw: t, href: n, title: a, text: o, tokens: i.inlineTokens(o) };
|
|
629
|
+
return i.state.inLink = !1, h;
|
|
630
|
+
}
|
|
631
|
+
function Gt(r, e, t) {
|
|
632
|
+
let i = r.match(t.other.indentCodeCompensation);
|
|
633
|
+
if (i === null) return e;
|
|
634
|
+
let s = i[1];
|
|
635
|
+
return e.split(`
|
|
636
|
+
`).map((n) => {
|
|
637
|
+
let a = n.match(t.other.beginningSpace);
|
|
638
|
+
if (a === null) return n;
|
|
639
|
+
let [o] = a;
|
|
640
|
+
return o.length >= s.length ? n.slice(s.length) : n;
|
|
641
|
+
}).join(`
|
|
642
|
+
`);
|
|
643
|
+
}
|
|
644
|
+
var le = class {
|
|
645
|
+
constructor(r) {
|
|
646
|
+
u(this, "options");
|
|
647
|
+
u(this, "rules");
|
|
648
|
+
u(this, "lexer");
|
|
649
|
+
this.options = r || q;
|
|
650
|
+
}
|
|
651
|
+
space(r) {
|
|
652
|
+
let e = this.rules.block.newline.exec(r);
|
|
653
|
+
if (e && e[0].length > 0) return { type: "space", raw: e[0] };
|
|
654
|
+
}
|
|
655
|
+
code(r) {
|
|
656
|
+
let e = this.rules.block.code.exec(r);
|
|
657
|
+
if (e) {
|
|
658
|
+
let t = e[0].replace(this.rules.other.codeRemoveIndent, "");
|
|
659
|
+
return { type: "code", raw: e[0], codeBlockStyle: "indented", text: this.options.pedantic ? t : Y(t, `
|
|
660
|
+
`) };
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
fences(r) {
|
|
664
|
+
let e = this.rules.block.fences.exec(r);
|
|
665
|
+
if (e) {
|
|
666
|
+
let t = e[0], i = Gt(t, e[3] || "", this.rules);
|
|
667
|
+
return { type: "code", raw: t, lang: e[2] ? e[2].trim().replace(this.rules.inline.anyPunctuation, "$1") : e[2], text: i };
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
heading(r) {
|
|
671
|
+
let e = this.rules.block.heading.exec(r);
|
|
672
|
+
if (e) {
|
|
673
|
+
let t = e[2].trim();
|
|
674
|
+
if (this.rules.other.endingHash.test(t)) {
|
|
675
|
+
let i = Y(t, "#");
|
|
676
|
+
(this.options.pedantic || !i || this.rules.other.endingSpaceChar.test(i)) && (t = i.trim());
|
|
677
|
+
}
|
|
678
|
+
return { type: "heading", raw: e[0], depth: e[1].length, text: t, tokens: this.lexer.inline(t) };
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
hr(r) {
|
|
682
|
+
let e = this.rules.block.hr.exec(r);
|
|
683
|
+
if (e) return { type: "hr", raw: Y(e[0], `
|
|
684
|
+
`) };
|
|
685
|
+
}
|
|
686
|
+
blockquote(r) {
|
|
687
|
+
let e = this.rules.block.blockquote.exec(r);
|
|
688
|
+
if (e) {
|
|
689
|
+
let t = Y(e[0], `
|
|
690
|
+
`).split(`
|
|
691
|
+
`), i = "", s = "", n = [];
|
|
692
|
+
for (; t.length > 0; ) {
|
|
693
|
+
let a = !1, o = [], h;
|
|
694
|
+
for (h = 0; h < t.length; h++) if (this.rules.other.blockquoteStart.test(t[h])) o.push(t[h]), a = !0;
|
|
695
|
+
else if (!a) o.push(t[h]);
|
|
696
|
+
else break;
|
|
697
|
+
t = t.slice(h);
|
|
698
|
+
let l = o.join(`
|
|
699
|
+
`), p = l.replace(this.rules.other.blockquoteSetextReplace, `
|
|
700
|
+
$1`).replace(this.rules.other.blockquoteSetextReplace2, "");
|
|
701
|
+
i = i ? `${i}
|
|
702
|
+
${l}` : l, s = s ? `${s}
|
|
703
|
+
${p}` : p;
|
|
704
|
+
let m = this.lexer.state.top;
|
|
705
|
+
if (this.lexer.state.top = !0, this.lexer.blockTokens(p, n, !0), this.lexer.state.top = m, t.length === 0) break;
|
|
706
|
+
let c = n.at(-1);
|
|
707
|
+
if ((c == null ? void 0 : c.type) === "code") break;
|
|
708
|
+
if ((c == null ? void 0 : c.type) === "blockquote") {
|
|
709
|
+
let f = c, d = f.raw + `
|
|
710
|
+
` + t.join(`
|
|
711
|
+
`), T = this.blockquote(d);
|
|
712
|
+
n[n.length - 1] = T, i = i.substring(0, i.length - f.raw.length) + T.raw, s = s.substring(0, s.length - f.text.length) + T.text;
|
|
713
|
+
break;
|
|
714
|
+
} else if ((c == null ? void 0 : c.type) === "list") {
|
|
715
|
+
let f = c, d = f.raw + `
|
|
716
|
+
` + t.join(`
|
|
717
|
+
`), T = this.list(d);
|
|
718
|
+
n[n.length - 1] = T, i = i.substring(0, i.length - c.raw.length) + T.raw, s = s.substring(0, s.length - f.raw.length) + T.raw, t = d.substring(n.at(-1).raw.length).split(`
|
|
719
|
+
`);
|
|
720
|
+
continue;
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
return { type: "blockquote", raw: i, tokens: n, text: s };
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
list(r) {
|
|
727
|
+
let e = this.rules.block.list.exec(r);
|
|
728
|
+
if (e) {
|
|
729
|
+
let t = e[1].trim(), i = t.length > 1, s = { type: "list", raw: "", ordered: i, start: i ? +t.slice(0, -1) : "", loose: !1, items: [] };
|
|
730
|
+
t = i ? `\\d{1,9}\\${t.slice(-1)}` : `\\${t}`, this.options.pedantic && (t = i ? t : "[*+-]");
|
|
731
|
+
let n = this.rules.other.listItemRegex(t), a = !1;
|
|
732
|
+
for (; r; ) {
|
|
733
|
+
let h = !1, l = "", p = "";
|
|
734
|
+
if (!(e = n.exec(r)) || this.rules.block.hr.test(r)) break;
|
|
735
|
+
l = e[0], r = r.substring(l.length);
|
|
736
|
+
let m = e[2].split(`
|
|
737
|
+
`, 1)[0].replace(this.rules.other.listReplaceTabs, ($) => " ".repeat(3 * $.length)), c = r.split(`
|
|
738
|
+
`, 1)[0], f = !m.trim(), d = 0;
|
|
739
|
+
if (this.options.pedantic ? (d = 2, p = m.trimStart()) : f ? d = e[1].length + 1 : (d = e[2].search(this.rules.other.nonSpaceChar), d = d > 4 ? 1 : d, p = m.slice(d), d += e[1].length), f && this.rules.other.blankLine.test(c) && (l += c + `
|
|
740
|
+
`, r = r.substring(c.length + 1), h = !0), !h) {
|
|
741
|
+
let $ = this.rules.other.nextBulletRegex(d), P = this.rules.other.hrRegex(d), I = this.rules.other.fencesBeginRegex(d), _ = this.rules.other.headingBeginRegex(d), ie = this.rules.other.htmlBeginRegex(d);
|
|
742
|
+
for (; r; ) {
|
|
743
|
+
let C = r.split(`
|
|
744
|
+
`, 1)[0], O;
|
|
745
|
+
if (c = C, this.options.pedantic ? (c = c.replace(this.rules.other.listReplaceNesting, " "), O = c) : O = c.replace(this.rules.other.tabCharGlobal, " "), I.test(c) || _.test(c) || ie.test(c) || $.test(c) || P.test(c)) break;
|
|
746
|
+
if (O.search(this.rules.other.nonSpaceChar) >= d || !c.trim()) p += `
|
|
747
|
+
` + O.slice(d);
|
|
748
|
+
else {
|
|
749
|
+
if (f || m.replace(this.rules.other.tabCharGlobal, " ").search(this.rules.other.nonSpaceChar) >= 4 || I.test(m) || _.test(m) || P.test(m)) break;
|
|
750
|
+
p += `
|
|
751
|
+
` + c;
|
|
752
|
+
}
|
|
753
|
+
!f && !c.trim() && (f = !0), l += C + `
|
|
754
|
+
`, r = r.substring(C.length + 1), m = O.slice(d);
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
s.loose || (a ? s.loose = !0 : this.rules.other.doubleBlankLine.test(l) && (a = !0));
|
|
758
|
+
let T = null, L;
|
|
759
|
+
this.options.gfm && (T = this.rules.other.listIsTask.exec(p), T && (L = T[0] !== "[ ] ", p = p.replace(this.rules.other.listReplaceTask, ""))), s.items.push({ type: "list_item", raw: l, task: !!T, checked: L, loose: !1, text: p, tokens: [] }), s.raw += l;
|
|
760
|
+
}
|
|
761
|
+
let o = s.items.at(-1);
|
|
762
|
+
if (o) o.raw = o.raw.trimEnd(), o.text = o.text.trimEnd();
|
|
763
|
+
else return;
|
|
764
|
+
s.raw = s.raw.trimEnd();
|
|
765
|
+
for (let h = 0; h < s.items.length; h++) if (this.lexer.state.top = !1, s.items[h].tokens = this.lexer.blockTokens(s.items[h].text, []), !s.loose) {
|
|
766
|
+
let l = s.items[h].tokens.filter((m) => m.type === "space"), p = l.length > 0 && l.some((m) => this.rules.other.anyLine.test(m.raw));
|
|
767
|
+
s.loose = p;
|
|
768
|
+
}
|
|
769
|
+
if (s.loose) for (let h = 0; h < s.items.length; h++) s.items[h].loose = !0;
|
|
770
|
+
return s;
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
html(r) {
|
|
774
|
+
let e = this.rules.block.html.exec(r);
|
|
775
|
+
if (e) return { type: "html", block: !0, raw: e[0], pre: e[1] === "pre" || e[1] === "script" || e[1] === "style", text: e[0] };
|
|
776
|
+
}
|
|
777
|
+
def(r) {
|
|
778
|
+
let e = this.rules.block.def.exec(r);
|
|
779
|
+
if (e) {
|
|
780
|
+
let t = e[1].toLowerCase().replace(this.rules.other.multipleSpaceGlobal, " "), i = e[2] ? e[2].replace(this.rules.other.hrefBrackets, "$1").replace(this.rules.inline.anyPunctuation, "$1") : "", s = e[3] ? e[3].substring(1, e[3].length - 1).replace(this.rules.inline.anyPunctuation, "$1") : e[3];
|
|
781
|
+
return { type: "def", tag: t, raw: e[0], href: i, title: s };
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
table(r) {
|
|
785
|
+
var a;
|
|
786
|
+
let e = this.rules.block.table.exec(r);
|
|
787
|
+
if (!e || !this.rules.other.tableDelimiter.test(e[2])) return;
|
|
788
|
+
let t = He(e[1]), i = e[2].replace(this.rules.other.tableAlignChars, "").split("|"), s = (a = e[3]) != null && a.trim() ? e[3].replace(this.rules.other.tableRowBlankLine, "").split(`
|
|
789
|
+
`) : [], n = { type: "table", raw: e[0], header: [], align: [], rows: [] };
|
|
790
|
+
if (t.length === i.length) {
|
|
791
|
+
for (let o of i) this.rules.other.tableAlignRight.test(o) ? n.align.push("right") : this.rules.other.tableAlignCenter.test(o) ? n.align.push("center") : this.rules.other.tableAlignLeft.test(o) ? n.align.push("left") : n.align.push(null);
|
|
792
|
+
for (let o = 0; o < t.length; o++) n.header.push({ text: t[o], tokens: this.lexer.inline(t[o]), header: !0, align: n.align[o] });
|
|
793
|
+
for (let o of s) n.rows.push(He(o, n.header.length).map((h, l) => ({ text: h, tokens: this.lexer.inline(h), header: !1, align: n.align[l] })));
|
|
794
|
+
return n;
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
lheading(r) {
|
|
798
|
+
let e = this.rules.block.lheading.exec(r);
|
|
799
|
+
if (e) return { type: "heading", raw: e[0], depth: e[2].charAt(0) === "=" ? 1 : 2, text: e[1], tokens: this.lexer.inline(e[1]) };
|
|
800
|
+
}
|
|
801
|
+
paragraph(r) {
|
|
802
|
+
let e = this.rules.block.paragraph.exec(r);
|
|
803
|
+
if (e) {
|
|
804
|
+
let t = e[1].charAt(e[1].length - 1) === `
|
|
805
|
+
` ? e[1].slice(0, -1) : e[1];
|
|
806
|
+
return { type: "paragraph", raw: e[0], text: t, tokens: this.lexer.inline(t) };
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
text(r) {
|
|
810
|
+
let e = this.rules.block.text.exec(r);
|
|
811
|
+
if (e) return { type: "text", raw: e[0], text: e[0], tokens: this.lexer.inline(e[0]) };
|
|
812
|
+
}
|
|
813
|
+
escape(r) {
|
|
814
|
+
let e = this.rules.inline.escape.exec(r);
|
|
815
|
+
if (e) return { type: "escape", raw: e[0], text: e[1] };
|
|
816
|
+
}
|
|
817
|
+
tag(r) {
|
|
818
|
+
let e = this.rules.inline.tag.exec(r);
|
|
819
|
+
if (e) return !this.lexer.state.inLink && this.rules.other.startATag.test(e[0]) ? this.lexer.state.inLink = !0 : this.lexer.state.inLink && this.rules.other.endATag.test(e[0]) && (this.lexer.state.inLink = !1), !this.lexer.state.inRawBlock && this.rules.other.startPreScriptTag.test(e[0]) ? this.lexer.state.inRawBlock = !0 : this.lexer.state.inRawBlock && this.rules.other.endPreScriptTag.test(e[0]) && (this.lexer.state.inRawBlock = !1), { type: "html", raw: e[0], inLink: this.lexer.state.inLink, inRawBlock: this.lexer.state.inRawBlock, block: !1, text: e[0] };
|
|
820
|
+
}
|
|
821
|
+
link(r) {
|
|
822
|
+
let e = this.rules.inline.link.exec(r);
|
|
823
|
+
if (e) {
|
|
824
|
+
let t = e[2].trim();
|
|
825
|
+
if (!this.options.pedantic && this.rules.other.startAngleBracket.test(t)) {
|
|
826
|
+
if (!this.rules.other.endAngleBracket.test(t)) return;
|
|
827
|
+
let n = Y(t.slice(0, -1), "\\");
|
|
828
|
+
if ((t.length - n.length) % 2 === 0) return;
|
|
829
|
+
} else {
|
|
830
|
+
let n = Kt(e[2], "()");
|
|
831
|
+
if (n === -2) return;
|
|
832
|
+
if (n > -1) {
|
|
833
|
+
let a = (e[0].indexOf("!") === 0 ? 5 : 4) + e[1].length + n;
|
|
834
|
+
e[2] = e[2].substring(0, n), e[0] = e[0].substring(0, a).trim(), e[3] = "";
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
let i = e[2], s = "";
|
|
838
|
+
if (this.options.pedantic) {
|
|
839
|
+
let n = this.rules.other.pedanticHrefTitle.exec(i);
|
|
840
|
+
n && (i = n[1], s = n[3]);
|
|
841
|
+
} else s = e[3] ? e[3].slice(1, -1) : "";
|
|
842
|
+
return i = i.trim(), this.rules.other.startAngleBracket.test(i) && (this.options.pedantic && !this.rules.other.endAngleBracket.test(t) ? i = i.slice(1) : i = i.slice(1, -1)), Ue(e, { href: i && i.replace(this.rules.inline.anyPunctuation, "$1"), title: s && s.replace(this.rules.inline.anyPunctuation, "$1") }, e[0], this.lexer, this.rules);
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
reflink(r, e) {
|
|
846
|
+
let t;
|
|
847
|
+
if ((t = this.rules.inline.reflink.exec(r)) || (t = this.rules.inline.nolink.exec(r))) {
|
|
848
|
+
let i = (t[2] || t[1]).replace(this.rules.other.multipleSpaceGlobal, " "), s = e[i.toLowerCase()];
|
|
849
|
+
if (!s) {
|
|
850
|
+
let n = t[0].charAt(0);
|
|
851
|
+
return { type: "text", raw: n, text: n };
|
|
852
|
+
}
|
|
853
|
+
return Ue(t, s, t[0], this.lexer, this.rules);
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
emStrong(r, e, t = "") {
|
|
857
|
+
let i = this.rules.inline.emStrongLDelim.exec(r);
|
|
858
|
+
if (!(!i || i[3] && t.match(this.rules.other.unicodeAlphaNumeric)) && (!(i[1] || i[2]) || !t || this.rules.inline.punctuation.exec(t))) {
|
|
859
|
+
let s = [...i[0]].length - 1, n, a, o = s, h = 0, l = i[0][0] === "*" ? this.rules.inline.emStrongRDelimAst : this.rules.inline.emStrongRDelimUnd;
|
|
860
|
+
for (l.lastIndex = 0, e = e.slice(-1 * r.length + s); (i = l.exec(e)) != null; ) {
|
|
861
|
+
if (n = i[1] || i[2] || i[3] || i[4] || i[5] || i[6], !n) continue;
|
|
862
|
+
if (a = [...n].length, i[3] || i[4]) {
|
|
863
|
+
o += a;
|
|
864
|
+
continue;
|
|
865
|
+
} else if ((i[5] || i[6]) && s % 3 && !((s + a) % 3)) {
|
|
866
|
+
h += a;
|
|
867
|
+
continue;
|
|
868
|
+
}
|
|
869
|
+
if (o -= a, o > 0) continue;
|
|
870
|
+
a = Math.min(a, a + o + h);
|
|
871
|
+
let p = [...i[0]][0].length, m = r.slice(0, s + i.index + p + a);
|
|
872
|
+
if (Math.min(s, a) % 2) {
|
|
873
|
+
let f = m.slice(1, -1);
|
|
874
|
+
return { type: "em", raw: m, text: f, tokens: this.lexer.inlineTokens(f) };
|
|
875
|
+
}
|
|
876
|
+
let c = m.slice(2, -2);
|
|
877
|
+
return { type: "strong", raw: m, text: c, tokens: this.lexer.inlineTokens(c) };
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
codespan(r) {
|
|
882
|
+
let e = this.rules.inline.code.exec(r);
|
|
883
|
+
if (e) {
|
|
884
|
+
let t = e[2].replace(this.rules.other.newLineCharGlobal, " "), i = this.rules.other.nonSpaceChar.test(t), s = this.rules.other.startingSpaceChar.test(t) && this.rules.other.endingSpaceChar.test(t);
|
|
885
|
+
return i && s && (t = t.substring(1, t.length - 1)), { type: "codespan", raw: e[0], text: t };
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
br(r) {
|
|
889
|
+
let e = this.rules.inline.br.exec(r);
|
|
890
|
+
if (e) return { type: "br", raw: e[0] };
|
|
891
|
+
}
|
|
892
|
+
del(r) {
|
|
893
|
+
let e = this.rules.inline.del.exec(r);
|
|
894
|
+
if (e) return { type: "del", raw: e[0], text: e[2], tokens: this.lexer.inlineTokens(e[2]) };
|
|
895
|
+
}
|
|
896
|
+
autolink(r) {
|
|
897
|
+
let e = this.rules.inline.autolink.exec(r);
|
|
898
|
+
if (e) {
|
|
899
|
+
let t, i;
|
|
900
|
+
return e[2] === "@" ? (t = e[1], i = "mailto:" + t) : (t = e[1], i = t), { type: "link", raw: e[0], text: t, href: i, tokens: [{ type: "text", raw: t, text: t }] };
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
url(r) {
|
|
904
|
+
var t;
|
|
905
|
+
let e;
|
|
906
|
+
if (e = this.rules.inline.url.exec(r)) {
|
|
907
|
+
let i, s;
|
|
908
|
+
if (e[2] === "@") i = e[0], s = "mailto:" + i;
|
|
909
|
+
else {
|
|
910
|
+
let n;
|
|
911
|
+
do
|
|
912
|
+
n = e[0], e[0] = ((t = this.rules.inline._backpedal.exec(e[0])) == null ? void 0 : t[0]) ?? "";
|
|
913
|
+
while (n !== e[0]);
|
|
914
|
+
i = e[0], e[1] === "www." ? s = "http://" + e[0] : s = e[0];
|
|
915
|
+
}
|
|
916
|
+
return { type: "link", raw: e[0], text: i, href: s, tokens: [{ type: "text", raw: i, text: i }] };
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
inlineText(r) {
|
|
920
|
+
let e = this.rules.inline.text.exec(r);
|
|
921
|
+
if (e) {
|
|
922
|
+
let t = this.lexer.state.inRawBlock;
|
|
923
|
+
return { type: "text", raw: e[0], text: e[0], escaped: t };
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
}, A = class ke {
|
|
927
|
+
constructor(e) {
|
|
928
|
+
u(this, "tokens");
|
|
929
|
+
u(this, "options");
|
|
930
|
+
u(this, "state");
|
|
931
|
+
u(this, "tokenizer");
|
|
932
|
+
u(this, "inlineQueue");
|
|
933
|
+
this.tokens = [], this.tokens.links = /* @__PURE__ */ Object.create(null), this.options = e || q, this.options.tokenizer = this.options.tokenizer || new le(), this.tokenizer = this.options.tokenizer, this.tokenizer.options = this.options, this.tokenizer.lexer = this, this.inlineQueue = [], this.state = { inLink: !1, inRawBlock: !1, top: !0 };
|
|
934
|
+
let t = { other: x, block: se.normal, inline: Z.normal };
|
|
935
|
+
this.options.pedantic ? (t.block = se.pedantic, t.inline = Z.pedantic) : this.options.gfm && (t.block = se.gfm, this.options.breaks ? t.inline = Z.breaks : t.inline = Z.gfm), this.tokenizer.rules = t;
|
|
936
|
+
}
|
|
937
|
+
static get rules() {
|
|
938
|
+
return { block: se, inline: Z };
|
|
939
|
+
}
|
|
940
|
+
static lex(e, t) {
|
|
941
|
+
return new ke(t).lex(e);
|
|
942
|
+
}
|
|
943
|
+
static lexInline(e, t) {
|
|
944
|
+
return new ke(t).inlineTokens(e);
|
|
945
|
+
}
|
|
946
|
+
lex(e) {
|
|
947
|
+
e = e.replace(x.carriageReturn, `
|
|
948
|
+
`), this.blockTokens(e, this.tokens);
|
|
949
|
+
for (let t = 0; t < this.inlineQueue.length; t++) {
|
|
950
|
+
let i = this.inlineQueue[t];
|
|
951
|
+
this.inlineTokens(i.src, i.tokens);
|
|
952
|
+
}
|
|
953
|
+
return this.inlineQueue = [], this.tokens;
|
|
954
|
+
}
|
|
955
|
+
blockTokens(e, t = [], i = !1) {
|
|
956
|
+
var s, n, a;
|
|
957
|
+
for (this.options.pedantic && (e = e.replace(x.tabCharGlobal, " ").replace(x.spaceLine, "")); e; ) {
|
|
958
|
+
let o;
|
|
959
|
+
if ((n = (s = this.options.extensions) == null ? void 0 : s.block) != null && n.some((l) => (o = l.call({ lexer: this }, e, t)) ? (e = e.substring(o.raw.length), t.push(o), !0) : !1)) continue;
|
|
960
|
+
if (o = this.tokenizer.space(e)) {
|
|
961
|
+
e = e.substring(o.raw.length);
|
|
962
|
+
let l = t.at(-1);
|
|
963
|
+
o.raw.length === 1 && l !== void 0 ? l.raw += `
|
|
964
|
+
` : t.push(o);
|
|
965
|
+
continue;
|
|
966
|
+
}
|
|
967
|
+
if (o = this.tokenizer.code(e)) {
|
|
968
|
+
e = e.substring(o.raw.length);
|
|
969
|
+
let l = t.at(-1);
|
|
970
|
+
(l == null ? void 0 : l.type) === "paragraph" || (l == null ? void 0 : l.type) === "text" ? (l.raw += (l.raw.endsWith(`
|
|
971
|
+
`) ? "" : `
|
|
972
|
+
`) + o.raw, l.text += `
|
|
973
|
+
` + o.text, this.inlineQueue.at(-1).src = l.text) : t.push(o);
|
|
974
|
+
continue;
|
|
975
|
+
}
|
|
976
|
+
if (o = this.tokenizer.fences(e)) {
|
|
977
|
+
e = e.substring(o.raw.length), t.push(o);
|
|
978
|
+
continue;
|
|
979
|
+
}
|
|
980
|
+
if (o = this.tokenizer.heading(e)) {
|
|
981
|
+
e = e.substring(o.raw.length), t.push(o);
|
|
982
|
+
continue;
|
|
983
|
+
}
|
|
984
|
+
if (o = this.tokenizer.hr(e)) {
|
|
985
|
+
e = e.substring(o.raw.length), t.push(o);
|
|
986
|
+
continue;
|
|
987
|
+
}
|
|
988
|
+
if (o = this.tokenizer.blockquote(e)) {
|
|
989
|
+
e = e.substring(o.raw.length), t.push(o);
|
|
990
|
+
continue;
|
|
991
|
+
}
|
|
992
|
+
if (o = this.tokenizer.list(e)) {
|
|
993
|
+
e = e.substring(o.raw.length), t.push(o);
|
|
994
|
+
continue;
|
|
995
|
+
}
|
|
996
|
+
if (o = this.tokenizer.html(e)) {
|
|
997
|
+
e = e.substring(o.raw.length), t.push(o);
|
|
998
|
+
continue;
|
|
999
|
+
}
|
|
1000
|
+
if (o = this.tokenizer.def(e)) {
|
|
1001
|
+
e = e.substring(o.raw.length);
|
|
1002
|
+
let l = t.at(-1);
|
|
1003
|
+
(l == null ? void 0 : l.type) === "paragraph" || (l == null ? void 0 : l.type) === "text" ? (l.raw += (l.raw.endsWith(`
|
|
1004
|
+
`) ? "" : `
|
|
1005
|
+
`) + o.raw, l.text += `
|
|
1006
|
+
` + o.raw, this.inlineQueue.at(-1).src = l.text) : this.tokens.links[o.tag] || (this.tokens.links[o.tag] = { href: o.href, title: o.title }, t.push(o));
|
|
1007
|
+
continue;
|
|
1008
|
+
}
|
|
1009
|
+
if (o = this.tokenizer.table(e)) {
|
|
1010
|
+
e = e.substring(o.raw.length), t.push(o);
|
|
1011
|
+
continue;
|
|
1012
|
+
}
|
|
1013
|
+
if (o = this.tokenizer.lheading(e)) {
|
|
1014
|
+
e = e.substring(o.raw.length), t.push(o);
|
|
1015
|
+
continue;
|
|
1016
|
+
}
|
|
1017
|
+
let h = e;
|
|
1018
|
+
if ((a = this.options.extensions) != null && a.startBlock) {
|
|
1019
|
+
let l = 1 / 0, p = e.slice(1), m;
|
|
1020
|
+
this.options.extensions.startBlock.forEach((c) => {
|
|
1021
|
+
m = c.call({ lexer: this }, p), typeof m == "number" && m >= 0 && (l = Math.min(l, m));
|
|
1022
|
+
}), l < 1 / 0 && l >= 0 && (h = e.substring(0, l + 1));
|
|
1023
|
+
}
|
|
1024
|
+
if (this.state.top && (o = this.tokenizer.paragraph(h))) {
|
|
1025
|
+
let l = t.at(-1);
|
|
1026
|
+
i && (l == null ? void 0 : l.type) === "paragraph" ? (l.raw += (l.raw.endsWith(`
|
|
1027
|
+
`) ? "" : `
|
|
1028
|
+
`) + o.raw, l.text += `
|
|
1029
|
+
` + o.text, this.inlineQueue.pop(), this.inlineQueue.at(-1).src = l.text) : t.push(o), i = h.length !== e.length, e = e.substring(o.raw.length);
|
|
1030
|
+
continue;
|
|
1031
|
+
}
|
|
1032
|
+
if (o = this.tokenizer.text(e)) {
|
|
1033
|
+
e = e.substring(o.raw.length);
|
|
1034
|
+
let l = t.at(-1);
|
|
1035
|
+
(l == null ? void 0 : l.type) === "text" ? (l.raw += (l.raw.endsWith(`
|
|
1036
|
+
`) ? "" : `
|
|
1037
|
+
`) + o.raw, l.text += `
|
|
1038
|
+
` + o.text, this.inlineQueue.pop(), this.inlineQueue.at(-1).src = l.text) : t.push(o);
|
|
1039
|
+
continue;
|
|
1040
|
+
}
|
|
1041
|
+
if (e) {
|
|
1042
|
+
let l = "Infinite loop on byte: " + e.charCodeAt(0);
|
|
1043
|
+
if (this.options.silent) {
|
|
1044
|
+
console.error(l);
|
|
1045
|
+
break;
|
|
1046
|
+
} else throw new Error(l);
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
return this.state.top = !0, t;
|
|
1050
|
+
}
|
|
1051
|
+
inline(e, t = []) {
|
|
1052
|
+
return this.inlineQueue.push({ src: e, tokens: t }), t;
|
|
1053
|
+
}
|
|
1054
|
+
inlineTokens(e, t = []) {
|
|
1055
|
+
var o, h, l, p, m;
|
|
1056
|
+
let i = e, s = null;
|
|
1057
|
+
if (this.tokens.links) {
|
|
1058
|
+
let c = Object.keys(this.tokens.links);
|
|
1059
|
+
if (c.length > 0) for (; (s = this.tokenizer.rules.inline.reflinkSearch.exec(i)) != null; ) c.includes(s[0].slice(s[0].lastIndexOf("[") + 1, -1)) && (i = i.slice(0, s.index) + "[" + "a".repeat(s[0].length - 2) + "]" + i.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex));
|
|
1060
|
+
}
|
|
1061
|
+
for (; (s = this.tokenizer.rules.inline.anyPunctuation.exec(i)) != null; ) i = i.slice(0, s.index) + "++" + i.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex);
|
|
1062
|
+
for (; (s = this.tokenizer.rules.inline.blockSkip.exec(i)) != null; ) i = i.slice(0, s.index) + "[" + "a".repeat(s[0].length - 2) + "]" + i.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);
|
|
1063
|
+
i = ((h = (o = this.options.hooks) == null ? void 0 : o.emStrongMask) == null ? void 0 : h.call({ lexer: this }, i)) ?? i;
|
|
1064
|
+
let n = !1, a = "";
|
|
1065
|
+
for (; e; ) {
|
|
1066
|
+
n || (a = ""), n = !1;
|
|
1067
|
+
let c;
|
|
1068
|
+
if ((p = (l = this.options.extensions) == null ? void 0 : l.inline) != null && p.some((d) => (c = d.call({ lexer: this }, e, t)) ? (e = e.substring(c.raw.length), t.push(c), !0) : !1)) continue;
|
|
1069
|
+
if (c = this.tokenizer.escape(e)) {
|
|
1070
|
+
e = e.substring(c.raw.length), t.push(c);
|
|
1071
|
+
continue;
|
|
1072
|
+
}
|
|
1073
|
+
if (c = this.tokenizer.tag(e)) {
|
|
1074
|
+
e = e.substring(c.raw.length), t.push(c);
|
|
1075
|
+
continue;
|
|
1076
|
+
}
|
|
1077
|
+
if (c = this.tokenizer.link(e)) {
|
|
1078
|
+
e = e.substring(c.raw.length), t.push(c);
|
|
1079
|
+
continue;
|
|
1080
|
+
}
|
|
1081
|
+
if (c = this.tokenizer.reflink(e, this.tokens.links)) {
|
|
1082
|
+
e = e.substring(c.raw.length);
|
|
1083
|
+
let d = t.at(-1);
|
|
1084
|
+
c.type === "text" && (d == null ? void 0 : d.type) === "text" ? (d.raw += c.raw, d.text += c.text) : t.push(c);
|
|
1085
|
+
continue;
|
|
1086
|
+
}
|
|
1087
|
+
if (c = this.tokenizer.emStrong(e, i, a)) {
|
|
1088
|
+
e = e.substring(c.raw.length), t.push(c);
|
|
1089
|
+
continue;
|
|
1090
|
+
}
|
|
1091
|
+
if (c = this.tokenizer.codespan(e)) {
|
|
1092
|
+
e = e.substring(c.raw.length), t.push(c);
|
|
1093
|
+
continue;
|
|
1094
|
+
}
|
|
1095
|
+
if (c = this.tokenizer.br(e)) {
|
|
1096
|
+
e = e.substring(c.raw.length), t.push(c);
|
|
1097
|
+
continue;
|
|
1098
|
+
}
|
|
1099
|
+
if (c = this.tokenizer.del(e)) {
|
|
1100
|
+
e = e.substring(c.raw.length), t.push(c);
|
|
1101
|
+
continue;
|
|
1102
|
+
}
|
|
1103
|
+
if (c = this.tokenizer.autolink(e)) {
|
|
1104
|
+
e = e.substring(c.raw.length), t.push(c);
|
|
1105
|
+
continue;
|
|
1106
|
+
}
|
|
1107
|
+
if (!this.state.inLink && (c = this.tokenizer.url(e))) {
|
|
1108
|
+
e = e.substring(c.raw.length), t.push(c);
|
|
1109
|
+
continue;
|
|
1110
|
+
}
|
|
1111
|
+
let f = e;
|
|
1112
|
+
if ((m = this.options.extensions) != null && m.startInline) {
|
|
1113
|
+
let d = 1 / 0, T = e.slice(1), L;
|
|
1114
|
+
this.options.extensions.startInline.forEach(($) => {
|
|
1115
|
+
L = $.call({ lexer: this }, T), typeof L == "number" && L >= 0 && (d = Math.min(d, L));
|
|
1116
|
+
}), d < 1 / 0 && d >= 0 && (f = e.substring(0, d + 1));
|
|
1117
|
+
}
|
|
1118
|
+
if (c = this.tokenizer.inlineText(f)) {
|
|
1119
|
+
e = e.substring(c.raw.length), c.raw.slice(-1) !== "_" && (a = c.raw.slice(-1)), n = !0;
|
|
1120
|
+
let d = t.at(-1);
|
|
1121
|
+
(d == null ? void 0 : d.type) === "text" ? (d.raw += c.raw, d.text += c.text) : t.push(c);
|
|
1122
|
+
continue;
|
|
1123
|
+
}
|
|
1124
|
+
if (e) {
|
|
1125
|
+
let d = "Infinite loop on byte: " + e.charCodeAt(0);
|
|
1126
|
+
if (this.options.silent) {
|
|
1127
|
+
console.error(d);
|
|
1128
|
+
break;
|
|
1129
|
+
} else throw new Error(d);
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
return t;
|
|
1133
|
+
}
|
|
1134
|
+
}, ce = class {
|
|
1135
|
+
constructor(r) {
|
|
1136
|
+
u(this, "options");
|
|
1137
|
+
u(this, "parser");
|
|
1138
|
+
this.options = r || q;
|
|
1139
|
+
}
|
|
1140
|
+
space(r) {
|
|
1141
|
+
return "";
|
|
1142
|
+
}
|
|
1143
|
+
code({ text: r, lang: e, escaped: t }) {
|
|
1144
|
+
var n;
|
|
1145
|
+
let i = (n = (e || "").match(x.notSpaceStart)) == null ? void 0 : n[0], s = r.replace(x.endingNewline, "") + `
|
|
1146
|
+
`;
|
|
1147
|
+
return i ? '<pre><code class="language-' + v(i) + '">' + (t ? s : v(s, !0)) + `</code></pre>
|
|
1148
|
+
` : "<pre><code>" + (t ? s : v(s, !0)) + `</code></pre>
|
|
1149
|
+
`;
|
|
1150
|
+
}
|
|
1151
|
+
blockquote({ tokens: r }) {
|
|
1152
|
+
return `<blockquote>
|
|
1153
|
+
${this.parser.parse(r)}</blockquote>
|
|
1154
|
+
`;
|
|
1155
|
+
}
|
|
1156
|
+
html({ text: r }) {
|
|
1157
|
+
return r;
|
|
1158
|
+
}
|
|
1159
|
+
def(r) {
|
|
1160
|
+
return "";
|
|
1161
|
+
}
|
|
1162
|
+
heading({ tokens: r, depth: e }) {
|
|
1163
|
+
return `<h${e}>${this.parser.parseInline(r)}</h${e}>
|
|
1164
|
+
`;
|
|
1165
|
+
}
|
|
1166
|
+
hr(r) {
|
|
1167
|
+
return `<hr>
|
|
1168
|
+
`;
|
|
1169
|
+
}
|
|
1170
|
+
list(r) {
|
|
1171
|
+
let e = r.ordered, t = r.start, i = "";
|
|
1172
|
+
for (let a = 0; a < r.items.length; a++) {
|
|
1173
|
+
let o = r.items[a];
|
|
1174
|
+
i += this.listitem(o);
|
|
1175
|
+
}
|
|
1176
|
+
let s = e ? "ol" : "ul", n = e && t !== 1 ? ' start="' + t + '"' : "";
|
|
1177
|
+
return "<" + s + n + `>
|
|
1178
|
+
` + i + "</" + s + `>
|
|
1179
|
+
`;
|
|
1180
|
+
}
|
|
1181
|
+
listitem(r) {
|
|
1182
|
+
var t;
|
|
1183
|
+
let e = "";
|
|
1184
|
+
if (r.task) {
|
|
1185
|
+
let i = this.checkbox({ checked: !!r.checked });
|
|
1186
|
+
r.loose ? ((t = r.tokens[0]) == null ? void 0 : t.type) === "paragraph" ? (r.tokens[0].text = i + " " + r.tokens[0].text, r.tokens[0].tokens && r.tokens[0].tokens.length > 0 && r.tokens[0].tokens[0].type === "text" && (r.tokens[0].tokens[0].text = i + " " + v(r.tokens[0].tokens[0].text), r.tokens[0].tokens[0].escaped = !0)) : r.tokens.unshift({ type: "text", raw: i + " ", text: i + " ", escaped: !0 }) : e += i + " ";
|
|
1187
|
+
}
|
|
1188
|
+
return e += this.parser.parse(r.tokens, !!r.loose), `<li>${e}</li>
|
|
1189
|
+
`;
|
|
1190
|
+
}
|
|
1191
|
+
checkbox({ checked: r }) {
|
|
1192
|
+
return "<input " + (r ? 'checked="" ' : "") + 'disabled="" type="checkbox">';
|
|
1193
|
+
}
|
|
1194
|
+
paragraph({ tokens: r }) {
|
|
1195
|
+
return `<p>${this.parser.parseInline(r)}</p>
|
|
1196
|
+
`;
|
|
1197
|
+
}
|
|
1198
|
+
table(r) {
|
|
1199
|
+
let e = "", t = "";
|
|
1200
|
+
for (let s = 0; s < r.header.length; s++) t += this.tablecell(r.header[s]);
|
|
1201
|
+
e += this.tablerow({ text: t });
|
|
1202
|
+
let i = "";
|
|
1203
|
+
for (let s = 0; s < r.rows.length; s++) {
|
|
1204
|
+
let n = r.rows[s];
|
|
1205
|
+
t = "";
|
|
1206
|
+
for (let a = 0; a < n.length; a++) t += this.tablecell(n[a]);
|
|
1207
|
+
i += this.tablerow({ text: t });
|
|
1208
|
+
}
|
|
1209
|
+
return i && (i = `<tbody>${i}</tbody>`), `<table>
|
|
1210
|
+
<thead>
|
|
1211
|
+
` + e + `</thead>
|
|
1212
|
+
` + i + `</table>
|
|
1213
|
+
`;
|
|
1214
|
+
}
|
|
1215
|
+
tablerow({ text: r }) {
|
|
1216
|
+
return `<tr>
|
|
1217
|
+
${r}</tr>
|
|
1218
|
+
`;
|
|
1219
|
+
}
|
|
1220
|
+
tablecell(r) {
|
|
1221
|
+
let e = this.parser.parseInline(r.tokens), t = r.header ? "th" : "td";
|
|
1222
|
+
return (r.align ? `<${t} align="${r.align}">` : `<${t}>`) + e + `</${t}>
|
|
1223
|
+
`;
|
|
1224
|
+
}
|
|
1225
|
+
strong({ tokens: r }) {
|
|
1226
|
+
return `<strong>${this.parser.parseInline(r)}</strong>`;
|
|
1227
|
+
}
|
|
1228
|
+
em({ tokens: r }) {
|
|
1229
|
+
return `<em>${this.parser.parseInline(r)}</em>`;
|
|
1230
|
+
}
|
|
1231
|
+
codespan({ text: r }) {
|
|
1232
|
+
return `<code>${v(r, !0)}</code>`;
|
|
1233
|
+
}
|
|
1234
|
+
br(r) {
|
|
1235
|
+
return "<br>";
|
|
1236
|
+
}
|
|
1237
|
+
del({ tokens: r }) {
|
|
1238
|
+
return `<del>${this.parser.parseInline(r)}</del>`;
|
|
1239
|
+
}
|
|
1240
|
+
link({ href: r, title: e, tokens: t }) {
|
|
1241
|
+
let i = this.parser.parseInline(t), s = Be(r);
|
|
1242
|
+
if (s === null) return i;
|
|
1243
|
+
r = s;
|
|
1244
|
+
let n = '<a href="' + r + '"';
|
|
1245
|
+
return e && (n += ' title="' + v(e) + '"'), n += ">" + i + "</a>", n;
|
|
1246
|
+
}
|
|
1247
|
+
image({ href: r, title: e, text: t, tokens: i }) {
|
|
1248
|
+
i && (t = this.parser.parseInline(i, this.parser.textRenderer));
|
|
1249
|
+
let s = Be(r);
|
|
1250
|
+
if (s === null) return v(t);
|
|
1251
|
+
r = s;
|
|
1252
|
+
let n = `<img src="${r}" alt="${t}"`;
|
|
1253
|
+
return e && (n += ` title="${v(e)}"`), n += ">", n;
|
|
1254
|
+
}
|
|
1255
|
+
text(r) {
|
|
1256
|
+
return "tokens" in r && r.tokens ? this.parser.parseInline(r.tokens) : "escaped" in r && r.escaped ? r.text : v(r.text);
|
|
1257
|
+
}
|
|
1258
|
+
}, $e = class {
|
|
1259
|
+
strong({ text: r }) {
|
|
1260
|
+
return r;
|
|
1261
|
+
}
|
|
1262
|
+
em({ text: r }) {
|
|
1263
|
+
return r;
|
|
1264
|
+
}
|
|
1265
|
+
codespan({ text: r }) {
|
|
1266
|
+
return r;
|
|
1267
|
+
}
|
|
1268
|
+
del({ text: r }) {
|
|
1269
|
+
return r;
|
|
1270
|
+
}
|
|
1271
|
+
html({ text: r }) {
|
|
1272
|
+
return r;
|
|
1273
|
+
}
|
|
1274
|
+
text({ text: r }) {
|
|
1275
|
+
return r;
|
|
1276
|
+
}
|
|
1277
|
+
link({ text: r }) {
|
|
1278
|
+
return "" + r;
|
|
1279
|
+
}
|
|
1280
|
+
image({ text: r }) {
|
|
1281
|
+
return "" + r;
|
|
1282
|
+
}
|
|
1283
|
+
br() {
|
|
1284
|
+
return "";
|
|
1285
|
+
}
|
|
1286
|
+
}, E = class be {
|
|
1287
|
+
constructor(e) {
|
|
1288
|
+
u(this, "options");
|
|
1289
|
+
u(this, "renderer");
|
|
1290
|
+
u(this, "textRenderer");
|
|
1291
|
+
this.options = e || q, this.options.renderer = this.options.renderer || new ce(), this.renderer = this.options.renderer, this.renderer.options = this.options, this.renderer.parser = this, this.textRenderer = new $e();
|
|
1292
|
+
}
|
|
1293
|
+
static parse(e, t) {
|
|
1294
|
+
return new be(t).parse(e);
|
|
1295
|
+
}
|
|
1296
|
+
static parseInline(e, t) {
|
|
1297
|
+
return new be(t).parseInline(e);
|
|
1298
|
+
}
|
|
1299
|
+
parse(e, t = !0) {
|
|
1300
|
+
var s, n;
|
|
1301
|
+
let i = "";
|
|
1302
|
+
for (let a = 0; a < e.length; a++) {
|
|
1303
|
+
let o = e[a];
|
|
1304
|
+
if ((n = (s = this.options.extensions) == null ? void 0 : s.renderers) != null && n[o.type]) {
|
|
1305
|
+
let l = o, p = this.options.extensions.renderers[l.type].call({ parser: this }, l);
|
|
1306
|
+
if (p !== !1 || !["space", "hr", "heading", "code", "table", "blockquote", "list", "html", "def", "paragraph", "text"].includes(l.type)) {
|
|
1307
|
+
i += p || "";
|
|
1308
|
+
continue;
|
|
1309
|
+
}
|
|
1310
|
+
}
|
|
1311
|
+
let h = o;
|
|
1312
|
+
switch (h.type) {
|
|
1313
|
+
case "space": {
|
|
1314
|
+
i += this.renderer.space(h);
|
|
1315
|
+
continue;
|
|
1316
|
+
}
|
|
1317
|
+
case "hr": {
|
|
1318
|
+
i += this.renderer.hr(h);
|
|
1319
|
+
continue;
|
|
1320
|
+
}
|
|
1321
|
+
case "heading": {
|
|
1322
|
+
i += this.renderer.heading(h);
|
|
1323
|
+
continue;
|
|
1324
|
+
}
|
|
1325
|
+
case "code": {
|
|
1326
|
+
i += this.renderer.code(h);
|
|
1327
|
+
continue;
|
|
1328
|
+
}
|
|
1329
|
+
case "table": {
|
|
1330
|
+
i += this.renderer.table(h);
|
|
1331
|
+
continue;
|
|
1332
|
+
}
|
|
1333
|
+
case "blockquote": {
|
|
1334
|
+
i += this.renderer.blockquote(h);
|
|
1335
|
+
continue;
|
|
1336
|
+
}
|
|
1337
|
+
case "list": {
|
|
1338
|
+
i += this.renderer.list(h);
|
|
1339
|
+
continue;
|
|
1340
|
+
}
|
|
1341
|
+
case "html": {
|
|
1342
|
+
i += this.renderer.html(h);
|
|
1343
|
+
continue;
|
|
1344
|
+
}
|
|
1345
|
+
case "def": {
|
|
1346
|
+
i += this.renderer.def(h);
|
|
1347
|
+
continue;
|
|
1348
|
+
}
|
|
1349
|
+
case "paragraph": {
|
|
1350
|
+
i += this.renderer.paragraph(h);
|
|
1351
|
+
continue;
|
|
1352
|
+
}
|
|
1353
|
+
case "text": {
|
|
1354
|
+
let l = h, p = this.renderer.text(l);
|
|
1355
|
+
for (; a + 1 < e.length && e[a + 1].type === "text"; ) l = e[++a], p += `
|
|
1356
|
+
` + this.renderer.text(l);
|
|
1357
|
+
t ? i += this.renderer.paragraph({ type: "paragraph", raw: p, text: p, tokens: [{ type: "text", raw: p, text: p, escaped: !0 }] }) : i += p;
|
|
1358
|
+
continue;
|
|
1359
|
+
}
|
|
1360
|
+
default: {
|
|
1361
|
+
let l = 'Token with "' + h.type + '" type was not found.';
|
|
1362
|
+
if (this.options.silent) return console.error(l), "";
|
|
1363
|
+
throw new Error(l);
|
|
1364
|
+
}
|
|
1365
|
+
}
|
|
1366
|
+
}
|
|
1367
|
+
return i;
|
|
1368
|
+
}
|
|
1369
|
+
parseInline(e, t = this.renderer) {
|
|
1370
|
+
var s, n;
|
|
1371
|
+
let i = "";
|
|
1372
|
+
for (let a = 0; a < e.length; a++) {
|
|
1373
|
+
let o = e[a];
|
|
1374
|
+
if ((n = (s = this.options.extensions) == null ? void 0 : s.renderers) != null && n[o.type]) {
|
|
1375
|
+
let l = this.options.extensions.renderers[o.type].call({ parser: this }, o);
|
|
1376
|
+
if (l !== !1 || !["escape", "html", "link", "image", "strong", "em", "codespan", "br", "del", "text"].includes(o.type)) {
|
|
1377
|
+
i += l || "";
|
|
1378
|
+
continue;
|
|
1379
|
+
}
|
|
1380
|
+
}
|
|
1381
|
+
let h = o;
|
|
1382
|
+
switch (h.type) {
|
|
1383
|
+
case "escape": {
|
|
1384
|
+
i += t.text(h);
|
|
1385
|
+
break;
|
|
1386
|
+
}
|
|
1387
|
+
case "html": {
|
|
1388
|
+
i += t.html(h);
|
|
1389
|
+
break;
|
|
1390
|
+
}
|
|
1391
|
+
case "link": {
|
|
1392
|
+
i += t.link(h);
|
|
1393
|
+
break;
|
|
1394
|
+
}
|
|
1395
|
+
case "image": {
|
|
1396
|
+
i += t.image(h);
|
|
1397
|
+
break;
|
|
1398
|
+
}
|
|
1399
|
+
case "strong": {
|
|
1400
|
+
i += t.strong(h);
|
|
1401
|
+
break;
|
|
1402
|
+
}
|
|
1403
|
+
case "em": {
|
|
1404
|
+
i += t.em(h);
|
|
1405
|
+
break;
|
|
1406
|
+
}
|
|
1407
|
+
case "codespan": {
|
|
1408
|
+
i += t.codespan(h);
|
|
1409
|
+
break;
|
|
1410
|
+
}
|
|
1411
|
+
case "br": {
|
|
1412
|
+
i += t.br(h);
|
|
1413
|
+
break;
|
|
1414
|
+
}
|
|
1415
|
+
case "del": {
|
|
1416
|
+
i += t.del(h);
|
|
1417
|
+
break;
|
|
1418
|
+
}
|
|
1419
|
+
case "text": {
|
|
1420
|
+
i += t.text(h);
|
|
1421
|
+
break;
|
|
1422
|
+
}
|
|
1423
|
+
default: {
|
|
1424
|
+
let l = 'Token with "' + h.type + '" type was not found.';
|
|
1425
|
+
if (this.options.silent) return console.error(l), "";
|
|
1426
|
+
throw new Error(l);
|
|
1427
|
+
}
|
|
1428
|
+
}
|
|
1429
|
+
}
|
|
1430
|
+
return i;
|
|
1431
|
+
}
|
|
1432
|
+
}, re, X = (re = class {
|
|
1433
|
+
constructor(r) {
|
|
1434
|
+
u(this, "options");
|
|
1435
|
+
u(this, "block");
|
|
1436
|
+
this.options = r || q;
|
|
1437
|
+
}
|
|
1438
|
+
preprocess(r) {
|
|
1439
|
+
return r;
|
|
1440
|
+
}
|
|
1441
|
+
postprocess(r) {
|
|
1442
|
+
return r;
|
|
1443
|
+
}
|
|
1444
|
+
processAllTokens(r) {
|
|
1445
|
+
return r;
|
|
1446
|
+
}
|
|
1447
|
+
emStrongMask(r) {
|
|
1448
|
+
return r;
|
|
1449
|
+
}
|
|
1450
|
+
provideLexer() {
|
|
1451
|
+
return this.block ? A.lex : A.lexInline;
|
|
1452
|
+
}
|
|
1453
|
+
provideParser() {
|
|
1454
|
+
return this.block ? E.parse : E.parseInline;
|
|
1455
|
+
}
|
|
1456
|
+
}, u(re, "passThroughHooks", /* @__PURE__ */ new Set(["preprocess", "postprocess", "processAllTokens", "emStrongMask"])), u(re, "passThroughHooksRespectAsync", /* @__PURE__ */ new Set(["preprocess", "postprocess", "processAllTokens"])), re), Vt = class {
|
|
1457
|
+
constructor(...r) {
|
|
1458
|
+
u(this, "defaults", Se());
|
|
1459
|
+
u(this, "options", this.setOptions);
|
|
1460
|
+
u(this, "parse", this.parseMarkdown(!0));
|
|
1461
|
+
u(this, "parseInline", this.parseMarkdown(!1));
|
|
1462
|
+
u(this, "Parser", E);
|
|
1463
|
+
u(this, "Renderer", ce);
|
|
1464
|
+
u(this, "TextRenderer", $e);
|
|
1465
|
+
u(this, "Lexer", A);
|
|
1466
|
+
u(this, "Tokenizer", le);
|
|
1467
|
+
u(this, "Hooks", X);
|
|
1468
|
+
this.use(...r);
|
|
1469
|
+
}
|
|
1470
|
+
walkTokens(r, e) {
|
|
1471
|
+
var i, s;
|
|
1472
|
+
let t = [];
|
|
1473
|
+
for (let n of r) switch (t = t.concat(e.call(this, n)), n.type) {
|
|
1474
|
+
case "table": {
|
|
1475
|
+
let a = n;
|
|
1476
|
+
for (let o of a.header) t = t.concat(this.walkTokens(o.tokens, e));
|
|
1477
|
+
for (let o of a.rows) for (let h of o) t = t.concat(this.walkTokens(h.tokens, e));
|
|
1478
|
+
break;
|
|
1479
|
+
}
|
|
1480
|
+
case "list": {
|
|
1481
|
+
let a = n;
|
|
1482
|
+
t = t.concat(this.walkTokens(a.items, e));
|
|
1483
|
+
break;
|
|
1484
|
+
}
|
|
1485
|
+
default: {
|
|
1486
|
+
let a = n;
|
|
1487
|
+
(s = (i = this.defaults.extensions) == null ? void 0 : i.childTokens) != null && s[a.type] ? this.defaults.extensions.childTokens[a.type].forEach((o) => {
|
|
1488
|
+
let h = a[o].flat(1 / 0);
|
|
1489
|
+
t = t.concat(this.walkTokens(h, e));
|
|
1490
|
+
}) : a.tokens && (t = t.concat(this.walkTokens(a.tokens, e)));
|
|
1491
|
+
}
|
|
1492
|
+
}
|
|
1493
|
+
return t;
|
|
1494
|
+
}
|
|
1495
|
+
use(...r) {
|
|
1496
|
+
let e = this.defaults.extensions || { renderers: {}, childTokens: {} };
|
|
1497
|
+
return r.forEach((t) => {
|
|
1498
|
+
let i = { ...t };
|
|
1499
|
+
if (i.async = this.defaults.async || i.async || !1, t.extensions && (t.extensions.forEach((s) => {
|
|
1500
|
+
if (!s.name) throw new Error("extension name required");
|
|
1501
|
+
if ("renderer" in s) {
|
|
1502
|
+
let n = e.renderers[s.name];
|
|
1503
|
+
n ? e.renderers[s.name] = function(...a) {
|
|
1504
|
+
let o = s.renderer.apply(this, a);
|
|
1505
|
+
return o === !1 && (o = n.apply(this, a)), o;
|
|
1506
|
+
} : e.renderers[s.name] = s.renderer;
|
|
1507
|
+
}
|
|
1508
|
+
if ("tokenizer" in s) {
|
|
1509
|
+
if (!s.level || s.level !== "block" && s.level !== "inline") throw new Error("extension level must be 'block' or 'inline'");
|
|
1510
|
+
let n = e[s.level];
|
|
1511
|
+
n ? n.unshift(s.tokenizer) : e[s.level] = [s.tokenizer], s.start && (s.level === "block" ? e.startBlock ? e.startBlock.push(s.start) : e.startBlock = [s.start] : s.level === "inline" && (e.startInline ? e.startInline.push(s.start) : e.startInline = [s.start]));
|
|
1512
|
+
}
|
|
1513
|
+
"childTokens" in s && s.childTokens && (e.childTokens[s.name] = s.childTokens);
|
|
1514
|
+
}), i.extensions = e), t.renderer) {
|
|
1515
|
+
let s = this.defaults.renderer || new ce(this.defaults);
|
|
1516
|
+
for (let n in t.renderer) {
|
|
1517
|
+
if (!(n in s)) throw new Error(`renderer '${n}' does not exist`);
|
|
1518
|
+
if (["options", "parser"].includes(n)) continue;
|
|
1519
|
+
let a = n, o = t.renderer[a], h = s[a];
|
|
1520
|
+
s[a] = (...l) => {
|
|
1521
|
+
let p = o.apply(s, l);
|
|
1522
|
+
return p === !1 && (p = h.apply(s, l)), p || "";
|
|
1523
|
+
};
|
|
1524
|
+
}
|
|
1525
|
+
i.renderer = s;
|
|
1526
|
+
}
|
|
1527
|
+
if (t.tokenizer) {
|
|
1528
|
+
let s = this.defaults.tokenizer || new le(this.defaults);
|
|
1529
|
+
for (let n in t.tokenizer) {
|
|
1530
|
+
if (!(n in s)) throw new Error(`tokenizer '${n}' does not exist`);
|
|
1531
|
+
if (["options", "rules", "lexer"].includes(n)) continue;
|
|
1532
|
+
let a = n, o = t.tokenizer[a], h = s[a];
|
|
1533
|
+
s[a] = (...l) => {
|
|
1534
|
+
let p = o.apply(s, l);
|
|
1535
|
+
return p === !1 && (p = h.apply(s, l)), p;
|
|
1536
|
+
};
|
|
1537
|
+
}
|
|
1538
|
+
i.tokenizer = s;
|
|
1539
|
+
}
|
|
1540
|
+
if (t.hooks) {
|
|
1541
|
+
let s = this.defaults.hooks || new X();
|
|
1542
|
+
for (let n in t.hooks) {
|
|
1543
|
+
if (!(n in s)) throw new Error(`hook '${n}' does not exist`);
|
|
1544
|
+
if (["options", "block"].includes(n)) continue;
|
|
1545
|
+
let a = n, o = t.hooks[a], h = s[a];
|
|
1546
|
+
X.passThroughHooks.has(n) ? s[a] = (l) => {
|
|
1547
|
+
if (this.defaults.async && X.passThroughHooksRespectAsync.has(n)) return (async () => {
|
|
1548
|
+
let m = await o.call(s, l);
|
|
1549
|
+
return h.call(s, m);
|
|
1550
|
+
})();
|
|
1551
|
+
let p = o.call(s, l);
|
|
1552
|
+
return h.call(s, p);
|
|
1553
|
+
} : s[a] = (...l) => {
|
|
1554
|
+
if (this.defaults.async) return (async () => {
|
|
1555
|
+
let m = await o.apply(s, l);
|
|
1556
|
+
return m === !1 && (m = await h.apply(s, l)), m;
|
|
1557
|
+
})();
|
|
1558
|
+
let p = o.apply(s, l);
|
|
1559
|
+
return p === !1 && (p = h.apply(s, l)), p;
|
|
1560
|
+
};
|
|
1561
|
+
}
|
|
1562
|
+
i.hooks = s;
|
|
1563
|
+
}
|
|
1564
|
+
if (t.walkTokens) {
|
|
1565
|
+
let s = this.defaults.walkTokens, n = t.walkTokens;
|
|
1566
|
+
i.walkTokens = function(a) {
|
|
1567
|
+
let o = [];
|
|
1568
|
+
return o.push(n.call(this, a)), s && (o = o.concat(s.call(this, a))), o;
|
|
1569
|
+
};
|
|
1570
|
+
}
|
|
1571
|
+
this.defaults = { ...this.defaults, ...i };
|
|
1572
|
+
}), this;
|
|
1573
|
+
}
|
|
1574
|
+
setOptions(r) {
|
|
1575
|
+
return this.defaults = { ...this.defaults, ...r }, this;
|
|
1576
|
+
}
|
|
1577
|
+
lexer(r, e) {
|
|
1578
|
+
return A.lex(r, e ?? this.defaults);
|
|
1579
|
+
}
|
|
1580
|
+
parser(r, e) {
|
|
1581
|
+
return E.parse(r, e ?? this.defaults);
|
|
1582
|
+
}
|
|
1583
|
+
parseMarkdown(r) {
|
|
1584
|
+
return (e, t) => {
|
|
1585
|
+
let i = { ...t }, s = { ...this.defaults, ...i }, n = this.onError(!!s.silent, !!s.async);
|
|
1586
|
+
if (this.defaults.async === !0 && i.async === !1) return n(new Error("marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise."));
|
|
1587
|
+
if (typeof e > "u" || e === null) return n(new Error("marked(): input parameter is undefined or null"));
|
|
1588
|
+
if (typeof e != "string") return n(new Error("marked(): input parameter is of type " + Object.prototype.toString.call(e) + ", string expected"));
|
|
1589
|
+
if (s.hooks && (s.hooks.options = s, s.hooks.block = r), s.async) return (async () => {
|
|
1590
|
+
let a = s.hooks ? await s.hooks.preprocess(e) : e, o = await (s.hooks ? await s.hooks.provideLexer() : r ? A.lex : A.lexInline)(a, s), h = s.hooks ? await s.hooks.processAllTokens(o) : o;
|
|
1591
|
+
s.walkTokens && await Promise.all(this.walkTokens(h, s.walkTokens));
|
|
1592
|
+
let l = await (s.hooks ? await s.hooks.provideParser() : r ? E.parse : E.parseInline)(h, s);
|
|
1593
|
+
return s.hooks ? await s.hooks.postprocess(l) : l;
|
|
1594
|
+
})().catch(n);
|
|
1595
|
+
try {
|
|
1596
|
+
s.hooks && (e = s.hooks.preprocess(e));
|
|
1597
|
+
let a = (s.hooks ? s.hooks.provideLexer() : r ? A.lex : A.lexInline)(e, s);
|
|
1598
|
+
s.hooks && (a = s.hooks.processAllTokens(a)), s.walkTokens && this.walkTokens(a, s.walkTokens);
|
|
1599
|
+
let o = (s.hooks ? s.hooks.provideParser() : r ? E.parse : E.parseInline)(a, s);
|
|
1600
|
+
return s.hooks && (o = s.hooks.postprocess(o)), o;
|
|
1601
|
+
} catch (a) {
|
|
1602
|
+
return n(a);
|
|
1603
|
+
}
|
|
1604
|
+
};
|
|
1605
|
+
}
|
|
1606
|
+
onError(r, e) {
|
|
1607
|
+
return (t) => {
|
|
1608
|
+
if (t.message += `
|
|
1609
|
+
Please report this to https://github.com/markedjs/marked.`, r) {
|
|
1610
|
+
let i = "<p>An error occurred:</p><pre>" + v(t.message + "", !0) + "</pre>";
|
|
1611
|
+
return e ? Promise.resolve(i) : i;
|
|
1612
|
+
}
|
|
1613
|
+
if (e) return Promise.reject(t);
|
|
1614
|
+
throw t;
|
|
1615
|
+
};
|
|
1616
|
+
}
|
|
1617
|
+
}, H = new Vt();
|
|
1618
|
+
function b(r, e) {
|
|
1619
|
+
return H.parse(r, e);
|
|
1620
|
+
}
|
|
1621
|
+
b.options = b.setOptions = function(r) {
|
|
1622
|
+
return H.setOptions(r), b.defaults = H.defaults, We(b.defaults), b;
|
|
1623
|
+
};
|
|
1624
|
+
b.getDefaults = Se;
|
|
1625
|
+
b.defaults = q;
|
|
1626
|
+
b.use = function(...r) {
|
|
1627
|
+
return H.use(...r), b.defaults = H.defaults, We(b.defaults), b;
|
|
1628
|
+
};
|
|
1629
|
+
b.walkTokens = function(r, e) {
|
|
1630
|
+
return H.walkTokens(r, e);
|
|
1631
|
+
};
|
|
1632
|
+
b.parseInline = H.parseInline;
|
|
1633
|
+
b.Parser = E;
|
|
1634
|
+
b.parser = E.parse;
|
|
1635
|
+
b.Renderer = ce;
|
|
1636
|
+
b.TextRenderer = $e;
|
|
1637
|
+
b.Lexer = A;
|
|
1638
|
+
b.lexer = A.lex;
|
|
1639
|
+
b.Tokenizer = le;
|
|
1640
|
+
b.Hooks = X;
|
|
1641
|
+
b.parse = b;
|
|
1642
|
+
b.options;
|
|
1643
|
+
b.setOptions;
|
|
1644
|
+
b.use;
|
|
1645
|
+
b.walkTokens;
|
|
1646
|
+
b.parseInline;
|
|
1647
|
+
E.parse;
|
|
1648
|
+
A.lex;
|
|
1649
|
+
const pe = class pe {
|
|
1650
|
+
constructor() {
|
|
1651
|
+
u(this, "currentLang", "en");
|
|
1652
|
+
u(this, "fallbackLang", "en");
|
|
1653
|
+
u(this, "translations", {});
|
|
1654
|
+
u(this, "supportedLangs", /* @__PURE__ */ new Set(["en", "pl"]));
|
|
1655
|
+
u(this, "loadingPromises", /* @__PURE__ */ new Map());
|
|
1656
|
+
}
|
|
1657
|
+
/** Returns the global singleton instance */
|
|
1658
|
+
static getInstance() {
|
|
1659
|
+
return this.instance || (this.instance = new pe()), this.instance;
|
|
1660
|
+
}
|
|
1661
|
+
/**
|
|
1662
|
+
* Sets the current active language.
|
|
1663
|
+
* Emits a change event if language was updated.
|
|
1664
|
+
*/
|
|
1665
|
+
setLanguage(e) {
|
|
1666
|
+
if (!this.supportedLangs.has(e)) {
|
|
1667
|
+
console.warn(`[HintoriumI18n] Unsupported language: ${e}`);
|
|
1668
|
+
return;
|
|
1669
|
+
}
|
|
1670
|
+
this.currentLang !== e && (this.currentLang = e);
|
|
1671
|
+
}
|
|
1672
|
+
/**
|
|
1673
|
+
* Sets the fallback language used when a translation key is missing.
|
|
1674
|
+
*/
|
|
1675
|
+
setFallbackLanguage(e) {
|
|
1676
|
+
if (!this.supportedLangs.has(e)) {
|
|
1677
|
+
console.warn(`[HintoriumI18n] Unsupported fallback language: ${e}`);
|
|
1678
|
+
return;
|
|
1679
|
+
}
|
|
1680
|
+
this.fallbackLang = e;
|
|
1681
|
+
}
|
|
1682
|
+
/**
|
|
1683
|
+
* Loads multiple language files at once.
|
|
1684
|
+
* @param langs - Array of language configurations
|
|
1685
|
+
* @returns Promise that resolves when all translations are loaded
|
|
1686
|
+
*/
|
|
1687
|
+
async loadMultipleTranslations(e) {
|
|
1688
|
+
await Promise.all(
|
|
1689
|
+
e.map(({ lang: t, url: i }) => this.loadTranslations(t, i))
|
|
1690
|
+
);
|
|
1691
|
+
}
|
|
1692
|
+
/**
|
|
1693
|
+
* Loads translations from an external file (JSON).
|
|
1694
|
+
* @param lang - Language code
|
|
1695
|
+
* @param url - URL to the JSON file
|
|
1696
|
+
* @returns Promise that resolves when translations are loaded
|
|
1697
|
+
*/
|
|
1698
|
+
async loadTranslations(e, t) {
|
|
1699
|
+
if (this.loadingPromises.has(e))
|
|
1700
|
+
return this.loadingPromises.get(e);
|
|
1701
|
+
const i = (async () => {
|
|
1702
|
+
try {
|
|
1703
|
+
const s = await fetch(t);
|
|
1704
|
+
if (!s.ok)
|
|
1705
|
+
throw new Error(
|
|
1706
|
+
`Failed to load translations: ${s.statusText}`
|
|
1707
|
+
);
|
|
1708
|
+
const n = await s.json();
|
|
1709
|
+
this.setTranslations(e, n);
|
|
1710
|
+
} catch (s) {
|
|
1711
|
+
throw console.error(
|
|
1712
|
+
`[HintoriumI18n] Error loading translations for ${e}:`,
|
|
1713
|
+
s
|
|
1714
|
+
), s;
|
|
1715
|
+
} finally {
|
|
1716
|
+
this.loadingPromises.delete(e);
|
|
1717
|
+
}
|
|
1718
|
+
})();
|
|
1719
|
+
return this.loadingPromises.set(e, i), i;
|
|
1720
|
+
}
|
|
1721
|
+
/**
|
|
1722
|
+
* Returns the fallback language.
|
|
1723
|
+
*/
|
|
1724
|
+
getFallbackLanguage() {
|
|
1725
|
+
return this.fallbackLang;
|
|
1726
|
+
}
|
|
1727
|
+
/**
|
|
1728
|
+
* Returns the currently active language.
|
|
1729
|
+
*/
|
|
1730
|
+
getLanguage() {
|
|
1731
|
+
return this.currentLang;
|
|
1732
|
+
}
|
|
1733
|
+
/** Dynamically adds a supported language (e.g. "fr", "de", "ar"). */
|
|
1734
|
+
addLanguage(e) {
|
|
1735
|
+
this.supportedLangs.has(e) || this.supportedLangs.add(e);
|
|
1736
|
+
}
|
|
1737
|
+
/**
|
|
1738
|
+
* Returns the list of supported languages.
|
|
1739
|
+
*/
|
|
1740
|
+
getSupportedLanguages() {
|
|
1741
|
+
return Array.from(this.supportedLangs);
|
|
1742
|
+
}
|
|
1743
|
+
/** Adds or merges translations for a given language. */
|
|
1744
|
+
setTranslations(e, t) {
|
|
1745
|
+
this.addLanguage(e), this.translations[e] = {
|
|
1746
|
+
...this.translations[e] || {},
|
|
1747
|
+
...t
|
|
1748
|
+
};
|
|
1749
|
+
}
|
|
1750
|
+
/**
|
|
1751
|
+
* Translates a key.
|
|
1752
|
+
* - Looks up the current language first.
|
|
1753
|
+
* - Falls back to the fallback language.
|
|
1754
|
+
* - Falls back to `fallback` param or the key itself if not found.
|
|
1755
|
+
*/
|
|
1756
|
+
t(e, t) {
|
|
1757
|
+
const i = this.currentLang, s = this.translations[i], n = this.translations[this.fallbackLang], a = (o, h) => h.split(".").reduce((l, p) => l == null ? void 0 : l[p], o);
|
|
1758
|
+
return s ? a(s, e) || a(n, e) || s[e] || t || e : (n == null ? void 0 : n[e]) || t || e;
|
|
1759
|
+
}
|
|
1760
|
+
/** Detects browser or document language. */
|
|
1761
|
+
detectLanguage() {
|
|
1762
|
+
const e = (document.documentElement.lang || document.body.lang || navigator.language || "en").split("-")[0].toLowerCase();
|
|
1763
|
+
return this.supportedLangs.has(e) && (this.currentLang = e), this.currentLang;
|
|
1764
|
+
}
|
|
1765
|
+
};
|
|
1766
|
+
u(pe, "instance", null);
|
|
1767
|
+
let Te = pe;
|
|
1768
|
+
const S = Te.getInstance(), V = class V {
|
|
1769
|
+
constructor(e) {
|
|
1770
|
+
u(this, "LOADING_HTML", '<span class="hintorium-loading">⏳ Loading...</span>');
|
|
1771
|
+
u(this, "ERROR_HTML", '<span class="hintorium-error">⚠️ Failed to load content</span>');
|
|
1772
|
+
u(this, "content");
|
|
1773
|
+
this.content = e;
|
|
1774
|
+
}
|
|
1775
|
+
/**
|
|
1776
|
+
* Render the tooltip content.
|
|
1777
|
+
* Supports string, HTMLElement, sync callback, or async callback.
|
|
1778
|
+
*/
|
|
1779
|
+
async render() {
|
|
1780
|
+
try {
|
|
1781
|
+
if (this.content instanceof HTMLElement)
|
|
1782
|
+
return this.content;
|
|
1783
|
+
if (typeof this.content == "string") {
|
|
1784
|
+
const i = S.t(this.content);
|
|
1785
|
+
return i ? this.renderString(i) : this.renderString(this.content);
|
|
1786
|
+
}
|
|
1787
|
+
let e = this.LOADING_HTML;
|
|
1788
|
+
const t = await this.resolveDynamicContent(this.content);
|
|
1789
|
+
return t instanceof HTMLElement ? e = t : e = await this.renderString(t), e;
|
|
1790
|
+
} catch {
|
|
1791
|
+
return this.ERROR_HTML;
|
|
1792
|
+
}
|
|
1793
|
+
}
|
|
1794
|
+
/**
|
|
1795
|
+
* Convert a string to HTML, treating it as Markdown
|
|
1796
|
+
* and then sanitizing it.
|
|
1797
|
+
*/
|
|
1798
|
+
async renderString(e) {
|
|
1799
|
+
const t = await b.parse(e);
|
|
1800
|
+
return this.sanitizeHTML(t);
|
|
1801
|
+
}
|
|
1802
|
+
/**
|
|
1803
|
+
* Resolves dynamic tooltip content (callback, promise, or URL fetch).
|
|
1804
|
+
*/
|
|
1805
|
+
async resolveDynamicContent(e) {
|
|
1806
|
+
let t;
|
|
1807
|
+
if (typeof e == "function") {
|
|
1808
|
+
const i = e();
|
|
1809
|
+
t = i instanceof Promise ? await i : i;
|
|
1810
|
+
} else
|
|
1811
|
+
t = e;
|
|
1812
|
+
if (typeof t == "string" && this.isURL(t)) {
|
|
1813
|
+
if (V.cache.has(t))
|
|
1814
|
+
return V.cache.get(t);
|
|
1815
|
+
try {
|
|
1816
|
+
const i = await fetch(t);
|
|
1817
|
+
if (!i.ok) throw new Error(`HTTP ${i.status}`);
|
|
1818
|
+
const s = await i.text(), n = await this.renderString(s);
|
|
1819
|
+
return V.cache.set(t, n), n;
|
|
1820
|
+
} catch {
|
|
1821
|
+
return this.ERROR_HTML;
|
|
1822
|
+
}
|
|
1823
|
+
}
|
|
1824
|
+
return t;
|
|
1825
|
+
}
|
|
1826
|
+
/**
|
|
1827
|
+
* Simple URL validator.
|
|
1828
|
+
*/
|
|
1829
|
+
isURL(e) {
|
|
1830
|
+
return /^https?:\/\//i.test(e);
|
|
1831
|
+
}
|
|
1832
|
+
/**
|
|
1833
|
+
* Sanitizes HTML string manually.
|
|
1834
|
+
* Removes <script>, <iframe>, <object>, <embed>, <link>, <meta>
|
|
1835
|
+
* and dangerous inline event handlers (onmouseover, onclick, etc.).
|
|
1836
|
+
*
|
|
1837
|
+
* @param html - Raw HTML to sanitize.
|
|
1838
|
+
* @returns Safe HTML string.
|
|
1839
|
+
*/
|
|
1840
|
+
sanitizeHTML(e) {
|
|
1841
|
+
const t = document.createElement("div");
|
|
1842
|
+
return t.innerHTML = e, [
|
|
1843
|
+
"script",
|
|
1844
|
+
"iframe",
|
|
1845
|
+
"object",
|
|
1846
|
+
"embed",
|
|
1847
|
+
"link",
|
|
1848
|
+
"meta"
|
|
1849
|
+
].forEach(
|
|
1850
|
+
(i) => t.querySelectorAll(i).forEach((s) => s.remove())
|
|
1851
|
+
), t.querySelectorAll("*").forEach((i) => {
|
|
1852
|
+
[...i.attributes].forEach((s) => {
|
|
1853
|
+
const n = s.name.toLowerCase();
|
|
1854
|
+
n.startsWith("on") && i.removeAttribute(s.name), ["srcdoc", "srcset", "formaction"].includes(n) && i.removeAttribute(s.name);
|
|
1855
|
+
});
|
|
1856
|
+
}), t.querySelectorAll("a, area, iframe").forEach((i) => {
|
|
1857
|
+
const s = i.getAttribute("href");
|
|
1858
|
+
s && s.trim().toLowerCase().startsWith("javascript:") && i.removeAttribute("href");
|
|
1859
|
+
}), t.innerHTML;
|
|
1860
|
+
}
|
|
1861
|
+
};
|
|
1862
|
+
u(V, "cache", /* @__PURE__ */ new Map());
|
|
1863
|
+
let we = V;
|
|
1864
|
+
const J = class J {
|
|
1865
|
+
/**
|
|
1866
|
+
* Positions a tooltip element relative to its trigger element.
|
|
1867
|
+
* Handles flipping and edge detection automatically.
|
|
1868
|
+
*
|
|
1869
|
+
* @param triggerElement - The element that triggers the tooltip.
|
|
1870
|
+
* @param tooltipElement - The tooltip element to be positioned.
|
|
1871
|
+
* @param position - Desired position ("top" | "bottom" | "left" | "right" | "auto").
|
|
1872
|
+
* @param offset - Distance in pixels between the trigger and the tooltip.
|
|
1873
|
+
* @param rtl - If direction is rtl or ltr.
|
|
1874
|
+
*/
|
|
1875
|
+
static position(e, t, i = "top", s, n = J.DEFAULT_OFFSET) {
|
|
1876
|
+
if (typeof window > "u" || !e || !t)
|
|
1877
|
+
return;
|
|
1878
|
+
const a = this.calculatePosition(
|
|
1879
|
+
e,
|
|
1880
|
+
t,
|
|
1881
|
+
i,
|
|
1882
|
+
n,
|
|
1883
|
+
s
|
|
1884
|
+
);
|
|
1885
|
+
t.style.top = `${a.top}px`, t.style.left = `${a.left}px`;
|
|
1886
|
+
}
|
|
1887
|
+
/**
|
|
1888
|
+
* Calculates the tooltip's top and left coordinates in the document.
|
|
1889
|
+
* Automatically flips the tooltip if it doesn't fit in the viewport.
|
|
1890
|
+
*/
|
|
1891
|
+
static calculatePosition(e, t, i, s, n) {
|
|
1892
|
+
const a = e.getBoundingClientRect();
|
|
1893
|
+
let o = t.getBoundingClientRect();
|
|
1894
|
+
const h = window.scrollX, l = window.scrollY, p = window.innerWidth, m = window.innerHeight, {
|
|
1895
|
+
top: c,
|
|
1896
|
+
left: f,
|
|
1897
|
+
bottom: d,
|
|
1898
|
+
right: T,
|
|
1899
|
+
width: L,
|
|
1900
|
+
height: $
|
|
1901
|
+
} = a;
|
|
1902
|
+
o = t.getBoundingClientRect();
|
|
1903
|
+
const P = o.width, I = o.height, _ = {
|
|
1904
|
+
top: c - s - this.VIEWPORT_PADDING,
|
|
1905
|
+
bottom: m - d - s - this.VIEWPORT_PADDING,
|
|
1906
|
+
left: f - s - this.VIEWPORT_PADDING,
|
|
1907
|
+
right: p - T - s - this.VIEWPORT_PADDING
|
|
1908
|
+
}, ie = {
|
|
1909
|
+
top: _.top >= I,
|
|
1910
|
+
bottom: _.bottom >= I,
|
|
1911
|
+
left: _.left >= P,
|
|
1912
|
+
right: _.right >= P
|
|
1913
|
+
};
|
|
1914
|
+
n && (i === "left" ? i = "right" : i === "right" && (i = "left"));
|
|
1915
|
+
let C = i;
|
|
1916
|
+
if (!ie[i]) {
|
|
1917
|
+
const nt = {
|
|
1918
|
+
top: ["bottom", "right", "left"],
|
|
1919
|
+
bottom: ["top", "right", "left"],
|
|
1920
|
+
left: ["right", "top", "bottom"],
|
|
1921
|
+
right: ["left", "top", "bottom"]
|
|
1922
|
+
};
|
|
1923
|
+
for (const De of nt[i])
|
|
1924
|
+
if (ie[De]) {
|
|
1925
|
+
C = De;
|
|
1926
|
+
break;
|
|
1927
|
+
}
|
|
1928
|
+
}
|
|
1929
|
+
const O = f + h + (L - P) / 2, Oe = c + l + ($ - I) / 2;
|
|
1930
|
+
let D = 0, M = 0;
|
|
1931
|
+
switch (C) {
|
|
1932
|
+
case "top":
|
|
1933
|
+
D = c + l - I - s, M = O;
|
|
1934
|
+
break;
|
|
1935
|
+
case "bottom":
|
|
1936
|
+
D = d + l + s, M = O;
|
|
1937
|
+
break;
|
|
1938
|
+
case "left":
|
|
1939
|
+
D = Oe, M = f + h - P - s;
|
|
1940
|
+
break;
|
|
1941
|
+
case "right":
|
|
1942
|
+
D = Oe, M = T + h + s;
|
|
1943
|
+
break;
|
|
1944
|
+
}
|
|
1945
|
+
D = Math.max(
|
|
1946
|
+
l + this.VIEWPORT_PADDING,
|
|
1947
|
+
Math.min(D, l + m - I - this.VIEWPORT_PADDING)
|
|
1948
|
+
), M = Math.max(
|
|
1949
|
+
h + this.VIEWPORT_PADDING,
|
|
1950
|
+
Math.min(M, h + p - P - this.VIEWPORT_PADDING)
|
|
1951
|
+
);
|
|
1952
|
+
const st = Math.max(
|
|
1953
|
+
10,
|
|
1954
|
+
Math.min(L / 2 + (f - M), P - 10)
|
|
1955
|
+
), rt = Math.max(
|
|
1956
|
+
10,
|
|
1957
|
+
Math.min($ / 2 + (c - D), I - 10)
|
|
1958
|
+
);
|
|
1959
|
+
return t.style.setProperty("--arrow-offset-x", `${st}px`), t.style.setProperty("--arrow-offset-y", `${rt}px`), t.setAttribute("data-position", C), t.setAttribute("dir", n ? "rtl" : "ltr"), { top: D, left: M, actualPosition: C };
|
|
1960
|
+
}
|
|
1961
|
+
};
|
|
1962
|
+
/** Default pixel offset between trigger and tooltip */
|
|
1963
|
+
u(J, "DEFAULT_OFFSET", g.DEFAULT.DEFAULT_OFFSET), /** Minimal padding from viewport edges (in px). */
|
|
1964
|
+
u(J, "VIEWPORT_PADDING", g.DEFAULT.VIEWPORT_PADDING);
|
|
1965
|
+
let xe = J;
|
|
1966
|
+
const y = class y {
|
|
1967
|
+
constructor(e, t, i) {
|
|
1968
|
+
u(this, "element");
|
|
1969
|
+
u(this, "contentManager");
|
|
1970
|
+
u(this, "tooltipEl", null);
|
|
1971
|
+
u(this, "options", {});
|
|
1972
|
+
u(this, "id");
|
|
1973
|
+
u(this, "listeners", /* @__PURE__ */ new Map());
|
|
1974
|
+
u(this, "outsideClickListener", null);
|
|
1975
|
+
u(this, "showTimeout", null);
|
|
1976
|
+
u(this, "rtl");
|
|
1977
|
+
u(this, "handleTooltipShow", () => this.show());
|
|
1978
|
+
u(this, "handleTooltipHide", () => this.hide());
|
|
1979
|
+
u(this, "handleTooltipToggle", () => this.tooltipEl ? this.hide() : this.show());
|
|
1980
|
+
u(this, "handleMouseEnter", () => {
|
|
1981
|
+
y.tourActive || this.show();
|
|
1982
|
+
});
|
|
1983
|
+
u(this, "handleMouseLeave", () => this.hide());
|
|
1984
|
+
u(this, "handleClick", () => {
|
|
1985
|
+
y.tourActive || (this.tooltipEl ? this.hide() : this.show());
|
|
1986
|
+
});
|
|
1987
|
+
this.element = e, this.rtl = this.detectRTL(), this.contentManager = new we(t), this.id = (i == null ? void 0 : i.id) ?? this.generateId(), i && (this.options = i), N.ensureFocusable(this.element, this.options), j.setupMobileSupport(this, this.element, this.options), this.setupListeners();
|
|
1988
|
+
}
|
|
1989
|
+
async createElement() {
|
|
1990
|
+
const e = document.createElement("div");
|
|
1991
|
+
e.id = this.id, e.classList.add(g.CSS_CLASSES.BASE), e.classList.add(
|
|
1992
|
+
this.options.theme || g.DEFAULT.THEME
|
|
1993
|
+
), this.rtl && (e.setAttribute("dir", "rtl"), e.classList.add(g.CSS_CLASSES.RTL));
|
|
1994
|
+
const t = document.createElement("div");
|
|
1995
|
+
t.classList.add(g.CSS_CLASSES.WRAPPER), this.options.isTour && t.classList.add(g.CSS_CLASSES.HINTORIUM_TOUR);
|
|
1996
|
+
const i = await this.contentManager.render();
|
|
1997
|
+
return typeof i == "string" ? t.innerHTML = i : t.appendChild(i), e.appendChild(t), e.setAttribute("data-position", this.options.position || "top"), e;
|
|
1998
|
+
}
|
|
1999
|
+
generateId() {
|
|
2000
|
+
return `${g.DEFAULT.ID_PREFIX}${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
|
|
2001
|
+
}
|
|
2002
|
+
setupAccessibility() {
|
|
2003
|
+
this.tooltipEl && N.setupTooltipAccessibility(
|
|
2004
|
+
this.tooltipEl,
|
|
2005
|
+
this.element,
|
|
2006
|
+
this.options
|
|
2007
|
+
);
|
|
2008
|
+
}
|
|
2009
|
+
setupListeners() {
|
|
2010
|
+
const e = {
|
|
2011
|
+
mouseenter: this.handleMouseEnter,
|
|
2012
|
+
mouseleave: this.options.sticky ? () => {
|
|
2013
|
+
} : this.handleMouseLeave,
|
|
2014
|
+
// 👈 ignore mouseleave if sticky
|
|
2015
|
+
focus: this.handleMouseEnter,
|
|
2016
|
+
blur: this.options.sticky ? () => {
|
|
2017
|
+
} : this.handleMouseLeave,
|
|
2018
|
+
"tooltip:show": this.handleTooltipShow,
|
|
2019
|
+
"tooltip:hide": this.handleTooltipHide,
|
|
2020
|
+
"tooltip:toggle": this.handleTooltipToggle
|
|
2021
|
+
};
|
|
2022
|
+
this.options.sticky && (this.element.addEventListener("click", this.handleClick), this.listeners.set("click", this.handleClick)), Object.entries(e).forEach(([t, i]) => {
|
|
2023
|
+
this.element.addEventListener(t, i), this.listeners.set(t, i);
|
|
2024
|
+
});
|
|
2025
|
+
}
|
|
2026
|
+
removeListeners() {
|
|
2027
|
+
this.listeners.forEach((e, t) => {
|
|
2028
|
+
this.element.removeEventListener(t, e);
|
|
2029
|
+
}), this.listeners.clear();
|
|
2030
|
+
}
|
|
2031
|
+
async show() {
|
|
2032
|
+
if (y.activeTooltip && y.activeTooltip !== this && await y.activeTooltip.hide(), y.activeTooltip = this, this.tooltipEl) return;
|
|
2033
|
+
const e = this.options.delay ?? 0;
|
|
2034
|
+
if (e > 0)
|
|
2035
|
+
return new Promise((t) => {
|
|
2036
|
+
this.showTimeout = window.setTimeout(async () => {
|
|
2037
|
+
this.showTimeout = null, await this.showTooltip(), t();
|
|
2038
|
+
}, e);
|
|
2039
|
+
});
|
|
2040
|
+
await this.showTooltip();
|
|
2041
|
+
}
|
|
2042
|
+
async showTooltip() {
|
|
2043
|
+
var e, t, i;
|
|
2044
|
+
this.tooltipEl = await this.createElement(), this.setupAccessibility(), this.options.onInjectContent && this.options.onInjectContent(this.tooltipEl), document.body.appendChild(this.tooltipEl), xe.position(
|
|
2045
|
+
this.element,
|
|
2046
|
+
this.tooltipEl,
|
|
2047
|
+
this.options.position,
|
|
2048
|
+
this.rtl
|
|
2049
|
+
), K.increment(this.id), (t = (e = this.options).onShow) == null || t.call(e, this.id), (i = this.options.a11y) != null && i.announceOnShow && N.announceToScreenReader(
|
|
2050
|
+
`Tooltip shown: ${this.element.textContent}`
|
|
2051
|
+
), this.options.sticky && this.addOutsideClickListener(), await ze.show(this.tooltipEl, this.options.animation);
|
|
2052
|
+
}
|
|
2053
|
+
addOutsideClickListener() {
|
|
2054
|
+
this.outsideClickListener = (e) => {
|
|
2055
|
+
var i;
|
|
2056
|
+
const t = e.target;
|
|
2057
|
+
(i = this.tooltipEl) != null && i.contains(t) || this.element.contains(t) || this.hide();
|
|
2058
|
+
}, document.addEventListener("mousedown", this.outsideClickListener), document.addEventListener("touchstart", this.outsideClickListener);
|
|
2059
|
+
}
|
|
2060
|
+
async hide() {
|
|
2061
|
+
var e, t;
|
|
2062
|
+
if (this.showTimeout) {
|
|
2063
|
+
clearTimeout(this.showTimeout), this.showTimeout = null;
|
|
2064
|
+
return;
|
|
2065
|
+
}
|
|
2066
|
+
if (this.tooltipEl)
|
|
2067
|
+
try {
|
|
2068
|
+
await ze.hide(this.tooltipEl), (t = (e = this.tooltipEl) == null ? void 0 : e.parentNode) == null || t.removeChild(this.tooltipEl);
|
|
2069
|
+
} catch (i) {
|
|
2070
|
+
console.warn("[Hintorium Tooltip] Error hiding tooltip:", i);
|
|
2071
|
+
} finally {
|
|
2072
|
+
this.tooltipEl = null, y.activeTooltip === this && (y.activeTooltip = null);
|
|
2073
|
+
}
|
|
2074
|
+
}
|
|
2075
|
+
/**
|
|
2076
|
+
* Detect if RTL is enabled.
|
|
2077
|
+
*/
|
|
2078
|
+
detectRTL() {
|
|
2079
|
+
var i;
|
|
2080
|
+
if (this.options.rtl) return this.options.rtl;
|
|
2081
|
+
const e = this.element.dir || document.documentElement.dir || document.body.dir;
|
|
2082
|
+
if (e) return e.toLowerCase() === "rtl";
|
|
2083
|
+
const t = ((i = document.documentElement.lang) == null ? void 0 : i.toLowerCase()) ?? "";
|
|
2084
|
+
return ["ar", "he", "fa", "ur"].some((s) => t.startsWith(s));
|
|
2085
|
+
}
|
|
2086
|
+
isRTL() {
|
|
2087
|
+
return this.rtl;
|
|
2088
|
+
}
|
|
2089
|
+
destroy() {
|
|
2090
|
+
this.hide(), this.tooltipEl && N.removeTooltipAccessibility(
|
|
2091
|
+
this.tooltipEl,
|
|
2092
|
+
this.element
|
|
2093
|
+
), this.removeListeners();
|
|
2094
|
+
}
|
|
2095
|
+
};
|
|
2096
|
+
u(y, "activeTooltip", null), u(y, "tourActive", !1);
|
|
2097
|
+
let U = y;
|
|
2098
|
+
class W {
|
|
2099
|
+
/**
|
|
2100
|
+
* Checks if the provided NodeList contains at least one valid tooltip element.
|
|
2101
|
+
* @param elements - List of elements to validate.
|
|
2102
|
+
* @returns True if at least one element exists, false otherwise.
|
|
2103
|
+
*/
|
|
2104
|
+
static isValidTooltipElements(e) {
|
|
2105
|
+
const t = e.length > 0;
|
|
2106
|
+
return t || console.warn(
|
|
2107
|
+
`⚠️ No valid tooltip elements found. Please ensure elements have the correct data attribute to initialize tooltip - (${g.ATTRIBUTES.TOOLTIP}).`
|
|
2108
|
+
), t;
|
|
2109
|
+
}
|
|
2110
|
+
/**
|
|
2111
|
+
* Validates that the element has tooltip content.
|
|
2112
|
+
* @param element - The HTML element to check.
|
|
2113
|
+
* @returns True if the element has non-empty tooltip content, false otherwise.
|
|
2114
|
+
*/
|
|
2115
|
+
static hasValidTooltipContent(e, t) {
|
|
2116
|
+
const i = !!t && t.trim().length > 0;
|
|
2117
|
+
return i || console.warn(
|
|
2118
|
+
"⚠️ Tooltip element missing content: ",
|
|
2119
|
+
e,
|
|
2120
|
+
`Please provide a non-empty ${g.ATTRIBUTES.TOOLTIP} attribute.`
|
|
2121
|
+
), i;
|
|
2122
|
+
}
|
|
2123
|
+
/**
|
|
2124
|
+
* Validates whether the provided animation string is a supported tooltip animation.
|
|
2125
|
+
*
|
|
2126
|
+
* Logs a console warning if the animation is invalid or unsupported.
|
|
2127
|
+
*
|
|
2128
|
+
* @param theme - The raw animation string to validate.
|
|
2129
|
+
* @param element - The HTML element associated with the tooltip, used for contextual logging.
|
|
2130
|
+
* @returns {theme is TooltipAnimation} `true` if the animation is valid, otherwise `false`.
|
|
2131
|
+
*/
|
|
2132
|
+
static validateAnimation(e, t) {
|
|
2133
|
+
const i = [
|
|
2134
|
+
"fade",
|
|
2135
|
+
"slide",
|
|
2136
|
+
"zoom",
|
|
2137
|
+
"bounce"
|
|
2138
|
+
], s = i.includes(e);
|
|
2139
|
+
return s || console.warn(
|
|
2140
|
+
`⚠️ Invalid tooltip animation: "${e}" for element`,
|
|
2141
|
+
t,
|
|
2142
|
+
`
|
|
2143
|
+
Valid animations are: ${i.join(", ")}.`
|
|
2144
|
+
), s;
|
|
2145
|
+
}
|
|
2146
|
+
/**
|
|
2147
|
+
* Validates the delay value for a tooltip.
|
|
2148
|
+
* Ensures that the provided value is a finite number and non-negative.
|
|
2149
|
+
*
|
|
2150
|
+
* Logs a console warning if the value is invalid.
|
|
2151
|
+
*
|
|
2152
|
+
* @param delay - The raw delay value (string from data attribute or number from options).
|
|
2153
|
+
* @param element - The HTML element associated with the tooltip, used for logging.
|
|
2154
|
+
* @returns A valid number delay (>= 0). Falls back to 0 if invalid.
|
|
2155
|
+
*/
|
|
2156
|
+
static validateDelay(e, t) {
|
|
2157
|
+
if (e == null) return 0;
|
|
2158
|
+
const i = typeof e == "number" ? e : Number(e);
|
|
2159
|
+
return Number.isNaN(i) || i < 0 ? (console.warn(
|
|
2160
|
+
`⚠️ Invalid tooltip delay "${e}" on element`,
|
|
2161
|
+
t,
|
|
2162
|
+
`
|
|
2163
|
+
Delay must be a non-negative number in milliseconds. Falling back to 0.`
|
|
2164
|
+
), 0) : i;
|
|
2165
|
+
}
|
|
2166
|
+
/**
|
|
2167
|
+
* Validates whether the provided theme string is a supported tooltip theme.
|
|
2168
|
+
*
|
|
2169
|
+
* Logs a console warning if the theme is invalid or unsupported.
|
|
2170
|
+
*
|
|
2171
|
+
* @param theme - The raw theme string to validate (e.g. "light", "dark").
|
|
2172
|
+
* @param element - The HTML element associated with the tooltip, used for contextual logging.
|
|
2173
|
+
* @returns {theme is TooltipTheme} `true` if the theme is valid, otherwise `false`.
|
|
2174
|
+
*/
|
|
2175
|
+
static validateTheme(e, t) {
|
|
2176
|
+
const i = [
|
|
2177
|
+
"light",
|
|
2178
|
+
"dark",
|
|
2179
|
+
"glass",
|
|
2180
|
+
"pastel",
|
|
2181
|
+
"neon",
|
|
2182
|
+
"gradient"
|
|
2183
|
+
], s = i.includes(e);
|
|
2184
|
+
return s || console.warn(
|
|
2185
|
+
`⚠️ Invalid tooltip theme: "${e}" for element`,
|
|
2186
|
+
t,
|
|
2187
|
+
`
|
|
2188
|
+
Valid themes are: ${i.join(", ")}.`
|
|
2189
|
+
), s;
|
|
2190
|
+
}
|
|
2191
|
+
/**
|
|
2192
|
+
* Checks if a given position string is a valid TooltipPosition.
|
|
2193
|
+
* Logs a warning if invalid.
|
|
2194
|
+
*
|
|
2195
|
+
* @param position - Raw position string to validate.
|
|
2196
|
+
* @returns True if position is valid, false otherwise.
|
|
2197
|
+
*/
|
|
2198
|
+
static validatePosition(e, t) {
|
|
2199
|
+
if (!e) return !1;
|
|
2200
|
+
const i = Me.includes(
|
|
2201
|
+
e
|
|
2202
|
+
);
|
|
2203
|
+
return i || console.warn(
|
|
2204
|
+
`Invalid tooltip position : ${e} for element`,
|
|
2205
|
+
t,
|
|
2206
|
+
`
|
|
2207
|
+
Valid positions are : ${Me.join(", ")}`
|
|
2208
|
+
), i;
|
|
2209
|
+
}
|
|
2210
|
+
/**
|
|
2211
|
+
* Returns a valid tooltip position, falling back to default if invalid.
|
|
2212
|
+
*
|
|
2213
|
+
* @param raw - Raw position string.
|
|
2214
|
+
* @param element - The HTML element to check.
|
|
2215
|
+
* @param defaultPosition - Default position to use if raw is invalid.
|
|
2216
|
+
* @returns Valid TooltipPosition.
|
|
2217
|
+
*/
|
|
2218
|
+
static getValidPosition(e, t, i = "top") {
|
|
2219
|
+
return e && this.validatePosition(e, t) ? e : i;
|
|
2220
|
+
}
|
|
2221
|
+
/**
|
|
2222
|
+
* Returns a valid tooltip theme, falling back to default if invalid.
|
|
2223
|
+
*
|
|
2224
|
+
* @param raw - Raw theme string.
|
|
2225
|
+
* @param element - The HTML element to check.
|
|
2226
|
+
* @param defaultPosition - Default theme to use if raw is invalid.
|
|
2227
|
+
* @returns Valid TooltipTheme.
|
|
2228
|
+
*/
|
|
2229
|
+
static getValidTheme(e, t, i = "dark") {
|
|
2230
|
+
return e && this.validateTheme(e, t) ? e : i;
|
|
2231
|
+
}
|
|
2232
|
+
/**
|
|
2233
|
+
* Returns a valid tooltip animation, falling back to default if invalid.
|
|
2234
|
+
*
|
|
2235
|
+
* @param raw - Raw animation string.
|
|
2236
|
+
* @param element - The HTML element to check.
|
|
2237
|
+
* @param defaultAnimation - Default animation to use if raw is invalid.
|
|
2238
|
+
* @returns Valid TooltipAnimation.
|
|
2239
|
+
*/
|
|
2240
|
+
static getValidAnimation(e, t, i = "fade") {
|
|
2241
|
+
return e && this.validateAnimation(e, t) ? e : i;
|
|
2242
|
+
}
|
|
2243
|
+
}
|
|
2244
|
+
const F = class F {
|
|
2245
|
+
constructor(e) {
|
|
2246
|
+
u(this, "options", {});
|
|
2247
|
+
u(this, "tooltips", /* @__PURE__ */ new Map());
|
|
2248
|
+
u(this, "isInitialized", !1);
|
|
2249
|
+
this.options = {
|
|
2250
|
+
...e
|
|
2251
|
+
};
|
|
2252
|
+
}
|
|
2253
|
+
/**
|
|
2254
|
+
* Returns the single instance of TooltipManager (Singleton pattern).
|
|
2255
|
+
*/
|
|
2256
|
+
static getInstance() {
|
|
2257
|
+
return F.instance || (F.instance = new F()), F.instance;
|
|
2258
|
+
}
|
|
2259
|
+
/**
|
|
2260
|
+
* Initializes all tooltips found in the DOM that contain the tooltip attribute.
|
|
2261
|
+
* Also sets up global listeners for touch devices and initializes accessibility support.
|
|
2262
|
+
*/
|
|
2263
|
+
init() {
|
|
2264
|
+
return this.isInitialized ? this : (this.isInitialized = !0, N.init(), this.registerGlobalTouchListener(), this.initializeAllTooltips(), B.initFromDOM(), this);
|
|
2265
|
+
}
|
|
2266
|
+
/**
|
|
2267
|
+
* Creates and registers a new tooltip instance for the given element.
|
|
2268
|
+
*
|
|
2269
|
+
* If a tooltip already exists for the same element, it will be removed
|
|
2270
|
+
* and replaced with a new instance. This ensures that each element has
|
|
2271
|
+
* at most one active tooltip at any given time.
|
|
2272
|
+
*
|
|
2273
|
+
* The provided options are merged with both global manager defaults
|
|
2274
|
+
* and tooltip-level overrides to ensure consistent configuration.
|
|
2275
|
+
*
|
|
2276
|
+
* @param {HTMLElement} element - The target element to which the tooltip is bound.
|
|
2277
|
+
* @param {string} content - The text or HTML content displayed inside the tooltip.
|
|
2278
|
+
* @param {TooltipOptions} [options] - Optional configuration overrides for this tooltip.
|
|
2279
|
+
* @returns {Tooltip} The newly created {@link Tooltip} instance.
|
|
2280
|
+
*
|
|
2281
|
+
* @example
|
|
2282
|
+
* const manager = TooltipManager.getInstance();
|
|
2283
|
+
* const button = document.querySelector('#save');
|
|
2284
|
+
* manager.add(button, 'Click to save your progress', { position: 'bottom' });
|
|
2285
|
+
*/
|
|
2286
|
+
add(e, t, i) {
|
|
2287
|
+
this.tooltips.has(e) && this.remove(e);
|
|
2288
|
+
const s = {
|
|
2289
|
+
...this.options,
|
|
2290
|
+
...i
|
|
2291
|
+
}, n = new U(e, t, s);
|
|
2292
|
+
return this.tooltips.set(e, n), n;
|
|
2293
|
+
}
|
|
2294
|
+
/**
|
|
2295
|
+
* Removes and destroys an existing tooltip associated with a specific element.
|
|
2296
|
+
*
|
|
2297
|
+
* This method ensures full cleanup by calling the tooltip’s internal `destroy()`
|
|
2298
|
+
* method, removing mobile-related listeners via {@link MobileManager.cleanup},
|
|
2299
|
+
* and deleting the reference from the manager’s internal Map.
|
|
2300
|
+
*
|
|
2301
|
+
* @param {HTMLElement} element - The element whose tooltip should be removed.
|
|
2302
|
+
*
|
|
2303
|
+
* @example
|
|
2304
|
+
* const button = document.querySelector('#save');
|
|
2305
|
+
* tooltipManager.remove(button);
|
|
2306
|
+
*/
|
|
2307
|
+
remove(e) {
|
|
2308
|
+
if (!e) return;
|
|
2309
|
+
const t = this.tooltips.get(e);
|
|
2310
|
+
t && (t.destroy(), j.cleanup(e), this.tooltips.delete(e));
|
|
2311
|
+
}
|
|
2312
|
+
/**
|
|
2313
|
+
* Extracts and normalizes tooltip configuration options from a given HTML element.
|
|
2314
|
+
*
|
|
2315
|
+
* This method reads tooltip-related attributes from the target element (such as
|
|
2316
|
+
* position, theme, and animation), validates them using {@link TooltipValidator},
|
|
2317
|
+
* and merges them with global and default configuration values.
|
|
2318
|
+
*
|
|
2319
|
+
* Additionally, mobile-specific behavior is automatically resolved via
|
|
2320
|
+
* {@link MobileManager.resolveMobileOptions}, which determines whether mobile
|
|
2321
|
+
* support should be enabled based on the current environment and user-provided options.
|
|
2322
|
+
*
|
|
2323
|
+
* The resulting configuration object ensures consistent, validated tooltip behavior
|
|
2324
|
+
* across all initialization methods (attribute-based and programmatic).
|
|
2325
|
+
*
|
|
2326
|
+
* @private
|
|
2327
|
+
* @param {HTMLElement} element - The target element containing tooltip attributes.
|
|
2328
|
+
* @returns {TooltipOptions} A fully merged and validated tooltip configuration object.
|
|
2329
|
+
*
|
|
2330
|
+
* @example
|
|
2331
|
+
* // Example element markup:
|
|
2332
|
+
* // <button data-tooltip="Hello" data-tooltip-position="bottom" data-tooltip-theme="dark"></button>
|
|
2333
|
+
*
|
|
2334
|
+
* const options = tooltipManager['extractOptions'](buttonEl);
|
|
2335
|
+
* // Returns something like:
|
|
2336
|
+
* // {
|
|
2337
|
+
* // position: "bottom",
|
|
2338
|
+
* // theme: "dark",
|
|
2339
|
+
* // animation: "fade",
|
|
2340
|
+
* // mobile: { enabled: true, longPress: true, touchDelay: 300 },
|
|
2341
|
+
* // ...
|
|
2342
|
+
* // }
|
|
2343
|
+
*/
|
|
2344
|
+
extractOptions(e) {
|
|
2345
|
+
const t = e.getAttribute(
|
|
2346
|
+
g.ATTRIBUTES.TOOLTIP_POSITION
|
|
2347
|
+
), i = e.getAttribute(
|
|
2348
|
+
g.ATTRIBUTES.TOOLTIP_THEME
|
|
2349
|
+
), s = e.getAttribute(
|
|
2350
|
+
g.ATTRIBUTES.TOOLTIP_ANIMATION
|
|
2351
|
+
), n = e.getAttribute(
|
|
2352
|
+
g.ATTRIBUTES.TOOLTIP_DELAY
|
|
2353
|
+
);
|
|
2354
|
+
return {
|
|
2355
|
+
position: t ? W.getValidPosition(t, e) : this.options.position ?? g.DEFAULT.POSITION,
|
|
2356
|
+
theme: i ? W.getValidTheme(i, e) : this.options.theme ?? g.DEFAULT.THEME,
|
|
2357
|
+
animation: s ? W.getValidAnimation(s, e) : this.options.animation ?? g.DEFAULT.ANIMATION,
|
|
2358
|
+
mobile: this.options.mobile !== void 0 ? j.resolveMobileOptions(this.options.mobile) : {},
|
|
2359
|
+
delay: n ? W.validateDelay(n, e) : this.options.delay ?? g.DEFAULT.DELAY
|
|
2360
|
+
};
|
|
2361
|
+
}
|
|
2362
|
+
/**
|
|
2363
|
+
* Initializes a single tooltip element from the DOM.
|
|
2364
|
+
*/
|
|
2365
|
+
initializeTooltip(e) {
|
|
2366
|
+
const t = e.getAttribute(g.ATTRIBUTES.TOOLTIP);
|
|
2367
|
+
if (!W.hasValidTooltipContent(e, t)) return;
|
|
2368
|
+
const i = this.extractOptions(e);
|
|
2369
|
+
this.add(e, t, i);
|
|
2370
|
+
}
|
|
2371
|
+
/**
|
|
2372
|
+
* Initializes tooltips for all DOM elements that contain the tooltip attribute.
|
|
2373
|
+
*/
|
|
2374
|
+
initializeAllTooltips() {
|
|
2375
|
+
const e = document.querySelectorAll(
|
|
2376
|
+
`[${g.ATTRIBUTES.TOOLTIP}]`
|
|
2377
|
+
);
|
|
2378
|
+
W.isValidTooltipElements(e) && e.forEach((t) => {
|
|
2379
|
+
this.initializeTooltip(t);
|
|
2380
|
+
});
|
|
2381
|
+
}
|
|
2382
|
+
/**
|
|
2383
|
+
* Registers a global event listener that hides mobile tooltips when tapping outside.
|
|
2384
|
+
*/
|
|
2385
|
+
registerGlobalTouchListener() {
|
|
2386
|
+
document.addEventListener("touchstart", (e) => {
|
|
2387
|
+
e.target instanceof HTMLElement && (Array.from(this.tooltips.values()).map(
|
|
2388
|
+
(t) => t.element
|
|
2389
|
+
).includes(e.target) || j.hideMobileTooltips());
|
|
2390
|
+
});
|
|
2391
|
+
}
|
|
2392
|
+
};
|
|
2393
|
+
u(F, "instance");
|
|
2394
|
+
let ee = F;
|
|
2395
|
+
function jt(r) {
|
|
2396
|
+
return console.info("🎨 Hintorium Tooltip Library Loaded!"), new ee(r).init();
|
|
2397
|
+
}
|
|
2398
|
+
const Zt = JSON.parse(
|
|
2399
|
+
JSON.stringify({
|
|
2400
|
+
hintorium: {
|
|
2401
|
+
tour: {
|
|
2402
|
+
next: "Next →",
|
|
2403
|
+
done: "Done",
|
|
2404
|
+
prev: "← Back"
|
|
2405
|
+
}
|
|
2406
|
+
}
|
|
2407
|
+
})
|
|
2408
|
+
), Yt = JSON.parse(
|
|
2409
|
+
JSON.stringify({
|
|
2410
|
+
hintorium: {
|
|
2411
|
+
tour: {
|
|
2412
|
+
next: "Następny →",
|
|
2413
|
+
done: "Gotowe",
|
|
2414
|
+
prev: "← Wstecz"
|
|
2415
|
+
}
|
|
2416
|
+
}
|
|
2417
|
+
})
|
|
2418
|
+
);
|
|
2419
|
+
class Xt {
|
|
2420
|
+
constructor({ steps: e, localStorageKey: t, auto: i }) {
|
|
2421
|
+
u(this, "steps", []);
|
|
2422
|
+
u(this, "current", 0);
|
|
2423
|
+
u(this, "activeTooltip", null);
|
|
2424
|
+
u(this, "storage", null);
|
|
2425
|
+
u(this, "completedTour", !1);
|
|
2426
|
+
/**
|
|
2427
|
+
* Tour state keys (localStorage)
|
|
2428
|
+
*/
|
|
2429
|
+
u(this, "tourProgress", "hintorium_tour_progress");
|
|
2430
|
+
u(this, "tourCompleted", "hintorium_tour_completed");
|
|
2431
|
+
u(this, "tourStorageKey");
|
|
2432
|
+
/**
|
|
2433
|
+
* Auto play
|
|
2434
|
+
*/
|
|
2435
|
+
u(this, "autoPlay", !1);
|
|
2436
|
+
u(this, "autoPlayDelay", 3e3);
|
|
2437
|
+
// default 3s
|
|
2438
|
+
u(this, "autoPlayTimeout", null);
|
|
2439
|
+
u(this, "progressBar");
|
|
2440
|
+
u(this, "autoPlayStartTime", 0);
|
|
2441
|
+
u(this, "autoPlayAnimationFrame", null);
|
|
2442
|
+
this.steps = e, t && (this.storage = oe.getInstance(t), this.tourStorageKey = t), i != null && i.enabled && (this.autoPlay = !0), i != null && i.delay && (this.autoPlayDelay = i.delay), this.registerDefaultTranslations(), this.initializeState();
|
|
2443
|
+
}
|
|
2444
|
+
registerDefaultTranslations() {
|
|
2445
|
+
S.setTranslations("en", Zt), S.setTranslations("pl", Yt);
|
|
2446
|
+
}
|
|
2447
|
+
initializeState() {
|
|
2448
|
+
if (!this.storage || !this.tourStorageKey) return;
|
|
2449
|
+
if (this.storage.get(
|
|
2450
|
+
`${this.tourStorageKey}-${this.tourCompleted}`,
|
|
2451
|
+
!1
|
|
2452
|
+
)) {
|
|
2453
|
+
this.completedTour = !0;
|
|
2454
|
+
return;
|
|
2455
|
+
}
|
|
2456
|
+
const e = this.storage.get(
|
|
2457
|
+
`${this.tourStorageKey}-${this.tourProgress}`,
|
|
2458
|
+
0
|
|
2459
|
+
);
|
|
2460
|
+
e && (this.current = e);
|
|
2461
|
+
}
|
|
2462
|
+
start() {
|
|
2463
|
+
this.steps.length && (this.completedTour || (U.tourActive = !0, this.showStep(this.current)));
|
|
2464
|
+
}
|
|
2465
|
+
startProgressBarAnimation() {
|
|
2466
|
+
if (!this.progressBar || !this.autoPlay) return;
|
|
2467
|
+
this.autoPlayStartTime = Date.now();
|
|
2468
|
+
const e = () => {
|
|
2469
|
+
const t = Date.now() - this.autoPlayStartTime, i = Math.min(t / this.autoPlayDelay, 1);
|
|
2470
|
+
this.progressBar.style.width = `${i * 100}%`, i < 1 ? this.autoPlayAnimationFrame = requestAnimationFrame(e) : (this.autoPlayAnimationFrame = null, this.current === this.steps.length - 1 ? this.finish() : this.next());
|
|
2471
|
+
};
|
|
2472
|
+
this.autoPlayAnimationFrame && cancelAnimationFrame(this.autoPlayAnimationFrame), this.autoPlayAnimationFrame = requestAnimationFrame(e);
|
|
2473
|
+
}
|
|
2474
|
+
async showStep(e) {
|
|
2475
|
+
if (e < 0 || e >= this.steps.length) return;
|
|
2476
|
+
this.activeTooltip && (this.activeTooltip.hide(), this.activeTooltip = null);
|
|
2477
|
+
const t = this.steps[e], i = document.querySelector(t.target);
|
|
2478
|
+
if (!i) return;
|
|
2479
|
+
const s = new U(i, t.content, {
|
|
2480
|
+
...t.options,
|
|
2481
|
+
sticky: !0,
|
|
2482
|
+
isTour: !0,
|
|
2483
|
+
onInjectContent: (n) => {
|
|
2484
|
+
this.createNavigation(n), this.createProgressBar(n);
|
|
2485
|
+
}
|
|
2486
|
+
});
|
|
2487
|
+
this.activeTooltip = s, await s.show(), this.autoPlay && (this.clearAutoPlay(), this.startProgressBarAnimation());
|
|
2488
|
+
}
|
|
2489
|
+
clearAutoPlay() {
|
|
2490
|
+
this.autoPlayTimeout && (clearTimeout(this.autoPlayTimeout), this.autoPlayTimeout = null), this.autoPlayAnimationFrame && (cancelAnimationFrame(this.autoPlayAnimationFrame), this.autoPlayAnimationFrame = null);
|
|
2491
|
+
}
|
|
2492
|
+
createProgressBar(e) {
|
|
2493
|
+
const t = document.createElement("div");
|
|
2494
|
+
t.className = "hintorium-tour-progress-bar-wrapper";
|
|
2495
|
+
const i = e.querySelector(
|
|
2496
|
+
`.${g.CSS_CLASSES.WRAPPER}`
|
|
2497
|
+
);
|
|
2498
|
+
if (!i) return;
|
|
2499
|
+
const s = document.createElement("div");
|
|
2500
|
+
s.className = "hintorium-tour-progress-bar-fill", t.appendChild(s), i.appendChild(t), this.progressBar = s, this.autoPlay && this.startProgressBarAnimation();
|
|
2501
|
+
}
|
|
2502
|
+
createNavigation(e) {
|
|
2503
|
+
const t = document.createElement("div");
|
|
2504
|
+
t.className = "hintorium-tour-nav";
|
|
2505
|
+
const i = e.querySelector(
|
|
2506
|
+
`.${g.CSS_CLASSES.WRAPPER}`
|
|
2507
|
+
);
|
|
2508
|
+
if (!i) return;
|
|
2509
|
+
const s = this.current === 0, n = this.current === this.steps.length - 1;
|
|
2510
|
+
t.innerHTML = `
|
|
2511
|
+
<div class="hintorium-tour-progress">
|
|
2512
|
+
<span class="hintorium-tour-step">${this.current + 1}</span>
|
|
2513
|
+
<span class="hintorium-tour-separator">/</span>
|
|
2514
|
+
<span class="hintorium-tour-total">${this.steps.length}</span>
|
|
2515
|
+
</div>
|
|
2516
|
+
<div class="hintorium-tour-buttons">
|
|
2517
|
+
<button class= "hintorium-tour-btn hintorium-tour-prev" ${s ? "disabled" : ""}>
|
|
2518
|
+
${S.t("hintorium.tour.prev")}
|
|
2519
|
+
</button>
|
|
2520
|
+
${n ? `<button class="hintorium-tour-btn hintorium-tour-done">${S.t(
|
|
2521
|
+
"hintorium.tour.done"
|
|
2522
|
+
)}</button>` : `<button class="hintorium-tour-btn hintorium-tour-next">${S.t(
|
|
2523
|
+
"hintorium.tour.next"
|
|
2524
|
+
)}</button>`}
|
|
2525
|
+
</div>
|
|
2526
|
+
`;
|
|
2527
|
+
const a = t.querySelector(
|
|
2528
|
+
".hintorium-tour-prev"
|
|
2529
|
+
), o = t.querySelector(
|
|
2530
|
+
".hintorium-tour-next"
|
|
2531
|
+
), h = t.querySelector(
|
|
2532
|
+
".hintorium-tour-done"
|
|
2533
|
+
);
|
|
2534
|
+
a == null || a.addEventListener("click", this.prev.bind(this)), o == null || o.addEventListener("click", this.next.bind(this)), h == null || h.addEventListener("click", this.finish.bind(this)), i.appendChild(t);
|
|
2535
|
+
}
|
|
2536
|
+
prev() {
|
|
2537
|
+
this.current > 0 && (this.clearAutoPlay(), this.current--, this.showStep(this.current), this.saveProgress());
|
|
2538
|
+
}
|
|
2539
|
+
next() {
|
|
2540
|
+
this.current < this.steps.length - 1 && (this.clearAutoPlay(), this.current++, this.showStep(this.current), this.saveProgress());
|
|
2541
|
+
}
|
|
2542
|
+
finish() {
|
|
2543
|
+
this.clearAutoPlay(), this.activeTooltip && (this.activeTooltip.hide(), this.activeTooltip.destroy(), this.activeTooltip = null), this.current = 0, this.markCompleted();
|
|
2544
|
+
}
|
|
2545
|
+
saveProgress() {
|
|
2546
|
+
this.storage && this.storage.set(
|
|
2547
|
+
`${this.tourStorageKey}-${this.tourProgress}`,
|
|
2548
|
+
this.current
|
|
2549
|
+
);
|
|
2550
|
+
}
|
|
2551
|
+
markCompleted() {
|
|
2552
|
+
!this.storage || !this.tourStorageKey || (this.storage.set(`${this.tourStorageKey}-${this.tourCompleted}`, !0), this.storage.remove(`${this.tourStorageKey}-${this.tourProgress}`));
|
|
2553
|
+
}
|
|
2554
|
+
resetProgress() {
|
|
2555
|
+
!this.storage || !this.tourStorageKey || (this.current = 0, this.storage.remove(`${this.tourStorageKey}-${this.tourProgress}`), this.storage.remove(`${this.tourStorageKey}-${this.tourCompleted}`));
|
|
2556
|
+
}
|
|
2557
|
+
}
|
|
2558
|
+
const tt = lt(null);
|
|
2559
|
+
function Ce() {
|
|
2560
|
+
return ct(tt);
|
|
2561
|
+
}
|
|
2562
|
+
function Qt(r) {
|
|
2563
|
+
const e = R(null), t = R(!1);
|
|
2564
|
+
return z(() => {
|
|
2565
|
+
if (!t.current) {
|
|
2566
|
+
try {
|
|
2567
|
+
e.current = jt(r), t.current = !0;
|
|
2568
|
+
} catch (i) {
|
|
2569
|
+
console.error(
|
|
2570
|
+
"[hintorium-react] Failed to initialize TooltipManager:",
|
|
2571
|
+
i
|
|
2572
|
+
);
|
|
2573
|
+
}
|
|
2574
|
+
return () => {
|
|
2575
|
+
t.current = !1, e.current = null;
|
|
2576
|
+
};
|
|
2577
|
+
}
|
|
2578
|
+
}, []), e.current;
|
|
2579
|
+
}
|
|
2580
|
+
function ri({
|
|
2581
|
+
children: r,
|
|
2582
|
+
options: e = {},
|
|
2583
|
+
initManager: t = !0
|
|
2584
|
+
}) {
|
|
2585
|
+
return t && Qt(e), /* @__PURE__ */ ye(tt.Provider, { value: { options: e }, children: r });
|
|
2586
|
+
}
|
|
2587
|
+
function it(r) {
|
|
2588
|
+
return w(
|
|
2589
|
+
(e) => (t) => {
|
|
2590
|
+
e == null || e(t), r != null && r.id && K.increment(r.id);
|
|
2591
|
+
},
|
|
2592
|
+
[r == null ? void 0 : r.id]
|
|
2593
|
+
);
|
|
2594
|
+
}
|
|
2595
|
+
function Jt(r, e) {
|
|
2596
|
+
const t = Ce(), i = R(null), s = R(null), n = it(e), a = w(() => {
|
|
2597
|
+
i.current && (i.current.destroy(), i.current = null);
|
|
2598
|
+
}, []), o = w(
|
|
2599
|
+
(h) => {
|
|
2600
|
+
if (a(), !h || e != null && e.disabled) {
|
|
2601
|
+
s.current = null;
|
|
2602
|
+
return;
|
|
2603
|
+
}
|
|
2604
|
+
s.current = h;
|
|
2605
|
+
const l = {
|
|
2606
|
+
...t == null ? void 0 : t.options,
|
|
2607
|
+
...e,
|
|
2608
|
+
onShow: n(e == null ? void 0 : e.onShow)
|
|
2609
|
+
};
|
|
2610
|
+
try {
|
|
2611
|
+
i.current = new U(h, r, l);
|
|
2612
|
+
} catch (p) {
|
|
2613
|
+
throw p;
|
|
2614
|
+
}
|
|
2615
|
+
},
|
|
2616
|
+
[r, e, t, a]
|
|
2617
|
+
);
|
|
2618
|
+
return z(() => a, [a]), o;
|
|
2619
|
+
}
|
|
2620
|
+
function ni(r, e) {
|
|
2621
|
+
const t = Ce(), i = R(null), s = R(null), n = it(e), a = w(() => {
|
|
2622
|
+
i.current && (i.current.destroy(), i.current = null);
|
|
2623
|
+
}, []), o = w(
|
|
2624
|
+
(h) => {
|
|
2625
|
+
if (a(), !h || e != null && e.disabled) {
|
|
2626
|
+
s.current = null;
|
|
2627
|
+
return;
|
|
2628
|
+
}
|
|
2629
|
+
s.current = h;
|
|
2630
|
+
const l = {
|
|
2631
|
+
...t == null ? void 0 : t.options,
|
|
2632
|
+
...e,
|
|
2633
|
+
onShow: n(e == null ? void 0 : e.onShow)
|
|
2634
|
+
};
|
|
2635
|
+
try {
|
|
2636
|
+
i.current = new U(h, r, l);
|
|
2637
|
+
} catch (p) {
|
|
2638
|
+
throw p;
|
|
2639
|
+
}
|
|
2640
|
+
},
|
|
2641
|
+
[r, e, t, a]
|
|
2642
|
+
);
|
|
2643
|
+
return z(() => a, [a]), {
|
|
2644
|
+
ref: o,
|
|
2645
|
+
tooltip: i.current
|
|
2646
|
+
};
|
|
2647
|
+
}
|
|
2648
|
+
function oi({
|
|
2649
|
+
content: r,
|
|
2650
|
+
children: e,
|
|
2651
|
+
className: t,
|
|
2652
|
+
disabled: i,
|
|
2653
|
+
...s
|
|
2654
|
+
}) {
|
|
2655
|
+
const n = typeof r == "string" ? r : String(r), a = Jt(n, { ...s, disabled: i });
|
|
2656
|
+
if (!ht(e))
|
|
2657
|
+
return console.error(
|
|
2658
|
+
"[hintorium-react] Tooltip children must be a valid React element"
|
|
2659
|
+
), /* @__PURE__ */ ye(qe, { children: e });
|
|
2660
|
+
const o = e;
|
|
2661
|
+
return ut(o, {
|
|
2662
|
+
ref: a,
|
|
2663
|
+
className: t ? `${o.props.className || ""} ${t}`.trim() : o.props.className
|
|
2664
|
+
});
|
|
2665
|
+
}
|
|
2666
|
+
function ei(r) {
|
|
2667
|
+
const e = Ce(), t = R(null), [i, s] = ne(0), [n, a] = ne(!1);
|
|
2668
|
+
z(() => {
|
|
2669
|
+
if (r.length === 0) return;
|
|
2670
|
+
const c = r.map((f) => ({
|
|
2671
|
+
target: typeof f.element == "string" ? f.element : "",
|
|
2672
|
+
content: typeof f.content == "string" ? f.content : String(f.content),
|
|
2673
|
+
options: {
|
|
2674
|
+
...e == null ? void 0 : e.options,
|
|
2675
|
+
...f.options,
|
|
2676
|
+
isTour: !0
|
|
2677
|
+
}
|
|
2678
|
+
}));
|
|
2679
|
+
try {
|
|
2680
|
+
t.current = new Xt({
|
|
2681
|
+
steps: c
|
|
2682
|
+
});
|
|
2683
|
+
} catch (f) {
|
|
2684
|
+
console.error("[hintorium-react] Failed to create tour:", f);
|
|
2685
|
+
}
|
|
2686
|
+
return () => {
|
|
2687
|
+
t.current && (t.current.finish(), t.current = null);
|
|
2688
|
+
};
|
|
2689
|
+
}, [r, e]);
|
|
2690
|
+
const o = w(() => {
|
|
2691
|
+
if (t.current)
|
|
2692
|
+
try {
|
|
2693
|
+
t.current.start(), a(!0), s(0);
|
|
2694
|
+
} catch (c) {
|
|
2695
|
+
console.error("[hintorium-react] Failed to start tour:", c);
|
|
2696
|
+
}
|
|
2697
|
+
}, []), h = w(() => {
|
|
2698
|
+
if (t.current)
|
|
2699
|
+
try {
|
|
2700
|
+
t.current.finish(), a(!1), s(0);
|
|
2701
|
+
} catch (c) {
|
|
2702
|
+
console.error("[hintorium-react] Failed to stop tour:", c);
|
|
2703
|
+
}
|
|
2704
|
+
}, []), l = w(() => {
|
|
2705
|
+
if (!(!t.current || !n))
|
|
2706
|
+
try {
|
|
2707
|
+
t.current.next(), s((c) => Math.min(c + 1, r.length - 1));
|
|
2708
|
+
} catch (c) {
|
|
2709
|
+
console.error("[hintorium-react] Failed to go to next step:", c);
|
|
2710
|
+
}
|
|
2711
|
+
}, [n, r.length]), p = w(() => {
|
|
2712
|
+
if (!(!t.current || !n))
|
|
2713
|
+
try {
|
|
2714
|
+
t.current.prev(), s((c) => Math.max(c - 1, 0));
|
|
2715
|
+
} catch (c) {
|
|
2716
|
+
console.error("[hintorium-react] Failed to go to previous step:", c);
|
|
2717
|
+
}
|
|
2718
|
+
}, [n]), m = w(
|
|
2719
|
+
(c) => {
|
|
2720
|
+
if (!t.current || !n || c < 0 || c >= r.length) return;
|
|
2721
|
+
const f = c - i;
|
|
2722
|
+
if (f > 0)
|
|
2723
|
+
for (let d = 0; d < f; d++)
|
|
2724
|
+
t.current.next();
|
|
2725
|
+
else if (f < 0)
|
|
2726
|
+
for (let d = 0; d < Math.abs(f); d++)
|
|
2727
|
+
t.current.prev();
|
|
2728
|
+
s(c);
|
|
2729
|
+
},
|
|
2730
|
+
[n, i, r.length]
|
|
2731
|
+
);
|
|
2732
|
+
return {
|
|
2733
|
+
start: o,
|
|
2734
|
+
stop: h,
|
|
2735
|
+
next: l,
|
|
2736
|
+
prev: p,
|
|
2737
|
+
goTo: m,
|
|
2738
|
+
currentStep: i,
|
|
2739
|
+
isActive: n
|
|
2740
|
+
};
|
|
2741
|
+
}
|
|
2742
|
+
function ai({ steps: r, children: e }) {
|
|
2743
|
+
const t = ei(r);
|
|
2744
|
+
return /* @__PURE__ */ ye(qe, { children: e(t) });
|
|
2745
|
+
}
|
|
2746
|
+
function li() {
|
|
2747
|
+
const [r, e] = ne(S.getLanguage());
|
|
2748
|
+
return z(() => {
|
|
2749
|
+
S.detectLanguage(), e(S.getLanguage());
|
|
2750
|
+
}, []), {
|
|
2751
|
+
language: r,
|
|
2752
|
+
setLanguage: (s) => {
|
|
2753
|
+
S.setLanguage(s), e(s);
|
|
2754
|
+
},
|
|
2755
|
+
t: (s, n) => S.t(s, n),
|
|
2756
|
+
supportedLanguages: S.getSupportedLanguages()
|
|
2757
|
+
};
|
|
2758
|
+
}
|
|
2759
|
+
function ci() {
|
|
2760
|
+
const [r, e] = ne({}), t = w(() => {
|
|
2761
|
+
e(K.getAll());
|
|
2762
|
+
}, []);
|
|
2763
|
+
z(() => {
|
|
2764
|
+
t();
|
|
2765
|
+
}, [t]);
|
|
2766
|
+
const i = w(
|
|
2767
|
+
(a) => {
|
|
2768
|
+
K.increment(a), t();
|
|
2769
|
+
},
|
|
2770
|
+
[t]
|
|
2771
|
+
), s = w((a) => K.getCount(a), []), n = w(() => {
|
|
2772
|
+
K.resetAll(), t();
|
|
2773
|
+
}, [t]);
|
|
2774
|
+
return {
|
|
2775
|
+
data: r,
|
|
2776
|
+
getCount: s,
|
|
2777
|
+
increment: i,
|
|
2778
|
+
resetAll: n,
|
|
2779
|
+
refresh: t
|
|
2780
|
+
};
|
|
2781
|
+
}
|
|
2782
|
+
function hi(r) {
|
|
2783
|
+
const e = R(null), t = w(() => {
|
|
2784
|
+
e.current && (e.current.destroy(), e.current = null);
|
|
2785
|
+
}, []), i = w(
|
|
2786
|
+
(s) => {
|
|
2787
|
+
if (t(), !!s)
|
|
2788
|
+
try {
|
|
2789
|
+
e.current = new B(s, r);
|
|
2790
|
+
} catch (n) {
|
|
2791
|
+
console.error("[hintorium-react] Failed to create inline hint:", n);
|
|
2792
|
+
}
|
|
2793
|
+
},
|
|
2794
|
+
[r, t]
|
|
2795
|
+
);
|
|
2796
|
+
return z(() => t, [t]), i;
|
|
2797
|
+
}
|
|
2798
|
+
function ui() {
|
|
2799
|
+
const r = R(!1);
|
|
2800
|
+
z(() => {
|
|
2801
|
+
if (!r.current)
|
|
2802
|
+
try {
|
|
2803
|
+
B.initFromDOM(), r.current = !0;
|
|
2804
|
+
} catch (e) {
|
|
2805
|
+
console.error("[hintorium-react] Failed to initialize inline hints:", e);
|
|
2806
|
+
}
|
|
2807
|
+
}, []);
|
|
2808
|
+
}
|
|
2809
|
+
export {
|
|
2810
|
+
K as Analytics,
|
|
2811
|
+
S as I18n,
|
|
2812
|
+
oi as Tooltip,
|
|
2813
|
+
ri as TooltipProvider,
|
|
2814
|
+
ai as Tour,
|
|
2815
|
+
ci as useAnalytics,
|
|
2816
|
+
li as useHintoriumI18n,
|
|
2817
|
+
hi as useInlineHint,
|
|
2818
|
+
ui as useInlineHintManager,
|
|
2819
|
+
Jt as useTooltip,
|
|
2820
|
+
it as useTooltipAnalytics,
|
|
2821
|
+
Ce as useTooltipContext,
|
|
2822
|
+
ni as useTooltipInstance,
|
|
2823
|
+
Qt as useTooltipManager,
|
|
2824
|
+
ei as useTour
|
|
2825
|
+
};
|
|
2826
|
+
//# sourceMappingURL=index.js.map
|