diff --git a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/TipTapEditor.vue b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/TipTapEditor.vue
index 405f7654de..321b40743d 100644
--- a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/TipTapEditor.vue
+++ b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/TipTapEditor.vue
@@ -1,8 +1,71 @@
-
-
+
openCreateModal({ targetElement: target })"
+ @insert-link="linkHandler.openLinkEditor()"
+ @insert-math="target => mathHandler.openCreateMathModal({ targetElement: target })"
+ />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -10,23 +73,79 @@
+
+
+
diff --git a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/components/image/ImageNodeView.vue b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/components/image/ImageNodeView.vue
new file mode 100644
index 0000000000..0e16eb11d4
--- /dev/null
+++ b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/components/image/ImageNodeView.vue
@@ -0,0 +1,279 @@
+
+
+
+
+
![]()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/components/image/ImageUploadModal.vue b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/components/image/ImageUploadModal.vue
new file mode 100644
index 0000000000..1d5cc39ddb
--- /dev/null
+++ b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/components/image/ImageUploadModal.vue
@@ -0,0 +1,511 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ uploadWarning }}
+
+
+ {{ fileName }}
+
+
+
+
![]()
+
+
+
+
+
+ {{ altTextDescription$() }}
+
+
+
+
+
+ {{ imageDropZoneText$() }}
+
+ {{ supportedFileTypes$() }}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/components/link/LinkBubbleMenu.vue b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/components/link/LinkBubbleMenu.vue
new file mode 100644
index 0000000000..4746dd2174
--- /dev/null
+++ b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/components/link/LinkBubbleMenu.vue
@@ -0,0 +1,172 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/components/link/LinkEditor.vue b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/components/link/LinkEditor.vue
new file mode 100644
index 0000000000..2171a8cf84
--- /dev/null
+++ b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/components/link/LinkEditor.vue
@@ -0,0 +1,256 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/components/math/FormulasMenu.vue b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/components/math/FormulasMenu.vue
new file mode 100644
index 0000000000..aa5683bdae
--- /dev/null
+++ b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/components/math/FormulasMenu.vue
@@ -0,0 +1,421 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/components/math/FormulasStrings.js b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/components/math/FormulasStrings.js
new file mode 100644
index 0000000000..65b9d2df03
--- /dev/null
+++ b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/components/math/FormulasStrings.js
@@ -0,0 +1,744 @@
+import { createTranslator } from 'shared/i18n';
+
+const NAMESPACE = 'FormulasStrings';
+
+const MESSAGES = {
+ // Category titles
+ formulasCategory: {
+ message: 'Formulas',
+ context: 'Category title for formula symbols',
+ },
+ linesCategory: {
+ message: 'Lines',
+ context: 'Category title for line symbols',
+ },
+ basicCategory: {
+ message: 'Basic',
+ context: 'Category title for basic math symbols',
+ },
+ advancedCategory: {
+ message: 'Advanced',
+ context: 'Category title for advanced math symbols',
+ },
+ logicCategory: {
+ message: 'Logic',
+ context: 'Category title for logic symbols',
+ },
+ geometryCategory: {
+ message: 'Geometry',
+ context: 'Category title for geometry symbols',
+ },
+ setsCategory: {
+ message: 'Sets',
+ context: 'Category title for set theory symbols',
+ },
+ directionalCategory: {
+ message: 'Directional',
+ context: 'Category title for directional symbols',
+ },
+ charactersCategory: {
+ message: 'Characters',
+ context: 'Category title for Greek characters',
+ },
+ miscellaneousCategory: {
+ message: 'Miscellaneous',
+ context: 'Category title for miscellaneous symbols',
+ },
+
+ // Formula symbols
+ superscript: {
+ message: 'Superscript',
+ context: 'Title for superscript symbol',
+ },
+ subscript: {
+ message: 'Subscript',
+ context: 'Title for subscript symbol',
+ },
+ fraction: {
+ message: 'Fraction',
+ context: 'Title for fraction symbol',
+ },
+ binomialCoefficient: {
+ message: 'Binomial coefficient',
+ context: 'Title for binomial coefficient symbol',
+ },
+ sum: {
+ message: 'Sum',
+ context: 'Title for sum symbol',
+ },
+ product: {
+ message: 'Product',
+ context: 'Title for product symbol',
+ },
+ coproduct: {
+ message: 'Coproduct',
+ context: 'Title for coproduct symbol',
+ },
+ integral: {
+ message: 'Integral',
+ context: 'Title for integral symbol',
+ },
+
+ // Lines symbols
+ squareRoot: {
+ message: 'Square root',
+ context: 'Title for square root symbol',
+ },
+ bar: {
+ message: 'Bar',
+ context: 'Title for bar symbol',
+ },
+ underline: {
+ message: 'Underline',
+ context: 'Title for underline symbol',
+ },
+ leftArrow: {
+ message: 'Left arrow',
+ context: 'Title for left arrow symbol',
+ },
+ rightArrow: {
+ message: 'Right arrow',
+ context: 'Title for right arrow symbol',
+ },
+ vector: {
+ message: 'Vector',
+ context: 'Title for vector symbol',
+ },
+
+ // Basic symbols
+ addition: {
+ message: 'Addition',
+ context: 'Title for addition symbol',
+ },
+ subtraction: {
+ message: 'Subtraction',
+ context: 'Title for subtraction symbol',
+ },
+ multiplication: {
+ message: 'Multiplication',
+ context: 'Title for multiplication symbol',
+ },
+ division: {
+ message: 'Division',
+ context: 'Title for division symbol',
+ },
+ dot: {
+ message: 'Dot',
+ context: 'Title for dot symbol',
+ },
+ negation: {
+ message: 'Negation',
+ context: 'Title for negation symbol',
+ },
+ plusMinus: {
+ message: 'Plus-minus',
+ context: 'Title for plus-minus symbol',
+ },
+ minusPlus: {
+ message: 'Minus-plus',
+ context: 'Title for minus-plus symbol',
+ },
+ doesNotEqual: {
+ message: 'Does not equal',
+ context: 'Title for does not equal symbol',
+ },
+ approximately: {
+ message: 'Approximately',
+ context: 'Title for approximately symbol',
+ },
+ proportional: {
+ message: 'Proportional',
+ context: 'Title for proportional symbol',
+ },
+ definition: {
+ message: 'Definition',
+ context: 'Title for definition symbol',
+ },
+ greaterThan: {
+ message: 'Greater than',
+ context: 'Title for greater than symbol',
+ },
+ greaterThanOrEqual: {
+ message: 'Greater than or equal to',
+ context: 'Title for greater than or equal symbol',
+ },
+ notGreaterThan: {
+ message: 'Not greater than',
+ context: 'Title for not greater than symbol',
+ },
+ significantlyGreaterThan: {
+ message: 'Significantly greater than',
+ context: 'Title for significantly greater than symbol',
+ },
+ lessThan: {
+ message: 'Less than',
+ context: 'Title for less than symbol',
+ },
+ lessThanOrEqual: {
+ message: 'Less than or equal to',
+ context: 'Title for less than or equal symbol',
+ },
+ notLessThan: {
+ message: 'Not less than',
+ context: 'Title for not less than symbol',
+ },
+ significantlyLessThan: {
+ message: 'Significantly less than',
+ context: 'Title for significantly less than symbol',
+ },
+ leftCeiling: {
+ message: 'Left ceiling',
+ context: 'Title for left ceiling symbol',
+ },
+ leftFloor: {
+ message: 'Left floor',
+ context: 'Title for left floor symbol',
+ },
+ rightCeiling: {
+ message: 'Right ceiling',
+ context: 'Title for right ceiling symbol',
+ },
+ rightFloor: {
+ message: 'Right floor',
+ context: 'Title for right floor symbol',
+ },
+
+ // Advanced symbols
+ tensorProduct: {
+ message: 'Tensor product',
+ context: 'Title for tensor product symbol',
+ },
+ contourIntegral: {
+ message: 'Contour integral',
+ context: 'Title for contour integral symbol',
+ },
+ nabla: {
+ message: 'Nabla',
+ context: 'Title for nabla symbol',
+ },
+ conjugate: {
+ message: 'Conjugate',
+ context: 'Title for conjugate symbol',
+ },
+ conjugateTranspose: {
+ message: 'Conjugate transpose',
+ context: 'Title for conjugate transpose symbol',
+ },
+ partial: {
+ message: 'Partial',
+ context: 'Title for partial symbol',
+ },
+ wedgeProduct: {
+ message: 'Wedge product',
+ context: 'Title for wedge product symbol',
+ },
+ infinity: {
+ message: 'Infinity',
+ context: 'Title for infinity symbol',
+ },
+ topElement: {
+ message: 'Top element',
+ context: 'Title for top element symbol',
+ },
+ reducibleTo: {
+ message: 'Reducible to',
+ context: 'Title for reducible to symbol',
+ },
+ nondominatedBy: {
+ message: 'Nondominated by',
+ context: 'Title for nondominated by symbol',
+ },
+
+ // Logic symbols
+ and: {
+ message: 'And',
+ context: 'Title for and symbol',
+ },
+ or: {
+ message: 'Or',
+ context: 'Title for or symbol',
+ },
+ ifAndOnlyIf: {
+ message: 'If and only if',
+ context: 'Title for if and only if symbol',
+ },
+ entails: {
+ message: 'Entails',
+ context: 'Title for entails symbol',
+ },
+ implies: {
+ message: 'Implies',
+ context: 'Title for implies symbol',
+ },
+ givenThat: {
+ message: 'Given that/Such that',
+ context: 'Title for given that symbol',
+ },
+ exists: {
+ message: 'Exists',
+ context: 'Title for exists symbol',
+ },
+ forAll: {
+ message: 'For all',
+ context: 'Title for for all symbol',
+ },
+ because: {
+ message: 'Because',
+ context: 'Title for because symbol',
+ },
+ therefore: {
+ message: 'Therefore',
+ context: 'Title for therefore symbol',
+ },
+ qed: {
+ message: 'QED',
+ context: 'Title for QED symbol',
+ },
+ exclusiveOr: {
+ message: 'Exclusive or',
+ context: 'Title for exclusive or symbol',
+ },
+
+ // Geometry symbols
+ degrees: {
+ message: 'Degrees',
+ context: 'Title for degrees symbol',
+ },
+ angle: {
+ message: 'Angle',
+ context: 'Title for angle symbol',
+ },
+ measuredAngle: {
+ message: 'Measured angle',
+ context: 'Title for measured angle symbol',
+ },
+ parallel: {
+ message: 'Parallel',
+ context: 'Title for parallel symbol',
+ },
+ perpendicular: {
+ message: 'Perpendicular',
+ context: 'Title for perpendicular symbol',
+ },
+ incomparableTo: {
+ message: 'Incomparable to',
+ context: 'Title for incomparable to symbol',
+ },
+ similarTo: {
+ message: 'Similar to',
+ context: 'Title for similar to symbol',
+ },
+ similarOrEqual: {
+ message: 'Similar or equal to',
+ context: 'Title for similar or equal symbol',
+ },
+ congruentTo: {
+ message: 'Congruent to',
+ context: 'Title for congruent to symbol',
+ },
+
+ // Sets symbols
+ ellipsis: {
+ message: 'Ellipsis',
+ context: 'Title for ellipsis symbol',
+ },
+ ellipsisVertical: {
+ message: 'Ellipsis (vertical)',
+ context: 'Title for vertical ellipsis symbol',
+ },
+ ellipsisCentered: {
+ message: 'Ellipsis (centered)',
+ context: 'Title for centered ellipsis symbol',
+ },
+ ellipsisDiagonal: {
+ message: 'Ellipsis (diagonal)',
+ context: 'Title for diagonal ellipsis symbol',
+ },
+ cardinality: {
+ message: 'Cardinality',
+ context: 'Title for cardinality symbol',
+ },
+ intersection: {
+ message: 'Intersection',
+ context: 'Title for intersection symbol',
+ },
+ union: {
+ message: 'Union',
+ context: 'Title for union symbol',
+ },
+ emptySet: {
+ message: 'Empty set',
+ context: 'Title for empty set symbol',
+ },
+ in: {
+ message: 'In',
+ context: 'Title for in symbol',
+ },
+ notIn: {
+ message: 'Not in',
+ context: 'Title for not in symbol',
+ },
+ contains: {
+ message: 'Contains',
+ context: 'Title for contains symbol',
+ },
+ symmetricDifference: {
+ message: 'Symmetric difference',
+ context: 'Title for symmetric difference symbol',
+ },
+ setDifference: {
+ message: 'Set difference',
+ context: 'Title for set difference symbol',
+ },
+ subset: {
+ message: 'Subset',
+ context: 'Title for subset symbol',
+ },
+ subsetOrEqual: {
+ message: 'Subset or equal',
+ context: 'Title for subset or equal symbol',
+ },
+ notSubsetOrEqual: {
+ message: 'Not a subset or equal',
+ context: 'Title for not subset or equal symbol',
+ },
+ superset: {
+ message: 'Superset',
+ context: 'Title for superset symbol',
+ },
+ supersetOrEqual: {
+ message: 'Superset or equal',
+ context: 'Title for superset or equal symbol',
+ },
+ notSupersetOrEqual: {
+ message: 'Not a superset or equal',
+ context: 'Title for not superset or equal symbol',
+ },
+ wreathProduct: {
+ message: 'Wreath product',
+ context: 'Title for wreath product symbol',
+ },
+ naturalJoin: {
+ message: 'Natural join',
+ context: 'Title for natural join symbol',
+ },
+
+ // Directional symbols
+ down: {
+ message: 'Down',
+ context: 'Title for down arrow symbol',
+ },
+ downDouble: {
+ message: 'Down (double)',
+ context: 'Title for double down arrow symbol',
+ },
+ triangleDown: {
+ message: 'Triangle down',
+ context: 'Title for triangle down symbol',
+ },
+ up: {
+ message: 'Up',
+ context: 'Title for up arrow symbol',
+ },
+ upDouble: {
+ message: 'Up (double)',
+ context: 'Title for double up arrow symbol',
+ },
+ triangleUp: {
+ message: 'Triangle up',
+ context: 'Title for triangle up symbol',
+ },
+ upDown: {
+ message: 'Up-down',
+ context: 'Title for up-down arrow symbol',
+ },
+ upDownDouble: {
+ message: 'Up-down (double)',
+ context: 'Title for double up-down arrow symbol',
+ },
+ left: {
+ message: 'Left',
+ context: 'Title for left arrow symbol',
+ },
+ leftDouble: {
+ message: 'Left (double)',
+ context: 'Title for double left arrow symbol',
+ },
+ leftLong: {
+ message: 'Left (long)',
+ context: 'Title for long left arrow symbol',
+ },
+ leftLongDouble: {
+ message: 'Left (long, double)',
+ context: 'Title for long double left arrow symbol',
+ },
+ leftHooked: {
+ message: 'Left (hooked)',
+ context: 'Title for hooked left arrow symbol',
+ },
+ leftHarpoonDown: {
+ message: 'Left (harpoon down)',
+ context: 'Title for left harpoon down symbol',
+ },
+ leftHarpoonUp: {
+ message: 'Left (harpoon up)',
+ context: 'Title for left harpoon up symbol',
+ },
+ right: {
+ message: 'Right',
+ context: 'Title for right arrow symbol',
+ },
+ rightDouble: {
+ message: 'Right (double)',
+ context: 'Title for double right arrow symbol',
+ },
+ rightLong: {
+ message: 'Right (long)',
+ context: 'Title for long right arrow symbol',
+ },
+ rightLongDouble: {
+ message: 'Right (long, double)',
+ context: 'Title for long double right arrow symbol',
+ },
+ rightHooked: {
+ message: 'Right (hooked)',
+ context: 'Title for hooked right arrow symbol',
+ },
+ rightHarpoonDown: {
+ message: 'Right (harpoon down)',
+ context: 'Title for right harpoon down symbol',
+ },
+ rightHarpoonUp: {
+ message: 'Right (harpoon up)',
+ context: 'Title for right harpoon up symbol',
+ },
+ leftRight: {
+ message: 'Left-right',
+ context: 'Title for left-right arrow symbol',
+ },
+ leftRightDouble: {
+ message: 'Left-right (double)',
+ context: 'Title for double left-right arrow symbol',
+ },
+ leftRightLong: {
+ message: 'Left-right (long)',
+ context: 'Title for long left-right arrow symbol',
+ },
+ leftRightLongDouble: {
+ message: 'Left-right (long, double)',
+ context: 'Title for long double left-right arrow symbol',
+ },
+ northeast: {
+ message: 'Northeast',
+ context: 'Title for northeast arrow symbol',
+ },
+ northwest: {
+ message: 'Northwest',
+ context: 'Title for northwest arrow symbol',
+ },
+ southeast: {
+ message: 'Southeast',
+ context: 'Title for southeast arrow symbol',
+ },
+ southwest: {
+ message: 'Southwest',
+ context: 'Title for southwest arrow symbol',
+ },
+
+ // Greek characters
+ alpha: {
+ message: 'alpha',
+ context: 'Title for alpha character',
+ },
+ beta: {
+ message: 'beta',
+ context: 'Title for beta character',
+ },
+ chi: {
+ message: 'chi',
+ context: 'Title for chi character',
+ },
+ delta: {
+ message: 'delta',
+ context: 'Title for delta character',
+ },
+ deltaCapital: {
+ message: 'Delta',
+ context: 'Title for capital Delta character',
+ },
+ digamma: {
+ message: 'digamma',
+ context: 'Title for digamma character',
+ },
+ ell: {
+ message: 'ell',
+ context: 'Title for ell character',
+ },
+ epsilon: {
+ message: 'epsilon',
+ context: 'Title for epsilon character',
+ },
+ eta: {
+ message: 'eta',
+ context: 'Title for eta character',
+ },
+ gamma: {
+ message: 'gamma',
+ context: 'Title for gamma character',
+ },
+ gammaCapital: {
+ message: 'Gamma',
+ context: 'Title for capital Gamma character',
+ },
+ planckConstant: {
+ message: "Planck's constant",
+ context: 'Title for Planck constant character',
+ },
+ iota: {
+ message: 'iota',
+ context: 'Title for iota character',
+ },
+ kappa: {
+ message: 'kappa',
+ context: 'Title for kappa character',
+ },
+ lambda: {
+ message: 'lambda',
+ context: 'Title for lambda character',
+ },
+ lambdaCapital: {
+ message: 'Lambda',
+ context: 'Title for capital Lambda character',
+ },
+ mu: {
+ message: 'mu',
+ context: 'Title for mu character',
+ },
+ nu: {
+ message: 'nu',
+ context: 'Title for nu character',
+ },
+ omega: {
+ message: 'omega',
+ context: 'Title for omega character',
+ },
+ omegaCapital: {
+ message: 'Omega',
+ context: 'Title for capital Omega character',
+ },
+ phi: {
+ message: 'phi',
+ context: 'Title for phi character',
+ },
+ phiCapital: {
+ message: 'Phi',
+ context: 'Title for capital Phi character',
+ },
+ pi: {
+ message: 'pi',
+ context: 'Title for pi character',
+ },
+ piCapital: {
+ message: 'Pi',
+ context: 'Title for capital Pi character',
+ },
+ psi: {
+ message: 'psi',
+ context: 'Title for psi character',
+ },
+ psiCapital: {
+ message: 'Psi',
+ context: 'Title for capital Psi character',
+ },
+ rho: {
+ message: 'rho',
+ context: 'Title for rho character',
+ },
+ sigma: {
+ message: 'sigma',
+ context: 'Title for sigma character',
+ },
+ sigmaCapital: {
+ message: 'Sigma',
+ context: 'Title for capital Sigma character',
+ },
+ tau: {
+ message: 'tau',
+ context: 'Title for tau character',
+ },
+ theta: {
+ message: 'theta',
+ context: 'Title for theta character',
+ },
+ thetaCapital: {
+ message: 'Theta',
+ context: 'Title for capital Theta character',
+ },
+ upsilon: {
+ message: 'upsilon',
+ context: 'Title for upsilon character',
+ },
+ upsilonCapital: {
+ message: 'Upsilon',
+ context: 'Title for capital Upsilon character',
+ },
+ pWeierstrass: {
+ message: 'P',
+ context: 'Title for Weierstrass P character',
+ },
+ xi: {
+ message: 'xi',
+ context: 'Title for xi character',
+ },
+ xiCapital: {
+ message: 'Xi',
+ context: 'Title for capital Xi character',
+ },
+ zeta: {
+ message: 'zeta',
+ context: 'Title for zeta character',
+ },
+
+ // Miscellaneous symbols
+ circle: {
+ message: 'Circle',
+ context: 'Title for circle symbol',
+ },
+ club: {
+ message: 'Club',
+ context: 'Title for club symbol',
+ },
+ diamond: {
+ message: 'Diamond',
+ context: 'Title for diamond symbol',
+ },
+ heart: {
+ message: 'Heart',
+ context: 'Title for heart symbol',
+ },
+ spade: {
+ message: 'Spade',
+ context: 'Title for spade symbol',
+ },
+ flat: {
+ message: 'Flat',
+ context: 'Title for flat symbol',
+ },
+ natural: {
+ message: 'Natural',
+ context: 'Title for natural symbol',
+ },
+ sharp: {
+ message: 'Sharp',
+ context: 'Title for sharp symbol',
+ },
+};
+
+let FormulasStrings = null;
+
+export function getFormulasStrings() {
+ if (!FormulasStrings) {
+ FormulasStrings = createTranslator(NAMESPACE, MESSAGES);
+ }
+ return FormulasStrings;
+}
diff --git a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/components/math/MathNodeView.vue b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/components/math/MathNodeView.vue
new file mode 100644
index 0000000000..8dc4dc6df5
--- /dev/null
+++ b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/components/math/MathNodeView.vue
@@ -0,0 +1,90 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/components/math/symbols.json b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/components/math/symbols.json
new file mode 100644
index 0000000000..b1d683de1a
--- /dev/null
+++ b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/components/math/symbols.json
@@ -0,0 +1,277 @@
+[
+ {
+ "titleKey": "formulasCategory",
+ "symbols": [
+ {
+ "key": "^",
+ "preview": "{a}^{b}",
+ "titleKey": "superscript",
+ "template": "\\placeholder{}^{\\placeholder{}}"
+ },
+ {
+ "key": "_",
+ "preview": "{a}_{b}",
+ "titleKey": "subscript",
+ "template": "\\placeholder{}_{\\placeholder{}}"
+ },
+ {
+ "key": "\\frac",
+ "preview": "\\frac{a}{b}",
+ "titleKey": "fraction",
+ "template": "\\frac{\\placeholder{}}{\\placeholder{}}"
+ },
+ {
+ "key": "\\binom",
+ "preview": "(\\binom{_b}{^a})",
+ "titleKey": "binomialCoefficient",
+ "template": "\\binom{\\placeholder{}}{\\placeholder{}}"
+ },
+ {
+ "key": "\\sum",
+ "preview": "\\sum_{i=0}^{n}x_{i}",
+ "titleKey": "sum",
+ "template": "\\sum_{\\placeholder{}}^{\\placeholder{}}\\placeholder{}"
+ },
+ {
+ "key": "\\prod",
+ "preview": "\\prod_b^a",
+ "titleKey": "product",
+ "template": "\\prod_{\\placeholder{}}^{\\placeholder{}}\\placeholder{}"
+ },
+ {
+ "key": "\\coprod",
+ "preview": "\\coprod_b^a",
+ "titleKey": "coproduct",
+ "template": "\\coprod_{\\placeholder{}}^{\\placeholder{}}\\placeholder{}"
+ },
+ {
+ "key": "",
+ "preview": "\\int_{a}^{b}f\\left(x\r)\\,dx",
+ "titleKey": "integral",
+ "template": "\\int_{\\placeholder{}}^{\\placeholder{}}\\placeholder{}\\,d\\placeholder{}"
+ }
+ ]
+ },
+ {
+ "titleKey": "linesCategory",
+ "symbols": [
+ { "key": "\\sqrt", "preview": "\\sqrt{abc}", "titleKey": "squareRoot" },
+ { "key": "\\bar", "preview": "\\overline{abc}", "titleKey": "bar" },
+ { "key": "\\underline", "preview": "\\underline{abc}", "titleKey": "underline" },
+ { "key": "\\overleftarrow", "preview": "\\overleftarrow{abc}", "titleKey": "leftArrow" },
+ { "key": "\\overrightarrow", "preview": "\\overrightarrow{abc}", "titleKey": "rightArrow" },
+ { "key": "\\vec", "preview": "\\vec{v}", "titleKey": "vector" }
+ ]
+ },
+ {
+ "titleKey": "basicCategory",
+ "symbols": [
+ { "key": "+", "preview": "+", "titleKey": "addition" },
+ { "key": "-", "preview": "−", "titleKey": "subtraction" },
+ { "key": "\\times", "preview": "×", "titleKey": "multiplication" },
+ { "key": "\\div", "preview": "÷", "titleKey": "division" },
+ { "key": "\\cdot", "preview": "·", "titleKey": "dot" },
+ { "key": "\\neg", "preview": "¬", "titleKey": "negation" },
+ { "key": "\\pm", "preview": "±", "titleKey": "plusMinus" },
+ { "key": "\\mp", "preview": "∓", "titleKey": "minusPlus" },
+ { "key": "\\neq", "preview": "≠", "titleKey": "doesNotEqual" },
+ { "key": "\\approx", "preview": "≈", "titleKey": "approximately" },
+ { "key": "\\propto", "preview": "∝", "titleKey": "proportional" },
+ { "key": "\\doteq", "preview": "≐", "titleKey": "definition" },
+ { "key": "\\gt", "preview": ">", "titleKey": "greaterThan" },
+ { "key": "\\ge", "preview": "≥", "titleKey": "greaterThanOrEqual" },
+ { "key": "\\ngtr", "preview": "≯", "titleKey": "notGreaterThan" },
+ { "key": "\\gg", "preview": "≫", "titleKey": "significantlyGreaterThan" },
+ { "key": "\\lt", "preview": "<", "titleKey": "lessThan" },
+ { "key": "\\le", "preview": "≤", "titleKey": "lessThanOrEqual" },
+ { "key": "\\nless", "preview": "≮", "titleKey": "notLessThan" },
+ { "key": "\\ll", "preview": "≪", "titleKey": "significantlyLessThan" },
+ { "key": "\\lceil", "preview": "⌈", "titleKey": "leftCeiling" },
+ { "key": "\\lfloor", "preview": "⌊", "titleKey": "leftFloor" },
+ { "key": "\\rceil", "preview": "⌉", "titleKey": "rightCeiling" },
+ { "key": "\\rfloor", "preview": "⌋", "titleKey": "rightFloor" }
+ ]
+ },
+ {
+ "titleKey": "advancedCategory",
+ "symbols": [
+ { "key": "\\bigotimes", "preview": "⨂", "titleKey": "tensorProduct" },
+ { "key": "\\otimes", "preview": "⊗", "titleKey": "tensorProduct" },
+ { "key": "\\oint", "preview": "∮", "titleKey": "contourIntegral" },
+ { "key": "\\nabla", "preview": "∇", "titleKey": "nabla" },
+ { "key": "\\ast", "preview": "*", "titleKey": "conjugate" },
+ { "key": "\\dagger", "preview": "†", "titleKey": "conjugateTranspose" },
+ { "key": "\\partial", "preview": "∂", "titleKey": "partial" },
+ { "key": "\\wedge", "preview": "∧", "titleKey": "wedgeProduct" },
+ { "key": "\\infty", "preview": "∞", "titleKey": "infinity" },
+ { "key": "\\top", "preview": "⊤", "titleKey": "topElement" },
+ { "key": "\\prec", "preview": "≺", "titleKey": "reducibleTo" },
+ { "key": "\\succ", "preview": "≻", "titleKey": "nondominatedBy" }
+ ]
+ },
+ {
+ "titleKey": "logicCategory",
+ "symbols": [
+ { "key": "\\land", "preview": "∧", "titleKey": "and" },
+ { "key": "\\lor", "preview": "∨", "titleKey": "or" },
+ { "key": "\\iff", "preview": "⟺", "titleKey": "ifAndOnlyIf" },
+ { "key": "\\models", "preview": "⊨", "titleKey": "entails" },
+ { "key": "\\vdash", "preview": "⊢", "titleKey": "implies" },
+ { "key": "\\vert", "preview": "|", "titleKey": "givenThat" },
+ { "key": "\\exists", "preview": "∃", "titleKey": "exists" },
+ { "key": "\\forall", "preview": "∀", "titleKey": "forAll" },
+ { "key": "\\because", "preview": "∵", "titleKey": "because" },
+ { "key": "\\therefore", "preview": "∴", "titleKey": "therefore" },
+ { "key": "\\square", "preview": "□", "titleKey": "qed" },
+ { "key": "\\bigoplus", "preview": "⨁", "titleKey": "exclusiveOr" },
+ { "key": "\\oplus", "preview": "⊕", "titleKey": "exclusiveOr" }
+ ]
+ },
+ {
+ "titleKey": "geometryCategory",
+ "symbols": [
+ { "key": "\\circ", "preview": "∘", "titleKey": "degrees" },
+ { "key": "\\angle", "preview": "∠", "titleKey": "angle" },
+ { "key": "\\measuredangle", "preview": "∡", "titleKey": "measuredAngle" },
+ { "key": "\\parallel", "preview": "∥", "titleKey": "parallel" },
+ { "key": "\\perp", "preview": "⊥", "titleKey": "perpendicular" },
+ { "key": "\\nparallel", "preview": "∦", "titleKey": "incomparableTo" },
+ { "key": "\\sim", "preview": "∼", "titleKey": "similarTo" },
+ { "key": "\\simeq", "preview": "≃", "titleKey": "similarOrEqual" },
+ { "key": "\\cong", "preview": "≅", "titleKey": "congruentTo" },
+ { "key": "\\equiv", "preview": "≡", "titleKey": "congruentTo" }
+ ]
+ },
+ {
+ "titleKey": "setsCategory",
+ "symbols": [
+ { "key": "\\dots", "preview": "…", "titleKey": "ellipsis" },
+ { "key": "\\vdots", "preview": "⋮", "titleKey": "ellipsisVertical" },
+ { "key": "\\cdots", "preview": "⋯", "titleKey": "ellipsisCentered" },
+ { "key": "\\ddots", "preview": "⋱", "titleKey": "ellipsisDiagonal" },
+ { "key": "\\aleph", "preview": "ℵ", "titleKey": "cardinality" },
+ { "key": "\\bigcap", "preview": "⋂", "titleKey": "intersection" },
+ { "key": "\\cap", "preview": "∩", "titleKey": "intersection" },
+ { "key": "\\sqcap", "preview": "⊓", "titleKey": "intersection" },
+ { "key": "\\bigcup", "preview": "⋃", "titleKey": "union" },
+ { "key": "\\cup", "preview": "∪", "titleKey": "union" },
+ { "key": "\\sqcup", "preview": "⊔", "titleKey": "union" },
+ { "key": "\\emptyset", "preview": "∅", "titleKey": "emptySet" },
+ { "key": "\\in", "preview": "∈", "titleKey": "in" },
+ { "key": "\\notin", "preview": "∉", "titleKey": "notIn" },
+ { "key": "\\ni", "preview": "∋", "titleKey": "contains" },
+ { "key": "\\ominus", "preview": "⊖", "titleKey": "symmetricDifference" },
+ { "key": "\\setminus", "preview": "∖", "titleKey": "setDifference" },
+ { "key": "\\subset", "preview": "⊂", "titleKey": "subset" },
+ { "key": "\\sqsubset", "preview": "⊏", "titleKey": "subset" },
+ { "key": "\\subseteq", "preview": "⊆", "titleKey": "subsetOrEqual" },
+ { "key": "\\sqsubseteq", "preview": "⊑", "titleKey": "subsetOrEqual" },
+ { "key": "\\nsubseteq", "preview": "⊈", "titleKey": "notSubsetOrEqual" },
+ { "key": "\\supset", "preview": "⊃", "titleKey": "superset" },
+ { "key": "\\sqsupset", "preview": "⊐", "titleKey": "superset" },
+ { "key": "\\supseteq", "preview": "⊇", "titleKey": "supersetOrEqual" },
+ { "key": "\\sqsupseteq", "preview": "⊒", "titleKey": "supersetOrEqual" },
+ { "key": "\\nsupseteq", "preview": "⊉", "titleKey": "notSupersetOrEqual" },
+ { "key": "\\wr", "preview": "≀", "titleKey": "wreathProduct" },
+ { "key": "\\bowtie", "preview": "⋈", "titleKey": "naturalJoin" }
+ ]
+ },
+ {
+ "titleKey": "directionalCategory",
+ "symbols": [
+ { "key": "\\downarrow", "preview": "↓", "titleKey": "down" },
+ { "key": "\\Downarrow", "preview": "⇓", "titleKey": "downDouble" },
+ { "key": "\\bigtriangledown", "preview": "▽", "titleKey": "triangleDown" },
+ { "key": "\\uparrow", "preview": "↑", "titleKey": "up" },
+ { "key": "\\Uparrow", "preview": "⇑", "titleKey": "upDouble" },
+ { "key": "\\bigtriangleup", "preview": "△", "titleKey": "triangleUp" },
+ { "key": "\\updownarrow", "preview": "↕", "titleKey": "upDown" },
+ { "key": "\\Updownarrow", "preview": "⇕", "titleKey": "upDownDouble" },
+ { "key": "\\leftarrow", "preview": "←", "titleKey": "left" },
+ { "key": "\\Leftarrow", "preview": "⇐", "titleKey": "leftDouble" },
+ { "key": "\\longleftarrow", "preview": "⟵", "titleKey": "leftLong" },
+ { "key": "\\Longleftarrow", "preview": "⟸", "titleKey": "leftLongDouble" },
+ { "key": "\\hookleftarrow", "preview": "↩", "titleKey": "leftHooked" },
+ { "key": "\\leftharpoondown", "preview": "↽", "titleKey": "leftHarpoonDown" },
+ { "key": "\\leftharpoondup", "preview": "↼", "titleKey": "leftHarpoonUp" },
+ { "key": "\\rightarrow", "preview": "→", "titleKey": "right" },
+ { "key": "\\Rightarrow", "preview": "⇒", "titleKey": "rightDouble" },
+ { "key": "\\longrightarrow", "preview": "⟶", "titleKey": "rightLong" },
+ { "key": "\\Longrightarrow", "preview": "⟹", "titleKey": "rightLongDouble" },
+ { "key": "\\hookrightarrow", "preview": "↪", "titleKey": "rightHooked" },
+ { "key": "\\rightharpoondown", "preview": "⇁", "titleKey": "rightHarpoonDown" },
+ { "key": "\\rightharpoondup", "preview": "⇀", "titleKey": "rightHarpoonUp" },
+ { "key": "\\leftrightarrow", "preview": "↔", "titleKey": "leftRight" },
+ { "key": "\\Leftrightarrow", "preview": "⇔", "titleKey": "leftRightDouble" },
+ { "key": "\\longleftrightarrow", "preview": "⟷", "titleKey": "leftRightLong" },
+ { "key": "\\Longleftrightarrow", "preview": "⟺", "titleKey": "leftRightLongDouble" },
+ { "key": "\\nearrow", "preview": "↗", "titleKey": "northeast" },
+ { "key": "\\nwarrow", "preview": "↖", "titleKey": "northwest" },
+ { "key": "\\searrow", "preview": "↘", "titleKey": "southeast" },
+ { "key": "\\swarrow", "preview": "↙", "titleKey": "southwest" }
+ ]
+ },
+ {
+ "titleKey": "charactersCategory",
+ "symbols": [
+ { "key": "\\alpha", "preview": "α", "titleKey": "alpha" },
+ { "key": "\\beta", "preview": "β", "titleKey": "beta" },
+ { "key": "\\chi", "preview": "χ", "titleKey": "chi" },
+ { "key": "\\Delta", "preview": "Δ", "titleKey": "deltaCapital" },
+ { "key": "\\delta", "preview": "δ", "titleKey": "delta" },
+ { "key": "\\digamma", "preview": "ϝ", "titleKey": "digamma" },
+ { "key": "\\ell", "preview": "ℓ", "titleKey": "ell" },
+ { "key": "\\epsilon", "preview": "ϵ", "titleKey": "epsilon" },
+ { "key": "\\varepsilon", "preview": "ε", "titleKey": "epsilon" },
+ { "key": "\\eta", "preview": "η", "titleKey": "eta" },
+ { "key": "\\Gamma", "preview": "Γ", "titleKey": "gammaCapital" },
+ { "key": "\\gamma", "preview": "γ", "titleKey": "gamma" },
+ { "key": "\\hbar", "preview": "ℏ", "titleKey": "planckConstant" },
+ { "key": "\\iota", "preview": "ι", "titleKey": "iota" },
+ { "key": "\\kappa", "preview": "κ", "titleKey": "kappa" },
+ { "key": "\\varkappa", "preview": "ϰ", "titleKey": "kappa" },
+ { "key": "\\Lambda", "preview": "Λ", "titleKey": "lambdaCapital" },
+ { "key": "\\lambda", "preview": "λ", "titleKey": "lambda" },
+ { "key": "\\mu", "preview": "μ", "titleKey": "mu" },
+ { "key": "\\nu", "preview": "ν", "titleKey": "nu" },
+ { "key": "\\Omega", "preview": "Ω", "titleKey": "omegaCapital" },
+ { "key": "\\omega", "preview": "ω", "titleKey": "omega" },
+ { "key": "\\Phi", "preview": "Φ", "titleKey": "phiCapital" },
+ { "key": "\\phi", "preview": "ϕ", "titleKey": "phi" },
+ { "key": "\\varphi", "preview": "φ", "titleKey": "phi" },
+ { "key": "\\Pi", "preview": "Π", "titleKey": "piCapital" },
+ { "key": "\\pi", "preview": "π", "titleKey": "pi" },
+ { "key": "\\varpi", "preview": "ϖ", "titleKey": "pi" },
+ { "key": "\\Psi", "preview": "Ψ", "titleKey": "psiCapital" },
+ { "key": "\\psi", "preview": "ψ", "titleKey": "psi" },
+ { "key": "\\rho", "preview": "ρ", "titleKey": "rho" },
+ { "key": "\\varrho", "preview": "ϱ", "titleKey": "rho" },
+ { "key": "\\Sigma", "preview": "Σ", "titleKey": "sigmaCapital" },
+ { "key": "\\sigma", "preview": "σ", "titleKey": "sigma" },
+ { "key": "\\varsigma", "preview": "ς", "titleKey": "sigma" },
+ { "key": "\\tau", "preview": "τ", "titleKey": "tau" },
+ { "key": "\\Theta", "preview": "Θ", "titleKey": "thetaCapital" },
+ { "key": "\\theta", "preview": "θ", "titleKey": "theta" },
+ { "key": "\\vartheta", "preview": "ϑ", "titleKey": "theta" },
+ { "key": "\\Upsilon", "preview": "Υ", "titleKey": "upsilonCapital" },
+ { "key": "\\upsilon", "preview": "υ", "titleKey": "upsilon" },
+ { "key": "\\wp", "preview": "℘", "titleKey": "pWeierstrass" },
+ { "key": "\\Xi", "preview": "Ξ", "titleKey": "xiCapital" },
+ { "key": "\\xi", "preview": "ξ", "titleKey": "xi" },
+ { "key": "\\zeta", "preview": "ζ", "titleKey": "zeta" }
+ ]
+ },
+ {
+ "titleKey": "miscellaneousCategory",
+ "symbols": [
+ { "key": "\\bigcirc", "preview": "◯", "titleKey": "circle" },
+ { "key": "\\clubsuit", "preview": "♣", "titleKey": "club" },
+ { "key": "\\diamondsuit", "preview": "♢", "titleKey": "diamond" },
+ { "key": "\\heartsuit", "preview": "♡", "titleKey": "heart" },
+ { "key": "\\spadesuit", "preview": "♠", "titleKey": "spade" },
+ { "key": "\\flat", "preview": "♭", "titleKey": "flat" },
+ { "key": "\\natural", "preview": "♮", "titleKey": "natural" },
+ { "key": "\\sharp", "preview": "♯", "titleKey": "sharp" }
+ ]
+ }
+]
diff --git a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/components/toolbar/FormatDropdown.vue b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/components/toolbar/FormatDropdown.vue
index a55ecd43ec..a3906153cd 100644
--- a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/components/toolbar/FormatDropdown.vue
+++ b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/components/toolbar/FormatDropdown.vue
@@ -126,7 +126,6 @@
case ' ':
event.preventDefault();
applyFormat(format);
- toggleDropdown();
break;
case 'ArrowDown':
event.preventDefault();
@@ -235,7 +234,6 @@
background: #e6e6e6;
border-radius: 4px;
outline: 2px solid #0097f2;
- outline-offset: 2px;
}
.dropdown-icon {
@@ -269,7 +267,6 @@
'Segoe UI',
sans-serif;
font-size: 14px;
- font-weight: 400;
line-height: 140%;
color: #000000;
cursor: pointer;
diff --git a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/components/toolbar/PasteDropdown.vue b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/components/toolbar/PasteDropdown.vue
index d8072183a3..ad5e27c398 100644
--- a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/components/toolbar/PasteDropdown.vue
+++ b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/components/toolbar/PasteDropdown.vue
@@ -259,7 +259,6 @@
background: #e6e6e6;
border-radius: 4px;
outline: 2px solid #0097f2;
- outline-offset: 2px;
}
.toolbar-icon {
@@ -304,7 +303,6 @@
background: #e6e6e6;
border-radius: 4px;
outline: 2px solid #0097f2;
- outline-offset: 2px;
}
.dropdown-arrow {
@@ -343,7 +341,6 @@
'Segoe UI',
sans-serif;
font-size: 14px;
- font-weight: 400;
line-height: 140%;
color: #000000;
cursor: pointer;
diff --git a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/components/toolbar/ToolbarButton.vue b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/components/toolbar/ToolbarButton.vue
index 97af38d3ec..406facb8ac 100644
--- a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/components/toolbar/ToolbarButton.vue
+++ b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/components/toolbar/ToolbarButton.vue
@@ -41,9 +41,9 @@
return props.icon;
});
- const handleClick = () => {
+ const handleClick = event => {
if (props.isAvailable) {
- emit('click');
+ emit('click', event);
}
};
@@ -51,7 +51,7 @@
// Handle Enter and Space keys
if ((event.key === 'Enter' || event.key === ' ') && props.isAvailable) {
event.preventDefault();
- emit('click');
+ emit('click', event);
}
};
@@ -129,12 +129,11 @@
background: #e6e6e6;
border-radius: 4px;
outline: 2px solid #0097f2;
- outline-offset: 2px;
}
.toolbar-icon {
- width: 19px;
- height: 19px;
+ width: 21px;
+ height: 21px;
opacity: 0.7;
}
diff --git a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/components/toolbar/ToolbarDivider.vue b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/components/toolbar/ToolbarDivider.vue
index 57917ffa58..25f9782a92 100644
--- a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/components/toolbar/ToolbarDivider.vue
+++ b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/components/toolbar/ToolbarDivider.vue
@@ -21,7 +21,7 @@
.toolbar-divider {
width: 1px;
height: 20px;
- margin: 0 4px;
+ margin: 0 3px;
background: #dee2e6;
}
diff --git a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/composables/useEditor.js b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/composables/useEditor.js
index 95375cbda0..47b1b48501 100644
--- a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/composables/useEditor.js
+++ b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/composables/useEditor.js
@@ -1,8 +1,14 @@
-import { ref, onMounted, onUnmounted } from 'vue';
+import { ref, onUnmounted } from 'vue';
import { Editor } from '@tiptap/vue-2';
import StarterKitExtension from '@tiptap/starter-kit';
import UnderlineExtension from '@tiptap/extension-underline';
+import { Superscript } from '@tiptap/extension-superscript';
+import { Subscript } from '@tiptap/extension-subscript';
import { Small } from '../extensions/SmallTextExtension';
+import { Image } from '../extensions/Image';
+import { CodeBlockSyntaxHighlight } from '../extensions/CodeBlockSyntaxHighlight';
+import { CustomLink } from '../extensions/Link';
+import { Math } from '../extensions/Math';
export function useEditor() {
const editor = ref(null);
@@ -10,7 +16,20 @@ export function useEditor() {
const initializeEditor = () => {
editor.value = new Editor({
- extensions: [StarterKitExtension, UnderlineExtension, Small],
+ extensions: [
+ StarterKitExtension.configure({
+ codeBlock: false, // Disable default code block to use the extended version
+ link: false, // Disable default link to use the custom link extension
+ }),
+ UnderlineExtension,
+ CodeBlockSyntaxHighlight,
+ Small,
+ Superscript,
+ Subscript,
+ Image,
+ CustomLink, // Use our custom Link extension
+ Math,
+ ],
content: '
',
editorProps: {
attributes: {
@@ -31,10 +50,6 @@ export function useEditor() {
}
};
- onMounted(() => {
- initializeEditor();
- });
-
onUnmounted(() => {
destroyEditor();
});
diff --git a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/composables/useFocusTrap.js b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/composables/useFocusTrap.js
new file mode 100644
index 0000000000..5907b11dfb
--- /dev/null
+++ b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/composables/useFocusTrap.js
@@ -0,0 +1,57 @@
+import { onMounted, onUnmounted, nextTick } from 'vue';
+
+/**
+ * A composable that traps focus within a specified element.
+ * @param {import('vue').Ref} rootElRef
+ * - A ref to the root element that should contain focus.
+ */
+export function useFocusTrap(rootElRef) {
+ const getFocusableElements = () => {
+ if (!rootElRef.value) return [];
+ const elements = rootElRef.value.querySelectorAll(
+ 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])',
+ );
+ // Return only visible and enabled elements
+ return Array.from(elements).filter(el => !el.disabled && el.offsetParent !== null);
+ };
+
+ const handleFocusTrap = event => {
+ if (event.key !== 'Tab') return;
+
+ const focusableElements = getFocusableElements();
+ if (focusableElements.length === 0) return;
+
+ const firstElement = focusableElements[0];
+ const lastElement = focusableElements[focusableElements.length - 1];
+
+ if (event.shiftKey) {
+ // When Shift+Tab is pressed on the first element, loop to the last
+ if (document.activeElement === firstElement) {
+ event.preventDefault();
+ lastElement.focus();
+ }
+ } else {
+ // When Tab is pressed on the last element, loop to the first
+ if (document.activeElement === lastElement) {
+ event.preventDefault();
+ firstElement.focus();
+ }
+ }
+ };
+
+ onMounted(() => {
+ // When the component mounts, focus the first interactive element
+ nextTick(() => {
+ const focusableElements = getFocusableElements();
+ if (focusableElements.length > 0) {
+ focusableElements[0].focus();
+ }
+ });
+
+ document.addEventListener('keydown', handleFocusTrap);
+ });
+
+ onUnmounted(() => {
+ document.removeEventListener('keydown', handleFocusTrap);
+ });
+}
diff --git a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/composables/useImageHandling.js b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/composables/useImageHandling.js
new file mode 100644
index 0000000000..68154a72b2
--- /dev/null
+++ b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/composables/useImageHandling.js
@@ -0,0 +1,126 @@
+import { ref, onMounted, onUnmounted, watch } from 'vue';
+
+export function useImageHandling(editor) {
+ const modalMode = ref(null); // 'create' or 'edit'
+ const modalInitialData = ref({});
+ const popoverStyle = ref({});
+ const editingNodePos = ref(null);
+ const isModalCentered = ref(false);
+
+ const setPopoverPosition = targetElement => {
+ isModalCentered.value = false;
+ const rect = targetElement.getBoundingClientRect();
+ popoverStyle.value = {
+ position: 'fixed',
+ top: `${rect.bottom + 5}px`,
+ left: `${rect.right}px`,
+ transform: 'translateX(-100%)',
+ };
+ };
+
+ const setCenteredPosition = () => {
+ isModalCentered.value = true;
+ popoverStyle.value = {
+ position: 'fixed',
+ top: '50%',
+ left: '50%',
+ transform: 'translate(-50%, -50%)',
+ };
+ };
+
+ const openCreateModal = ({ file = null, targetElement = null } = {}) => {
+ if (targetElement) {
+ setPopoverPosition(targetElement);
+ } else {
+ setCenteredPosition();
+ }
+ modalInitialData.value = { file };
+ modalMode.value = 'create';
+ };
+
+ const openEditModal = ({ pos, attrs }) => {
+ setCenteredPosition();
+ editingNodePos.value = pos;
+ modalInitialData.value = { ...attrs };
+ modalMode.value = 'edit';
+ };
+
+ const closeModal = () => {
+ modalMode.value = null;
+ modalInitialData.value = {};
+ editingNodePos.value = null;
+ isModalCentered.value = false;
+ };
+
+ const handleInsert = async data => {
+ if (!data.src || !editor?.value) return;
+ editor.value.chain().focus().setImage(data).run();
+ closeModal();
+ };
+
+ const handleUpdate = newAttrs => {
+ if (editingNodePos.value !== null && editor?.value) {
+ editor.value
+ .chain()
+ .focus()
+ .updateAttributes('image', newAttrs)
+ .setNodeSelection(editingNodePos.value)
+ .run();
+ }
+ closeModal();
+ };
+
+ const handleRemove = () => {
+ if (editingNodePos.value !== null && editor?.value) {
+ const node = editor.value.state.doc.nodeAt(editingNodePos.value);
+ if (node) {
+ editor.value
+ .chain()
+ .focus()
+ .deleteRange({ from: editingNodePos.value, to: editingNodePos.value + node.nodeSize })
+ .run();
+ }
+ }
+ closeModal();
+ };
+
+ watch(modalMode, mode => {
+ const handler = event => {
+ const popover = document.querySelector('.image-upload-modal');
+ if (popover && !popover.contains(event.target)) {
+ closeModal();
+ }
+ };
+ if (mode) {
+ setTimeout(() => {
+ document.addEventListener('mousedown', handler, true);
+ }, 0);
+ } else {
+ document.removeEventListener('mousedown', handler, true);
+ }
+ });
+
+ onMounted(() => {
+ if (editor?.value) {
+ editor.value.on('open-image-editor', openEditModal);
+ }
+ });
+
+ onUnmounted(() => {
+ if (editor?.value) {
+ editor.value.off('open-image-editor', openEditModal);
+ }
+ });
+
+ return {
+ modalMode,
+ modalInitialData,
+ popoverStyle,
+ isModalCentered,
+ openCreateModal,
+ closeModal,
+ handleInsert,
+ handleUpdate,
+ handleRemove,
+ };
+}
diff --git a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/composables/useLinkHandling.js b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/composables/useLinkHandling.js
new file mode 100644
index 0000000000..fa0e6a3d00
--- /dev/null
+++ b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/composables/useLinkHandling.js
@@ -0,0 +1,164 @@
+import { ref, watch, onUnmounted } from 'vue';
+
+export function useLinkHandling(editor) {
+ const isEditorOpen = ref(false);
+ const isBubbleMenuOpen = ref(false);
+ const popoverStyle = ref({});
+ const editorInitialState = ref({ text: '', href: '' });
+ const editorMode = ref('create');
+ const savedSelection = ref(null);
+
+ const calculatePosition = () => {
+ if (!editor.value) return {};
+ const { view } = editor.value;
+ const { from } = view.state.selection;
+ const coords = view.coordsAtPos(from);
+ return {
+ position: 'fixed',
+ left: `${coords.left}px`,
+ top: `${coords.bottom + 8}px`,
+ zIndex: 1001,
+ };
+ };
+
+ const openLinkEditor = (mode = 'create') => {
+ if (!editor.value) return;
+
+ closeBubbleMenu(); // Ensure bubble menu is closed
+
+ const { state } = editor.value;
+ const { from, to, empty } = state.selection;
+
+ popoverStyle.value = calculatePosition();
+ editorMode.value = mode;
+
+ if (mode === 'edit') {
+ const linkAttrs = editor.value.getAttributes('link');
+ if (!linkAttrs.href) {
+ closeLinkEditor();
+ return;
+ }
+ editor.value.chain().focus().extendMarkRange('link').run();
+ const newSelection = editor.value.state.selection;
+ savedSelection.value = { from: newSelection.from, to: newSelection.to };
+ editorInitialState.value = {
+ href: linkAttrs.href,
+ text: state.doc.textBetween(newSelection.from, newSelection.to, ' '),
+ };
+ } else {
+ savedSelection.value = { from, to };
+ editorInitialState.value = {
+ href: '',
+ text: empty ? '' : state.doc.textBetween(from, to, ' '),
+ };
+ }
+
+ isEditorOpen.value = true;
+ };
+
+ const closeLinkEditor = () => {
+ isEditorOpen.value = false;
+ savedSelection.value = null;
+ editorMode.value = 'create';
+ };
+
+ const openBubbleMenu = () => {
+ if (isEditorOpen.value) return;
+ popoverStyle.value = calculatePosition();
+ isBubbleMenuOpen.value = true;
+ };
+
+ const closeBubbleMenu = () => {
+ isBubbleMenuOpen.value = false;
+ };
+
+ const closeAll = () => {
+ closeLinkEditor();
+ closeBubbleMenu();
+ };
+
+ const saveLink = ({ text, href }) => {
+ if (!editor.value || !savedSelection.value) {
+ return closeAll();
+ }
+
+ const { from, to } = savedSelection.value;
+ const tr = editor.value.state.tr;
+ const linkMark = editor.value.state.schema.marks.link.create({ href });
+ tr.replaceWith(from, to, editor.value.state.schema.text(text, [linkMark]));
+ editor.value.view.dispatch(tr);
+
+ closeAll();
+ };
+
+ const removeLink = () => {
+ editor.value?.chain().focus().extendMarkRange('link').unsetLink().run();
+ closeAll();
+ };
+
+ const handleSelectionUpdate = () => {
+ if (editor.value.isActive('link')) {
+ openBubbleMenu();
+ } else {
+ closeBubbleMenu();
+ }
+ };
+
+ watch([isEditorOpen, isBubbleMenuOpen], ([editorIsOpen, bubbleIsOpen]) => {
+ const isOpen = editorIsOpen || bubbleIsOpen;
+ const clickHandler = event => {
+ const popover =
+ document.querySelector('.link-editor-popover') ||
+ document.querySelector('.link-bubble-menu');
+ if (popover && !popover.contains(event.target)) {
+ closeAll();
+ }
+ };
+ const scrollHandler = () => closeAll();
+
+ if (isOpen) {
+ setTimeout(() => {
+ document.addEventListener('mousedown', clickHandler, true);
+ document.addEventListener('scroll', scrollHandler, true);
+ }, 0);
+ } else {
+ document.removeEventListener('mousedown', clickHandler, true);
+ document.removeEventListener('scroll', scrollHandler, true);
+ }
+ });
+
+ watch(
+ () => editor.value,
+ (newEditor, oldEditor) => {
+ if (oldEditor) {
+ oldEditor.off('open-link-editor', openLinkEditor);
+ oldEditor.off('selectionUpdate', handleSelectionUpdate);
+ }
+ if (newEditor) {
+ newEditor.on('open-link-editor', openLinkEditor);
+ newEditor.on('selectionUpdate', handleSelectionUpdate);
+ }
+ },
+ { immediate: true },
+ );
+
+ onUnmounted(() => {
+ if (editor?.value) {
+ editor.value.off('open-link-editor', openLinkEditor);
+ editor.value.off('selectionUpdate', handleSelectionUpdate);
+ }
+ });
+
+ return {
+ isEditorOpen,
+ isBubbleMenuOpen,
+ popoverStyle,
+ editorInitialState,
+ editorMode,
+ openLinkEditor,
+ closeLinkEditor,
+ closeBubbleMenu,
+ saveLink,
+ removeLink,
+ };
+}
diff --git a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/composables/useMathHandling.js b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/composables/useMathHandling.js
new file mode 100644
index 0000000000..ab51f39895
--- /dev/null
+++ b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/composables/useMathHandling.js
@@ -0,0 +1,128 @@
+import { ref, onUnmounted, watch } from 'vue';
+
+export function useMathHandling(editor) {
+ // State for the modal
+ const isMathModalOpen = ref(false);
+ const mathModalMode = ref('create'); // 'create' or 'edit'
+ const mathModalInitialLatex = ref('');
+ const editingMathNodePos = ref(null);
+ const popoverStyle = ref({});
+ const isModalCentered = ref(false);
+
+ const setPopoverPosition = targetElement => {
+ isModalCentered.value = false;
+ const rect = targetElement.getBoundingClientRect();
+ popoverStyle.value = {
+ position: 'fixed',
+ top: `${rect.bottom + 5}px`,
+ left: `${rect.right}px`,
+ transform: 'translateX(-100%)',
+ };
+ };
+
+ const setCenteredPosition = () => {
+ isModalCentered.value = true;
+ popoverStyle.value = {
+ position: 'fixed',
+ top: '50%',
+ left: '50%',
+ transform: 'translate(-50%, -50%)',
+ };
+ };
+
+ const openCreateMathModal = ({ targetElement = null } = {}) => {
+ mathModalMode.value = 'create';
+ mathModalInitialLatex.value = '';
+ editingMathNodePos.value = null;
+
+ if (targetElement) {
+ setPopoverPosition(targetElement);
+ } else {
+ setCenteredPosition();
+ }
+
+ isMathModalOpen.value = true;
+ };
+
+ const openEditMathModal = ({ pos, latex }) => {
+ mathModalMode.value = 'edit';
+ mathModalInitialLatex.value = latex;
+ editingMathNodePos.value = pos;
+ setCenteredPosition(); // Edit mode stays centered
+ isMathModalOpen.value = true;
+ };
+
+ const closeMathModal = () => {
+ isMathModalOpen.value = false;
+ isModalCentered.value = false;
+ };
+
+ const handleSaveMath = newLatex => {
+ if (!editor.value) return;
+
+ if (mathModalMode.value === 'create') {
+ editor.value.chain().focus().setMath({ latex: newLatex }).run();
+ } else if (editingMathNodePos.value !== null) {
+ // For editing - use direct transaction approach
+ const { state, view } = editor.value;
+ const pos = editingMathNodePos.value;
+ const node = state.doc.nodeAt(pos);
+
+ if (node && node.type.name === 'math') {
+ const tr = state.tr.setNodeMarkup(pos, null, { latex: newLatex });
+ view.dispatch(tr);
+ editor.value.commands.focus();
+ }
+ }
+ closeMathModal();
+ };
+
+ // Watch for when the editor becomes available and set up event listeners
+ watch(
+ () => editor.value,
+ (newEditor, oldEditor) => {
+ if (oldEditor) {
+ oldEditor.off('open-math-editor', openEditMathModal);
+ }
+ if (newEditor) {
+ newEditor.on('open-math-editor', openEditMathModal);
+ }
+ },
+ { immediate: true },
+ );
+
+ // Close modal when clicking outside
+ watch(isMathModalOpen, isOpen => {
+ const handler = event => {
+ const modalElement = document.querySelector('.formulas-menu');
+ if (modalElement && !modalElement.contains(event.target)) {
+ closeMathModal();
+ }
+ };
+
+ if (isOpen) {
+ setTimeout(() => {
+ document.addEventListener('mousedown', handler, true);
+ }, 0);
+ } else {
+ document.removeEventListener('mousedown', handler, true);
+ }
+ });
+
+ onUnmounted(() => {
+ if (editor.value) {
+ editor.value.off('open-math-editor', openEditMathModal);
+ }
+ });
+
+ return {
+ isMathModalOpen,
+ mathModalMode,
+ mathModalInitialLatex,
+ popoverStyle,
+ isModalCentered,
+ openCreateMathModal,
+ closeMathModal,
+ handleSaveMath,
+ };
+}
diff --git a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/composables/useMathLiveLocale.js b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/composables/useMathLiveLocale.js
new file mode 100644
index 0000000000..7a307d4dbb
--- /dev/null
+++ b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/composables/useMathLiveLocale.js
@@ -0,0 +1,26 @@
+import { watch } from 'vue';
+
+export function useMathLiveLocale(locale) {
+ const configureMathLiveLocale = newLocale => {
+ if (typeof window !== 'undefined' && window.MathfieldElement) {
+ window.MathfieldElement.locale = newLocale;
+
+ if (window.mathVirtualKeyboard) {
+ window.mathVirtualKeyboard.locale = newLocale;
+ }
+ }
+ };
+
+ // Watch for locale changes
+ watch(
+ locale,
+ newLocale => {
+ configureMathLiveLocale(newLocale);
+ },
+ { immediate: true },
+ );
+
+ return {
+ configureMathLiveLocale,
+ };
+}
diff --git a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/composables/useToolbarActions.js b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/composables/useToolbarActions.js
index 1eeacf871b..56a9018de0 100644
--- a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/composables/useToolbarActions.js
+++ b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/composables/useToolbarActions.js
@@ -61,38 +61,76 @@ export function useToolbarActions() {
// Copy with formatting
const handleCopy = async () => {
- if (editor.value) {
- const { state } = editor.value;
- const { from, to } = state.selection;
+ if (!editor.value) return;
- if (from === to) return; // No selection
+ const { state } = editor.value;
+ const { from, to } = state.selection;
- // Get selected text
- const selectedText = state.doc.textBetween(from, to, '\n');
+ if (from === to) return; // No selection
- // Use browser's native selection to get the actual selected HTML
- const selection = window.getSelection();
- let selectedHtml = '';
+ // Get selected text for plain text fallback
+ const selectedText = state.doc.textBetween(from, to, '\n');
+ try {
+ // Get HTML directly from the current selection
+ const selection = window.getSelection();
if (selection.rangeCount > 0) {
const range = selection.getRangeAt(0);
- const contents = range.cloneContents();
- const tempDiv = document.createElement('div');
- tempDiv.appendChild(contents);
- selectedHtml = tempDiv.innerHTML;
- }
+ const container = document.createElement('div');
+ container.appendChild(range.cloneContents());
+
+ // Process math elements specifically
+ const mathFields = container.querySelectorAll('math-field');
+ mathFields.forEach(mathField => {
+ const latex = mathField.getAttribute('value') || '';
+ const span = document.createElement('span');
+ span.className = 'math-inline';
+ span.setAttribute('data-latex', latex);
+ span.textContent = `\\(${latex}\\)`;
+ mathField.parentNode.replaceChild(span, mathField);
+ });
+
+ // Remove elements marked with data-copy-ignore
+ const copyIgnoreElements = container.querySelectorAll('[data-copy-ignore]');
+ copyIgnoreElements.forEach(el => el.remove());
+
+ // Remove Vue-specific attributes and wrapper divs
+ const allElements = container.querySelectorAll('*');
+ allElements.forEach(el => {
+ // Remove Vue data attributes
+ Array.from(el.attributes).forEach(attr => {
+ if (
+ attr.name.startsWith('data-v-') ||
+ attr.name === 'data-node-view-wrapper' ||
+ attr.name === 'contenteditable' ||
+ attr.name === 'tabindex' ||
+ attr.name === 'data-copy-ignore'
+ ) {
+ el.removeAttribute(attr.name);
+ }
+ });
+
+ // Remove wrapper divs
+ if (el.classList.contains('math-node-wrapper')) {
+ while (el.firstChild) {
+ el.parentNode.insertBefore(el.firstChild, el);
+ }
+ el.remove();
+ }
+ });
+
+ const cleanHtml = container.innerHTML;
- try {
await navigator.clipboard.write([
new ClipboardItem({
- 'text/html': new Blob([selectedHtml], { type: 'text/html' }),
+ 'text/html': new Blob([cleanHtml], { type: 'text/html' }),
'text/plain': new Blob([selectedText], { type: 'text/plain' }),
}),
]);
- } catch (err) {
- // Fallback to plain text
- await navigator.clipboard.writeText(selectedText);
}
+ } catch (err) {
+ // Fallback to plain text
+ await navigator.clipboard.writeText(selectedText);
}
};
@@ -142,19 +180,23 @@ export function useToolbarActions() {
};
const handleSubscript = () => {
- // TipTap subscript logic will be added here
+ if (editor?.value) {
+ editor.value.chain().focus().toggleSubscript().run();
+ }
};
const handleSuperscript = () => {
- // TipTap superscript logic will be added here
+ if (editor?.value) {
+ editor.value.chain().focus().toggleSuperscript().run();
+ }
};
const handleInsertImage = () => {
- // TipTap insert image logic will be added here
+ // placeholder
};
const handleInsertLink = () => {
- // TipTap insert link logic will be added here
+ // placeholder
};
const handleMath = () => {
@@ -162,7 +204,9 @@ export function useToolbarActions() {
};
const handleCodeBlock = () => {
- // TipTap code block logic may be added here
+ if (editor?.value) {
+ editor.value.chain().focus().toggleCodeBlock().run();
+ }
};
const handleFormatChange = format => {
@@ -191,12 +235,34 @@ export function useToolbarActions() {
}
};
+ const handleClearFormat = () => {
+ if (editor?.value) {
+ editor.value.chain().focus().unsetAllMarks().run();
+ }
+ };
+
// Helper function to check if a mark is active
const isMarkActive = markName => {
return editor?.value?.isActive(markName) || false;
};
- // Helper function to check if a button is clickable
+ // Helper function to check if any of the main marks are active
+ const hasClearableMark = () => {
+ if (!editor?.value) return false;
+ const { from, to, empty } = editor.value.state.selection;
+ if (empty) {
+ return false;
+ }
+
+ let hasMarks = false;
+ editor.value.state.doc.nodesBetween(from, to, node => {
+ if (node.marks.length > 0) {
+ hasMarks = true;
+ }
+ });
+ return hasMarks;
+ };
+
const isButtonAvailable = action => {
if (!editor?.value) return false;
@@ -205,8 +271,10 @@ export function useToolbarActions() {
return editor.value.can().undo();
case 'redo':
return editor.value.can().redo();
+ case 'removeFormat':
+ return hasClearableMark();
default:
- return true; // Default to true for other actions
+ return true;
}
};
@@ -282,13 +350,17 @@ export function useToolbarActions() {
name: 'subscript',
title: subscript$(),
icon: require('../../assets/icon-subscript.svg'),
+ rtlIcon: require('../../assets/icon-subscriptRTL.svg'),
handler: handleSubscript,
+ isActive: isMarkActive('subscript'),
},
{
name: 'superscript',
title: superscript$(),
icon: require('../../assets/icon-superscript.svg'),
+ rtlIcon: require('../../assets/icon-superscriptRTL.svg'),
handler: handleSuperscript,
+ isActive: isMarkActive('superscript'),
},
]);
@@ -303,6 +375,7 @@ export function useToolbarActions() {
name: 'link',
title: insertLink$(),
icon: require('../../assets/icon-link.svg'),
+ isActive: isMarkActive('link'),
handler: handleInsertLink,
},
{
@@ -316,6 +389,7 @@ export function useToolbarActions() {
title: codeBlock$(),
icon: require('../../assets/icon-codeblock.svg'),
handler: handleCodeBlock,
+ isActive: isMarkActive('codeBlock'),
},
]);
@@ -339,6 +413,8 @@ export function useToolbarActions() {
handleMath,
handleCodeBlock,
handleFormatChange,
+ handleClearFormat,
+ canClearFormat: computed(() => isButtonAvailable('removeFormat')),
// Action arrays
historyActions,
diff --git a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/extensions/CodeBlockSyntaxHighlight.js b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/extensions/CodeBlockSyntaxHighlight.js
new file mode 100644
index 0000000000..ae13fae18b
--- /dev/null
+++ b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/extensions/CodeBlockSyntaxHighlight.js
@@ -0,0 +1,12 @@
+import TiptapCodeBlockLowlight from '@tiptap/extension-code-block-lowlight';
+
+import { createLowlight, common } from 'lowlight';
+
+const lowlight = createLowlight(common);
+
+export const CodeBlockSyntaxHighlight = TiptapCodeBlockLowlight.configure({
+ lowlight,
+ HTMLAttributes: {
+ spellcheck: 'false',
+ },
+});
diff --git a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/extensions/Image.js b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/extensions/Image.js
new file mode 100644
index 0000000000..6b75c2eae1
--- /dev/null
+++ b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/extensions/Image.js
@@ -0,0 +1,47 @@
+import { Node, mergeAttributes } from '@tiptap/core';
+import { VueNodeViewRenderer } from '@tiptap/vue-2';
+import ImageNodeView from '../components/image/ImageNodeView.vue';
+
+export const Image = Node.create({
+ name: 'image',
+
+ group: 'block',
+
+ inline: false,
+
+ allowBase64: true,
+
+ addAttributes() {
+ return {
+ src: { default: null },
+ alt: { default: null },
+ width: { default: null },
+ height: { default: null },
+ };
+ },
+
+ parseHTML() {
+ return [{ tag: 'img[src]' }];
+ },
+
+ renderHTML({ HTMLAttributes }) {
+ return ['img', mergeAttributes(HTMLAttributes)];
+ },
+
+ addNodeView() {
+ return VueNodeViewRenderer(ImageNodeView);
+ },
+
+ addCommands() {
+ return {
+ setImage:
+ options =>
+ ({ commands }) => {
+ return commands.insertContent({
+ type: this.name,
+ attrs: options,
+ });
+ },
+ };
+ },
+});
diff --git a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/extensions/Link.js b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/extensions/Link.js
new file mode 100644
index 0000000000..8a76237bdf
--- /dev/null
+++ b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/extensions/Link.js
@@ -0,0 +1,24 @@
+/* We specifically want to control the click behavior to show our custom bubble menu instead of
+immediately navigating to the link's URL */
+
+import { Link } from '@tiptap/extension-link';
+
+export const CustomLink = Link.extend({
+ inclusive: false,
+
+ addOptions() {
+ return {
+ ...this.parent?.(),
+ openOnClick: false,
+ };
+ },
+
+ addKeyboardShortcuts() {
+ return {
+ 'Mod-k': () => {
+ this.editor.emit('open-link-editor');
+ return true;
+ },
+ };
+ },
+});
diff --git a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/extensions/Math.js b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/extensions/Math.js
new file mode 100644
index 0000000000..73546c81e2
--- /dev/null
+++ b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/extensions/Math.js
@@ -0,0 +1,49 @@
+import { Node, mergeAttributes } from '@tiptap/core';
+import { VueNodeViewRenderer } from '@tiptap/vue-2';
+import MathNodeView from '../components/math/MathNodeView.vue';
+
+export const Math = Node.create({
+ name: 'math',
+ group: 'inline',
+ inline: true,
+
+ addAttributes() {
+ return {
+ latex: {
+ default: null,
+ parseHTML: element => element.getAttribute('data-latex'),
+ renderHTML: attributes => {
+ if (!attributes.latex) {
+ return {};
+ }
+ return { 'data-latex': attributes.latex };
+ },
+ },
+ };
+ },
+
+ parseHTML() {
+ return [{ tag: 'span[data-latex]' }];
+ },
+
+ renderHTML({ HTMLAttributes }) {
+ return ['span', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes)];
+ },
+
+ addNodeView() {
+ return VueNodeViewRenderer(MathNodeView);
+ },
+
+ addCommands() {
+ return {
+ setMath:
+ attributes =>
+ ({ commands }) => {
+ return commands.insertContent({
+ type: this.name,
+ attrs: attributes,
+ });
+ },
+ };
+ },
+});
diff --git a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/services/imageService.js b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/services/imageService.js
new file mode 100644
index 0000000000..2577312a80
--- /dev/null
+++ b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/services/imageService.js
@@ -0,0 +1,85 @@
+import { getTipTapEditorStrings } from '../TipTapEditorStrings';
+
+const MAX_FILE_SIZE_MB = 10; // I think I need review on this value, I just picked what seemed reasonable
+export const ACCEPTED_MIME_TYPES = [
+ 'image/png',
+ 'image/jpeg',
+ 'image/jpg',
+ 'image/webp',
+ 'image/svg+xml',
+];
+
+const { noFileProvided$, invalidFileType$, fileTooLarge$, fileSizeUnit$, failedToProcessImage$ } =
+ getTipTapEditorStrings();
+
+/**
+ * Validates a file based on type and size.
+ * @param {File} file - The file to validate.
+ * @returns {{isValid: boolean, error?: string}}
+ */
+export function validateFile(file) {
+ if (!file) {
+ return { isValid: false, error: noFileProvided$ };
+ }
+ if (!ACCEPTED_MIME_TYPES.includes(file.type)) {
+ return {
+ isValid: false,
+ error: invalidFileType$ + ACCEPTED_MIME_TYPES.join(', '),
+ };
+ }
+ if (file.size > MAX_FILE_SIZE_MB * 1024 * 1024) {
+ return {
+ isValid: false,
+ error: fileTooLarge$ + MAX_FILE_SIZE_MB + fileSizeUnit$,
+ };
+ }
+ return { isValid: true };
+}
+
+/**
+ * Reads a file and returns it as a Data URL.
+ * @param {File} file - The image file.
+ * @returns {Promise} A promise that resolves with the Data URL.
+ */
+function readFileAsDataURL(file) {
+ return new Promise((resolve, reject) => {
+ const reader = new FileReader();
+ reader.onload = () => resolve(reader.result);
+ reader.onerror = error => reject(error);
+ reader.readAsDataURL(file);
+ });
+}
+
+/**
+ * Gets the natural dimensions of an image from its source.
+ * @param {string} src - The image source (e.g., a Data URL).
+ * @returns {Promise<{width: number, height: number}>}
+ */
+export function getImageDimensions(src) {
+ return new Promise((resolve, reject) => {
+ const img = new window.Image();
+ img.onload = () => resolve({ width: img.width, height: img.height });
+ img.onerror = error => reject(error);
+ img.src = src;
+ });
+}
+
+/**
+ * Fully processes a file: validates, reads, and gets dimensions.
+ * @param {File} file - The file to process.
+ * @returns {Promise<{src: string, width: number, height: number, file: File}>}
+ */
+export async function processFile(file) {
+ const validation = validateFile(file);
+ if (!validation.isValid) {
+ throw new Error(validation.error);
+ }
+
+ try {
+ const src = await readFileAsDataURL(file);
+ const { width, height } = await getImageDimensions(src);
+ return { src, width, height, file };
+ } catch (error) {
+ throw new Error(failedToProcessImage$);
+ }
+}
diff --git a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/assets/icon-clearFormat.svg b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/assets/icon-clearFormat.svg
new file mode 100644
index 0000000000..dbb054ca6e
--- /dev/null
+++ b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/assets/icon-clearFormat.svg
@@ -0,0 +1,3 @@
+
diff --git a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/assets/icon-edit.svg b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/assets/icon-edit.svg
new file mode 100644
index 0000000000..63c2ca84f5
--- /dev/null
+++ b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/assets/icon-edit.svg
@@ -0,0 +1,3 @@
+
diff --git a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/assets/icon-linkOff.svg b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/assets/icon-linkOff.svg
new file mode 100644
index 0000000000..3518cdca07
--- /dev/null
+++ b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/assets/icon-linkOff.svg
@@ -0,0 +1,3 @@
+
diff --git a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/assets/icon-subscriptRTL.svg b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/assets/icon-subscriptRTL.svg
new file mode 100644
index 0000000000..f24cea89a9
--- /dev/null
+++ b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/assets/icon-subscriptRTL.svg
@@ -0,0 +1,8 @@
+
diff --git a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/assets/icon-superscriptRTL.svg b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/assets/icon-superscriptRTL.svg
new file mode 100644
index 0000000000..eeafffef79
--- /dev/null
+++ b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/assets/icon-superscriptRTL.svg
@@ -0,0 +1,7 @@
+
diff --git a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/assets/icon-trash.svg b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/assets/icon-trash.svg
new file mode 100644
index 0000000000..1e6141d04b
--- /dev/null
+++ b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/assets/icon-trash.svg
@@ -0,0 +1,3 @@
+
diff --git a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/assets/styles/code-theme-dark.css b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/assets/styles/code-theme-dark.css
new file mode 100644
index 0000000000..b25a3038d9
--- /dev/null
+++ b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/assets/styles/code-theme-dark.css
@@ -0,0 +1,80 @@
+/*
+https://github.com/microsoft/vscode/blob/main/extensions/theme-defaults/themes/dark_modern.json
+*/
+
+.ProseMirror pre {
+ padding: 1rem 1.25rem;
+ font-family: 'Consolas', 'Courier New', monospace;
+ color: #d4d4d4;
+ white-space: pre-wrap;
+ background: #1e1e1e;
+ border-radius: 0.5rem;
+}
+
+.ProseMirror pre code {
+ display: block;
+ padding: 0;
+ overflow-x: auto;
+ font-size: 0.9rem;
+ color: inherit;
+ background: none;
+}
+
+/* Comments */
+.ProseMirror .hljs-comment,
+.ProseMirror .hljs-quote {
+ color: #6a9955;
+}
+
+/* Keywords (const, let, if, return, etc.) & HTML Tags */
+.ProseMirror .hljs-keyword,
+.ProseMirror .hljs-selector-tag,
+.ProseMirror .hljs-tag .hljs-name {
+ color: #569cd6;
+}
+
+/* Storage type (const) & Built-ins */
+.ProseMirror .hljs-storage.type,
+.ProseMirror .hljs-built_in {
+ color: #c586c0;
+}
+
+/* Strings */
+.ProseMirror .hljs-string,
+.ProseMirror .hljs-symbol {
+ color: #ce9178;
+}
+
+/* Numbers & Booleans */
+.ProseMirror .hljs-number,
+.ProseMirror .hljs-literal {
+ color: #b5cea8;
+}
+
+/* Function & Class Names */
+.ProseMirror .hljs-title.function_,
+.ProseMirror .hljs-title.class_ {
+ color: #dcdcaa;
+}
+
+/* HTML Attributes (class, id, etc.) & Variables/Parameters */
+.ProseMirror .hljs-attr,
+.ProseMirror .hljs-variable,
+.ProseMirror .hljs-params,
+.ProseMirror .hljs-template-variable {
+ color: #9cdcfe;
+}
+
+/* RegEx */
+.ProseMirror .hljs-regexp {
+ color: #d16969;
+}
+
+/* Special Emphasis */
+.ProseMirror .hljs-emphasis {
+ font-style: italic;
+}
+
+.ProseMirror .hljs-strong {
+ font-weight: bold;
+}
diff --git a/jest_config/jest.conf.js b/jest_config/jest.conf.js
index 06b73f2a3c..20987fa663 100644
--- a/jest_config/jest.conf.js
+++ b/jest_config/jest.conf.js
@@ -18,6 +18,7 @@ module.exports = {
'shared/client': path.resolve(__dirname, './globalMocks/client.js'),
'shared/urls': path.resolve(__dirname, './globalMocks/urls.js'),
'^dexie$': require.resolve('dexie'),
+ '^mathlive$': 'identity-obj-proxy',
},
testEnvironment: 'jsdom',
testMatch: ['**/?(*.)+(spec|test).[jt]s?(x)'],
@@ -28,7 +29,9 @@ module.exports = {
'^.+\\.js$': '/node_modules/babel-jest',
'.*\\.(vue)$': '/node_modules/vue-jest',
},
- transformIgnorePatterns: ['/node_modules/.pnpm/(?!(vuetify|epubjs|kolibri-design-system|kolibri-constants|axios)@)'],
+ transformIgnorePatterns: [
+ '/node_modules/.pnpm/(?!(vuetify|epubjs|kolibri-design-system|kolibri-constants|axios|lowlight|@tiptap|tiptap|prosemirror-.*|unified|unist-.*|hast-.*|bail|trough|vfile.*|remark-.*|rehype-.*|mdast-.*|devlop))',
+ ],
snapshotSerializers: ['/node_modules/jest-serializer-vue'],
setupFilesAfterEnv: ['/jest_config/setup.js'],
coverageDirectory: '/coverage',
diff --git a/package.json b/package.json
index 072263e08b..d6f1092fb8 100644
--- a/package.json
+++ b/package.json
@@ -55,6 +55,10 @@
"dependencies": {
"@sentry/vue": "^7.112.2",
"@tiptap/core": "^2.14.0",
+ "@tiptap/extension-code-block-lowlight": "^2.23.0",
+ "@tiptap/extension-link": "^2.23.1",
+ "@tiptap/extension-subscript": "^2.14.0",
+ "@tiptap/extension-superscript": "^2.14.0",
"@tiptap/extension-underline": "^2.14.0",
"@tiptap/starter-kit": "^2.13.0",
"@tiptap/vue-2": "^2.13.0",
@@ -69,6 +73,7 @@
"dexie-observable": "3.0.0-beta.11",
"epubjs": "^0.3.89",
"file-saver": "^2.0.2",
+ "highlight.js": "^11.11.1",
"html2canvas": "^1.0.0-rc.5",
"i18n-iso-countries": "^7.11.3",
"intl": "1.2.5",
@@ -78,7 +83,9 @@
"kolibri-constants": "^0.2.12",
"kolibri-design-system": "5.2.0",
"lodash": "^4.17.21",
+ "lowlight": "^3.3.0",
"material-icons": "0.3.1",
+ "mathlive": "^0.105.3",
"mutex-js": "^1.1.5",
"node-vibrant": "^3.1.6",
"pako": "^2.1.0",
@@ -119,6 +126,7 @@
"babel-jest": "^29.7.0",
"babel-loader": "^9.2.1",
"circular-dependency-plugin": "^5.2.0",
+ "copy-webpack-plugin": "^13.0.0",
"css-loader": "7.1.2",
"eslint": "^8.57.0",
"eslint-config-prettier": "^10.0.1",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 38287974df..e290aa9f14 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -13,16 +13,28 @@ importers:
version: 7.120.3(vue@2.7.16)
'@tiptap/core':
specifier: ^2.14.0
- version: 2.22.3(@tiptap/pm@2.22.3)
+ version: 2.23.1(@tiptap/pm@2.23.1)
+ '@tiptap/extension-code-block-lowlight':
+ specifier: ^2.23.0
+ version: 2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))(@tiptap/extension-code-block@2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))(@tiptap/pm@2.23.1))(@tiptap/pm@2.23.1)(highlight.js@11.11.1)(lowlight@3.3.0)
+ '@tiptap/extension-link':
+ specifier: ^2.23.1
+ version: 2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))(@tiptap/pm@2.23.1)
+ '@tiptap/extension-subscript':
+ specifier: ^2.14.0
+ version: 2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))
+ '@tiptap/extension-superscript':
+ specifier: ^2.14.0
+ version: 2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))
'@tiptap/extension-underline':
specifier: ^2.14.0
- version: 2.22.3(@tiptap/core@2.22.3(@tiptap/pm@2.22.3))
+ version: 2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))
'@tiptap/starter-kit':
specifier: ^2.13.0
- version: 2.22.3
+ version: 2.23.1
'@tiptap/vue-2':
specifier: ^2.13.0
- version: 2.22.3(@tiptap/core@2.22.3(@tiptap/pm@2.22.3))(@tiptap/pm@2.22.3)(vue@2.7.16)
+ version: 2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))(@tiptap/pm@2.23.1)(vue@2.7.16)
'@toast-ui/editor':
specifier: ^2.3.1
version: 2.5.4
@@ -56,6 +68,9 @@ importers:
file-saver:
specifier: ^2.0.2
version: 2.0.5
+ highlight.js:
+ specifier: ^11.11.1
+ version: 11.11.1
html2canvas:
specifier: ^1.0.0-rc.5
version: 1.4.1
@@ -83,9 +98,15 @@ importers:
lodash:
specifier: ^4.17.21
version: 4.17.21
+ lowlight:
+ specifier: ^3.3.0
+ version: 3.3.0
material-icons:
specifier: 0.3.1
version: 0.3.1
+ mathlive:
+ specifier: ^0.105.3
+ version: 0.105.3
mutex-js:
specifier: ^1.1.5
version: 1.1.5
@@ -197,13 +218,16 @@ importers:
version: 29.7.0(@babel/core@7.28.0)
babel-loader:
specifier: ^9.2.1
- version: 9.2.1(@babel/core@7.28.0)(webpack@5.99.7)
+ version: 9.2.1(@babel/core@7.28.0)(webpack@5.99.9)
circular-dependency-plugin:
specifier: ^5.2.0
- version: 5.2.2(webpack@5.99.7)
+ version: 5.2.2(webpack@5.99.9)
+ copy-webpack-plugin:
+ specifier: ^13.0.0
+ version: 13.0.0(webpack@5.99.9)
css-loader:
specifier: 7.1.2
- version: 7.1.2(webpack@5.99.7)
+ version: 7.1.2(webpack@5.99.9)
eslint:
specifier: ^8.57.0
version: 8.57.1
@@ -212,13 +236,13 @@ importers:
version: 10.1.5(eslint@8.57.1)
eslint-import-resolver-webpack:
specifier: 0.13.8
- version: 0.13.8(eslint-plugin-import@2.32.0)(webpack@5.99.7)
+ version: 0.13.8(eslint-plugin-import@2.32.0)(webpack@5.99.9)
eslint-plugin-import:
specifier: ^2.31.0
version: 2.32.0(eslint-import-resolver-webpack@0.13.8)(eslint@8.57.1)
eslint-plugin-jest:
specifier: ^28.11.0
- version: 28.14.0(eslint@8.57.1)(jest@29.7.0(@types/node@24.0.4))(typescript@5.8.3)
+ version: 28.14.0(eslint@8.57.1)(jest@29.7.0(@types/node@24.0.10))(typescript@5.8.3)
eslint-plugin-jest-dom:
specifier: ^5.5.0
version: 5.5.0(@testing-library/dom@9.3.4)(eslint@8.57.1)
@@ -233,7 +257,7 @@ importers:
version: 5.0.2
file-loader:
specifier: ^6.2.0
- version: 6.2.0(webpack@5.99.7)
+ version: 6.2.0(webpack@5.99.9)
flush-promises:
specifier: ^1.0.2
version: 1.0.2
@@ -242,10 +266,10 @@ importers:
version: 3.0.0
jest:
specifier: ^29.7.0
- version: 29.7.0(@types/node@24.0.4)
+ version: 29.7.0(@types/node@24.0.10)
jest-cli:
specifier: ^29.7.0
- version: 29.7.0(@types/node@24.0.4)
+ version: 29.7.0(@types/node@24.0.10)
jest-each:
specifier: ^29.7.0
version: 29.7.0
@@ -257,13 +281,13 @@ importers:
version: 3.1.0
kolibri-format:
specifier: 1.0.1
- version: 1.0.1(@testing-library/dom@9.3.4)(eslint-import-resolver-webpack@0.13.8)(jest@29.7.0(@types/node@24.0.4))(postcss@8.5.6)(typescript@5.8.3)
+ version: 1.0.1(@testing-library/dom@9.3.4)(eslint-import-resolver-webpack@0.13.8)(jest@29.7.0(@types/node@24.0.10))(postcss@8.5.6)(typescript@5.8.3)
kolibri-tools:
specifier: 0.18.2
- version: 0.18.2(@testing-library/dom@9.3.4)(@types/node@24.0.4)(ejs@3.1.10)(eslint-import-resolver-webpack@0.13.8)(file-loader@6.2.0(webpack@5.99.7))(postcss@8.5.6)(typescript@5.8.3)(vue@2.7.16)
+ version: 0.18.2(@testing-library/dom@9.3.4)(@types/node@24.0.10)(ejs@3.1.10)(eslint-import-resolver-webpack@0.13.8)(file-loader@6.2.0(webpack@5.99.9))(postcss@8.5.6)(typescript@5.8.3)(vue@2.7.16)
mini-css-extract-plugin:
specifier: ^2.8.1
- version: 2.9.2(webpack@5.99.7)
+ version: 2.9.2(webpack@5.99.9)
node-sass:
specifier: 9.0.0
version: 9.0.0
@@ -278,7 +302,7 @@ importers:
version: 6.0.0(postcss@8.5.6)
postcss-loader:
specifier: ^8.1.1
- version: 8.1.1(postcss@8.5.6)(typescript@5.8.3)(webpack@5.99.7)
+ version: 8.1.1(postcss@8.5.6)(typescript@5.8.3)(webpack@5.99.9)
postcss-sass:
specifier: ^0.5.0
version: 0.5.0
@@ -287,10 +311,10 @@ importers:
version: 4.0.9(postcss@8.5.6)
sass-loader:
specifier: 16.0.5
- version: 16.0.5(node-sass@9.0.0)(webpack@5.99.7)
+ version: 16.0.5(node-sass@9.0.0)(webpack@5.99.9)
style-loader:
specifier: ^4.0.0
- version: 4.0.0(webpack@5.99.7)
+ version: 4.0.0(webpack@5.99.9)
stylelint:
specifier: ^15.11.0
version: 15.11.0(typescript@5.8.3)
@@ -323,13 +347,13 @@ importers:
version: 0.63.0
stylus-loader:
specifier: ^8.1.0
- version: 8.1.1(stylus@0.63.0)(webpack@5.99.7)
+ version: 8.1.1(stylus@0.63.0)(webpack@5.99.9)
vue-jest:
specifier: ^3.0.7
version: 3.0.7(babel-core@7.0.0-bridge.0(@babel/core@7.28.0))(vue-template-compiler@2.7.16)(vue@2.7.16)
vue-loader:
specifier: 15.11.1
- version: 15.11.1(babel-core@7.0.0-bridge.0(@babel/core@7.28.0))(css-loader@7.1.2(webpack@5.99.7))(ejs@3.1.10)(lodash@4.17.21)(vue-template-compiler@2.7.16)(webpack@5.99.7)
+ version: 15.11.1(babel-core@7.0.0-bridge.0(@babel/core@7.28.0))(css-loader@7.1.2(webpack@5.99.9))(ejs@3.1.10)(lodash@4.17.21)(vue-template-compiler@2.7.16)(webpack@5.99.9)
vue-style-loader:
specifier: ^4.1.3
version: 4.1.3
@@ -341,19 +365,19 @@ importers:
version: 4.1.0
webpack:
specifier: ^5.97.1
- version: 5.99.7(webpack-cli@6.0.1)
+ version: 5.99.9(webpack-cli@6.0.1)
webpack-cli:
specifier: ^6.0.1
- version: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.7)
+ version: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.9)
webpack-dev-server:
specifier: ^5.2.2
- version: 5.2.2(webpack-cli@6.0.1)(webpack@5.99.7)
+ version: 5.2.2(webpack-cli@6.0.1)(webpack@5.99.9)
webpack-merge:
specifier: ^6.0.1
version: 6.0.1
workbox-webpack-plugin:
specifier: ^7.3.0
- version: 7.3.0(@types/babel__core@7.20.5)(webpack@5.99.7)
+ version: 7.3.0(@types/babel__core@7.20.5)(webpack@5.99.9)
packages:
@@ -927,8 +951,8 @@ packages:
peerDependencies:
'@babel/core': ^7.0.0-0
- '@babel/plugin-transform-typescript@7.27.1':
- resolution: {integrity: sha512-Q5sT5+O4QUebHdbwKedFBEwRLb02zJ7r4A5Gg2hUoLuU3FjdMcyqcywqUrLCaDsFCxzokf7u9kuy7qz51YUuAg==}
+ '@babel/plugin-transform-typescript@7.28.0':
+ resolution: {integrity: sha512-4AEiDEBPIZvLQaWlc9liCavE0xRM0dNca41WtBeM3jgFptfUOSG9z0uteLhq6+3rq+WB6jIvUwKDTpXEHPJ2Vg==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
@@ -1009,6 +1033,10 @@ packages:
'@bcoe/v8-coverage@0.2.3':
resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==}
+ '@cortex-js/compute-engine@0.28.0':
+ resolution: {integrity: sha512-kGs74P4KVNLSqu+iVhLSAvodScZdVGoZI2kOsUjnBEFCFjlPJ1Nj5TpBz/4nwPT+viguB+g7VseXsmcxWRx23Q==}
+ engines: {node: '>=21.7.3', npm: '>=10.5.0'}
+
'@csstools/css-parser-algorithms@2.7.1':
resolution: {integrity: sha512-2SJS42gxmACHgikc1WGesXLIT8d/q2l0UFM7TaEeIzdFCE/FPMtTiizcPGGJtlPo2xuQzY09OhrLTzRxqJqwGw==}
engines: {node: ^14 || ^16 || >=18}
@@ -1212,18 +1240,12 @@ packages:
resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
engines: {node: '>=6.0.0'}
- '@jridgewell/source-map@0.3.6':
- resolution: {integrity: sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==}
-
- '@jridgewell/sourcemap-codec@1.5.0':
- resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==}
+ '@jridgewell/source-map@0.3.10':
+ resolution: {integrity: sha512-0pPkgz9dY+bijgistcTTJ5mR+ocqRXLuhXHYdzoMmmoJ2C9S46RCm2GMUbatPEUK9Yjy26IrAy8D/M00lLkv+Q==}
'@jridgewell/sourcemap-codec@1.5.4':
resolution: {integrity: sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==}
- '@jridgewell/trace-mapping@0.3.25':
- resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==}
-
'@jridgewell/trace-mapping@0.3.29':
resolution: {integrity: sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==}
@@ -1342,8 +1364,8 @@ packages:
'@rtsao/scc@1.1.0':
resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==}
- '@rushstack/eslint-patch@1.11.0':
- resolution: {integrity: sha512-zxnHvoMQVqewTJr/W4pKjF0bMGiKJv1WX7bSrkl46Hg0QjESbzBROWK0Wg4RphzSOS5Jiy7eFimmM3UgMrMZbQ==}
+ '@rushstack/eslint-patch@1.12.0':
+ resolution: {integrity: sha512-5EwMtOqvJMMa3HbmxLlF74e+3/HhwBTMcvt3nqVJgGCozO6hzIPOBlwm8mGVNR9SN2IJpxSnlxczyDjcn7qIyw==}
'@sentry-internal/feedback@7.120.3':
resolution: {integrity: sha512-ewJJIQ0mbsOX6jfiVFvqMjokxNtgP3dNwUv+4nenN+iJJPQsM6a0ocro3iscxwVdbkjw5hY3BUV2ICI5Q0UWoA==}
@@ -1420,136 +1442,161 @@ packages:
vue: ^2.6.10
vue-template-compiler: ^2.6.10
- '@tiptap/core@2.22.3':
- resolution: {integrity: sha512-czyBPXZG/ZFyObZEF1kyusGf58Ai3X8TnaxlUUn3gqLLWPy0idXZg85NETCidzi/gAxWxL9j6Pcy+zwS4pbZYQ==}
+ '@tiptap/core@2.23.1':
+ resolution: {integrity: sha512-EURGKGsEPrwxvOPi9gA+BsczvsECJNV+xgTAGWHmEtU4YJ0AulYrCX3b7FK+aiduVhThIHDoG/Mmvmb/HPLRhQ==}
peerDependencies:
'@tiptap/pm': ^2.7.0
- '@tiptap/extension-blockquote@2.22.3':
- resolution: {integrity: sha512-HvTXvqeGaANg0owk0Xxkgyc4lJMO5CZES2Lc3JJp8u5kV+HZIwd78eJ7fbKBMtkpKb4zOk4xQsHQ/TuhghJaeA==}
+ '@tiptap/extension-blockquote@2.23.1':
+ resolution: {integrity: sha512-GI3s+uFU88LWRaDG20Z9yIu2av3Usn8kw2lkm2ntwX1K6/mQBS/zkGhWr/FSwWOlMtTzYFxF4Ttb0e+hn67A/A==}
peerDependencies:
'@tiptap/core': ^2.7.0
- '@tiptap/extension-bold@2.22.3':
- resolution: {integrity: sha512-J3GxKwijD42eqCwU1SS7PK5aSgnp0wgQDetLz9izAD0RQBrKj5WZA13GnPoTTlzLU4qwjcPRV+6mvF+llH6b6A==}
+ '@tiptap/extension-bold@2.23.1':
+ resolution: {integrity: sha512-OM4RxuZeOqpYRN1G/YpXSE8tZ3sVtT2XlO3qKa74qf+htWz8W3x4X0oQCrHrRTDSAA1wbmeZU3QghAIHnbvP/A==}
peerDependencies:
'@tiptap/core': ^2.7.0
- '@tiptap/extension-bubble-menu@2.22.3':
- resolution: {integrity: sha512-8iQLNrRf3iBPKqI3dQnfvMxMfgp6y9TAbO803LihvzbIGqBaX264ES7fHtoyFIIeVjy2xFruVsTZCZofWTupGg==}
+ '@tiptap/extension-bubble-menu@2.23.1':
+ resolution: {integrity: sha512-tupuvrlZMTziVZXJuCVjLwllUnux/an9BtTYHpoRyLX9Hg0v7Kh39k9x58zJaoW8Q/Oc/qxPhbJpyOqhE1rLeg==}
peerDependencies:
'@tiptap/core': ^2.7.0
'@tiptap/pm': ^2.7.0
- '@tiptap/extension-bullet-list@2.22.3':
- resolution: {integrity: sha512-SYvLIxqmuV0kTj4/3ZFlnZ1fr9Y233qX00BKuIpGnczeFsWQmzBJo8vGm3d1IlKPCQN+jTRtDdDE1aSum8Kv2w==}
+ '@tiptap/extension-bullet-list@2.23.1':
+ resolution: {integrity: sha512-0g9U42m+boLJZP3x9KoJHDCp9WD5abaVdqNbTg9sFPDNsepb7Zaeu8AEB+yZLP/fuTI1I4ko6qkdr3UaaIYcmA==}
peerDependencies:
'@tiptap/core': ^2.7.0
- '@tiptap/extension-code-block@2.22.3':
- resolution: {integrity: sha512-twPCBpb/ygNixlSBAXgvfo+t56Ucpb8lvPDiZn+cH8OjmmO0ayBoSfSrjKWgaEWGPcXBrFAfsBRbYHyoHj7pXg==}
+ '@tiptap/extension-code-block-lowlight@2.23.1':
+ resolution: {integrity: sha512-EQwLyO1zKViSXcwdsnzurWOdVS1W3oiNuFnkxxSGtU8hlRbkDP4+dY8c/jRE2XejfJuxz7zY7iGg594d8+5/SA==}
peerDependencies:
'@tiptap/core': ^2.7.0
+ '@tiptap/extension-code-block': ^2.7.0
'@tiptap/pm': ^2.7.0
+ highlight.js: ^11
+ lowlight: ^2 || ^3
- '@tiptap/extension-code@2.22.3':
- resolution: {integrity: sha512-s+W6jHezq+n9cC40xZ3hZF6cGGSl+fBELik1b2x8+cb0WoIlqmcdWin1dgeMNrWlRZUw1aD2DNwy/PdXI5vn2g==}
+ '@tiptap/extension-code-block@2.23.1':
+ resolution: {integrity: sha512-eYzJVUR13BhSE/TYAMZihGBId+XiwhnTPqGcSFo+zx89It/vxwDLvAUn0PReMNI7ULKPTw8orUt2fVKSarb2DQ==}
peerDependencies:
'@tiptap/core': ^2.7.0
+ '@tiptap/pm': ^2.7.0
- '@tiptap/extension-document@2.22.3':
- resolution: {integrity: sha512-7MnILbhRZRyROlMUgyntzRZ/EZlqNB8fO761RNjJxR2WMb49R4yc04fz7/+f/QH/hwxoS13bKfsNUDAsDxA5Aw==}
+ '@tiptap/extension-code@2.23.1':
+ resolution: {integrity: sha512-3IOdE40m0UTR2+UXui69o/apLtutAbtzfgmMxD6q0qlRvVqz99QEfk9RPHDNlUqJtYCL4TD+sj7UclBsDdgVXA==}
peerDependencies:
'@tiptap/core': ^2.7.0
- '@tiptap/extension-dropcursor@2.22.3':
- resolution: {integrity: sha512-yQxSfTWjdUQS+bh6KiNLR9KIMsn1SElzycQe4XE+0eoaetapGtKqxfwkTbbQdNgQOU5wQG1KOda221mnPvkpAA==}
+ '@tiptap/extension-document@2.23.1':
+ resolution: {integrity: sha512-2nkIkGVsaMJkpd024E6vXK+5XNz8VOVWp/pM6bbXpuv0HnGPrfLdh4ruuFc+xTQ3WPOmpSu8ygtujt4I1o9/6g==}
+ peerDependencies:
+ '@tiptap/core': ^2.7.0
+
+ '@tiptap/extension-dropcursor@2.23.1':
+ resolution: {integrity: sha512-GyVp+o/RVrKlLdrQvtIpJGphFGogiPjcPCkAFcrfY1vDY1EYxfVZELC96gG1mUT1BO8FUD3hmbpkWi9l8/6O4A==}
peerDependencies:
'@tiptap/core': ^2.7.0
'@tiptap/pm': ^2.7.0
- '@tiptap/extension-floating-menu@2.22.3':
- resolution: {integrity: sha512-GeJRRdulxpwsshxzBkpOf/xJkLD2fa+49o+3FqRCmrm7AioC8oUcZZmzuzjLj5a3ZNGKPuJ9xxDkYWUjH4tE1g==}
+ '@tiptap/extension-floating-menu@2.23.1':
+ resolution: {integrity: sha512-GMWkpH+p/OUOk1Y5UGOnKuHSDEVBN7DhYIJiWt5g9LK/mpPeuqoCmQg3RQDgjtZXb74SlxLK2pS/3YcAnemdfQ==}
peerDependencies:
'@tiptap/core': ^2.7.0
'@tiptap/pm': ^2.7.0
- '@tiptap/extension-gapcursor@2.22.3':
- resolution: {integrity: sha512-6Q8TLL4PVGcZLn27eQazCC+be8LP8uzuz5Z5e4TpIeswPAju49cerQOdEGNFKkuYv/FelWIhXNtkWFMf4eSmyw==}
+ '@tiptap/extension-gapcursor@2.23.1':
+ resolution: {integrity: sha512-iP+TiFIGZEbOvYAs04pI14mLI4xqbt64Da91TgMF1FNZUrG+9eWKjqbcHLQREuK3Qnjn5f0DI4nOBv61FlnPmA==}
peerDependencies:
'@tiptap/core': ^2.7.0
'@tiptap/pm': ^2.7.0
- '@tiptap/extension-hard-break@2.22.3':
- resolution: {integrity: sha512-tbEji/V4Za3UhxYwB36amYhyonwe5j66iYTNRWzgjNixjrcGDbWk6cfaF9jMAgPgIDBmmtQLJY+moKskwgpnZg==}
+ '@tiptap/extension-hard-break@2.23.1':
+ resolution: {integrity: sha512-YF66EVxnBxt1bHPx6fUUSSXK1Vg+/9baJ0AfJ12hCSPCgSjUclRuNmWIH5ikVfByOmPV1xlrN9wryLoSEBcNRQ==}
peerDependencies:
'@tiptap/core': ^2.7.0
- '@tiptap/extension-heading@2.22.3':
- resolution: {integrity: sha512-+MexJD+kXtNwMDbNTFa7jCFipx1DqAdT+n9GgInqebAN9bK+CWjC+SskzZNRqeMrQ0Er7QTsi6YC09M+74sevA==}
+ '@tiptap/extension-heading@2.23.1':
+ resolution: {integrity: sha512-5BPoli9wudiAOgSyK8309jyRhFyu5vd02lNChfpHwxUudzIJ/L+0E6FcwrDcw+yXh23cx7F5SSjtFQ7AobxlDQ==}
peerDependencies:
'@tiptap/core': ^2.7.0
- '@tiptap/extension-history@2.22.3':
- resolution: {integrity: sha512-F9sC45zPw7vbjKrwSKuSLZ0ODyc/X3bGPeCa6HYLEHKfgqsdt2v2fQLvxjpmlwO2ZMrnkBkg76KDxHfVyrZ2zQ==}
+ '@tiptap/extension-history@2.23.1':
+ resolution: {integrity: sha512-1rp2CRjM+P58oGEgeUUDSk0ch67ngIGbGJOOjiBGKU9GIVhI2j4uSwsYTAa9qYMjMUI6IyH1xJpsY2hLKcBOtg==}
peerDependencies:
'@tiptap/core': ^2.7.0
'@tiptap/pm': ^2.7.0
- '@tiptap/extension-horizontal-rule@2.22.3':
- resolution: {integrity: sha512-3GvY798p9pCXUBbCebIdSmi1q80l7VZz/B6NN4uUMQ9iwxWopd8yaZ0O7xx2hM2UBzPEtY3M4FAhhpYUTXNFgQ==}
+ '@tiptap/extension-horizontal-rule@2.23.1':
+ resolution: {integrity: sha512-uHEF0jpmhtgAxjKw8/s5ipEeTnu99f9RVMGAlmcthJ5Fx9TzH0MvtH4dtBNEu5MXC7+0bNsnncWo125AAbCohg==}
peerDependencies:
'@tiptap/core': ^2.7.0
'@tiptap/pm': ^2.7.0
- '@tiptap/extension-italic@2.22.3':
- resolution: {integrity: sha512-W/rQDo7qFL7MfwfaYEcdtbk862fOmBv30qIEwVdqElBye7BFJYKtRuWBzNbG2BwKanjwMbVc/tBXF5W1sqfT7Q==}
+ '@tiptap/extension-italic@2.23.1':
+ resolution: {integrity: sha512-a+cPzffaC/1AKMmZ1Ka6l81xmTgcalf8NXfBuFCUTf5r7uI9NIgXnLo9hg+jR9F4K+bwhC4/UbMvQQzAjh0c0A==}
peerDependencies:
'@tiptap/core': ^2.7.0
- '@tiptap/extension-list-item@2.22.3':
- resolution: {integrity: sha512-B7Fze+eM1sYbGOZtDDAwAivnj1ow2wN5RqaQPC1la3wdTK4Wgp7bdzGjvUbrN6gp3zMFCEWlqP2toc/mRAHCtA==}
+ '@tiptap/extension-link@2.23.1':
+ resolution: {integrity: sha512-zMD0V8djkvwRYACzd8EvFXXNLQH5poJt6aHC9/8uest6njRhlrRjSjwG5oa+xHW4A76XfAH0A5BPj6ZxZnAUQg==}
peerDependencies:
'@tiptap/core': ^2.7.0
+ '@tiptap/pm': ^2.7.0
- '@tiptap/extension-ordered-list@2.22.3':
- resolution: {integrity: sha512-pHGkuZhV/uAAHI9vzk/lpAkbdpMT4wUR1FI17/GE3zNrogfzx0VopCQrXq4+sQVsLUW4I6Cj6VeBjm9wB6qlIw==}
+ '@tiptap/extension-list-item@2.23.1':
+ resolution: {integrity: sha512-wVrRp6KAiyjFVFGmn+ojisP64Bsd+ZPdqQBYVbebBx1skZeW0uhG60d7vUkWHi0gCgxHZDfvDbXpfnOD0INRWw==}
peerDependencies:
'@tiptap/core': ^2.7.0
- '@tiptap/extension-paragraph@2.22.3':
- resolution: {integrity: sha512-TYvgS7CweNFo/xVxsKWSt0wnm46Y8OtsfDSjnLbSC4Pj4ZNa6PU3zpvDTW+UxYakr+8zIPvI2WgLBkyTHq6oQA==}
+ '@tiptap/extension-ordered-list@2.23.1':
+ resolution: {integrity: sha512-Zp+qognyNgoaJ9bxkBwIuWJEnQ67RdsHXzv3YOdeGRbkUhd8LT6OL7P0mAuNbMBU8MwHxyJ7C7NsyzwzuVbFzA==}
peerDependencies:
'@tiptap/core': ^2.7.0
- '@tiptap/extension-strike@2.22.3':
- resolution: {integrity: sha512-I+s2Csw2cTHae2vFJiojnHK+NnQjDr6441mSlAd+e7kEly1kjZ4g7J+JMj02ajNQhr/ob8/hb5r6EdIyv2xtoA==}
+ '@tiptap/extension-paragraph@2.23.1':
+ resolution: {integrity: sha512-LLEPizt1ALE7Ek6prlJ1uhoUCT8C/a3PdZpCh3DshM1L3Kv9TENlaJL2GhFl8SVUCwHmWHvXg30+4tIRFBedaQ==}
peerDependencies:
'@tiptap/core': ^2.7.0
- '@tiptap/extension-text-style@2.22.3':
- resolution: {integrity: sha512-M3FLOUPcO8fR+rM97mR2gQ54KFkdlAUQtEPKQpO1f312gtcVdBNxgq0WgqTnBY7thWLyqQSKiAsL6y88+JddSA==}
+ '@tiptap/extension-strike@2.23.1':
+ resolution: {integrity: sha512-hAT9peYkKezRGp/EcPQKtyYQT+2XGUbb26toTr9XIBQIeQCuCpT+FirPrDMrMVWPwcJt7Rv+AzoVjDuBs9wE0A==}
peerDependencies:
'@tiptap/core': ^2.7.0
- '@tiptap/extension-text@2.22.3':
- resolution: {integrity: sha512-07cymWkPTfq6nuum88Yf90YYArbowed8nNiu0Tw3jCvwpzf9J9TDaovT+LAKuSKtrOsnNpFB/9IqUwFxZepOGw==}
+ '@tiptap/extension-subscript@2.23.1':
+ resolution: {integrity: sha512-LFUwe90E90f38aES6ka0Jg7kUG3WTMq3M+7qRu6skEx4+izVB6ub5RTvA56trQlWefWiYeJZptf8xfIKdcwGSw==}
peerDependencies:
'@tiptap/core': ^2.7.0
- '@tiptap/extension-underline@2.22.3':
- resolution: {integrity: sha512-floLjh1UbQ2pKgdwfw7qCAJ5VojvH1uqj7xW2RCv79aWYUuJCPD6UBpaBOt/jv7gXDJJ9EeV3m2Hga49CXBrEQ==}
+ '@tiptap/extension-superscript@2.23.1':
+ resolution: {integrity: sha512-us1p+AZD6B3+eWuhO83WP3Kd9MBSApOh5c4S9MEavmmQxHAvFk7sv/tuyQPgBQNxvNnpV5z0mfFEtqiMrCo22A==}
peerDependencies:
'@tiptap/core': ^2.7.0
- '@tiptap/pm@2.22.3':
- resolution: {integrity: sha512-uWPeIScnpQVCYdTnL140XgcvbT1qH288CstMJ6S0Y11lC5PclPK9CxfAipsqgWWrIK7yatxKUVCg6TzfG9zpmA==}
+ '@tiptap/extension-text-style@2.23.1':
+ resolution: {integrity: sha512-fZn1GePlL27pUFfKXKoRZo4L4pZP9dUjNNiS/eltLpbi/SenJ15UKhAoHtN1KQvNGJsWkYN49FjnnltU8qvQ+Q==}
+ peerDependencies:
+ '@tiptap/core': ^2.7.0
+
+ '@tiptap/extension-text@2.23.1':
+ resolution: {integrity: sha512-XK0D/eyS1Vm5yUrCtkS0AfgyKLJqpi8nJivCOux/JLhhC4x87R1+mI8NoFDYZJ5ic/afREPSBB8jORqOi0qIHg==}
+ peerDependencies:
+ '@tiptap/core': ^2.7.0
+
+ '@tiptap/extension-underline@2.23.1':
+ resolution: {integrity: sha512-MTG+VlGStXD3uj7iPzZU8aJrqxoQyX45WX6xTouezaZzh/NQtTyVWwJqNGE7fsMhxirpJ+at0IZmqlDTjAhEDQ==}
+ peerDependencies:
+ '@tiptap/core': ^2.7.0
+
+ '@tiptap/pm@2.23.1':
+ resolution: {integrity: sha512-iAx4rP0k4Xd9Ywh+Gpaz5IWfY2CYRpiwVXWekTHLlNRFtrVIWVpMxaQr2mvRU2g0Ca6rz5w3KzkHBMqrI3dIBA==}
- '@tiptap/starter-kit@2.22.3':
- resolution: {integrity: sha512-GkvheaR2ORnHJ9g9R6xIT38w2uppGja/iAIrXLZ9vY1QuR+0cya/ZZ5vKU6r9C2PeyBs3aKYxRD1/j3HDhuGXw==}
+ '@tiptap/starter-kit@2.23.1':
+ resolution: {integrity: sha512-rrImwzJbKSHoFa+WdNU4I0evXcMiQ4yRm737sxvNJwYItT6fXIxrbRT7nJDmtYu2TflcfT1KklEnSrzz1hhYRw==}
- '@tiptap/vue-2@2.22.3':
- resolution: {integrity: sha512-x2sv+3JbupXTdoBvgTMLexi7VLbXgDE0FoJssjfa5FsZqDw+qO1e0DG2/sUKuGCbDVTT0vm8ac/7sfgTS4WXvg==}
+ '@tiptap/vue-2@2.23.1':
+ resolution: {integrity: sha512-AgbBm0PjYj+amuZZ4fZui3hrBexg1YVTw6ppDhZJL5pyY2PeTo4ag4tRoj+Z/CPS0Cxj3hC6OHgxrMdr6rYeCw==}
peerDependencies:
'@tiptap/core': ^2.7.0
'@tiptap/pm': ^2.7.0
@@ -1624,6 +1671,9 @@ packages:
'@types/graceful-fs@4.1.9':
resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==}
+ '@types/hast@3.0.4':
+ resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==}
+
'@types/http-errors@2.0.5':
resolution: {integrity: sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==}
@@ -1655,8 +1705,8 @@ packages:
resolution: {integrity: sha512-tJxahnjm9dEI1X+hQSC5f2BSd/coZaqbIl1m3TCl0q9SVuC52XcXfV0XmoCU1+PmjyucuVITwoTnN8OlTbEXXA==}
deprecated: This is a stub types definition for localforage (https://github.com/localForage/localForage). localforage provides its own type definitions, so you don't need @types/localforage installed!
- '@types/lodash@4.17.18':
- resolution: {integrity: sha512-KJ65INaxqxmU6EoCiJmRPZC9H9RVWCRd349tXM2M3O5NA7cY6YL7c0bHAHQ93NOfTObEQ004kd2QVHs/r0+m4g==}
+ '@types/lodash@4.17.20':
+ resolution: {integrity: sha512-H3MHACvFUEiujabxhaI/ImO6gUrd8oOurg7LQtS7mbwIXA/cUqWrvBsaeJ23aZEPk1TAYkurjfMbSELfoCXlGA==}
'@types/markdown-it@14.1.2':
resolution: {integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==}
@@ -1679,8 +1729,8 @@ packages:
'@types/node@16.9.1':
resolution: {integrity: sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g==}
- '@types/node@24.0.4':
- resolution: {integrity: sha512-ulyqAkrhnuNq9pB76DRBTkcS6YsmDALy6Ua63V8OhrOBgbcYt6IOdzpw5P1+dyRIyMerzLkeYWBeOXPpA9GMAA==}
+ '@types/node@24.0.10':
+ resolution: {integrity: sha512-ENHwaH+JIRTDIEEbDK6QSQntAYGtbvdDXnMXnZaZ6k13Du1dPMmprkEHIL7ok2Wl2aZevetwTAb5S+7yIF+enA==}
'@types/normalize-package-data@2.4.4':
resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==}
@@ -1727,6 +1777,9 @@ packages:
'@types/trusted-types@2.0.7':
resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==}
+ '@types/unist@3.0.3':
+ resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==}
+
'@types/web-bluetooth@0.0.20':
resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==}
@@ -1739,41 +1792,41 @@ packages:
'@types/yargs@17.0.33':
resolution: {integrity: sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==}
- '@typescript-eslint/project-service@8.35.0':
- resolution: {integrity: sha512-41xatqRwWZuhUMF/aZm2fcUsOFKNcG28xqRSS6ZVr9BVJtGExosLAm5A1OxTjRMagx8nJqva+P5zNIGt8RIgbQ==}
+ '@typescript-eslint/project-service@8.35.1':
+ resolution: {integrity: sha512-VYxn/5LOpVxADAuP3NrnxxHYfzVtQzLKeldIhDhzC8UHaiQvYlXvKuVho1qLduFbJjjy5U5bkGwa3rUGUb1Q6Q==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
typescript: '>=4.8.4 <5.9.0'
- '@typescript-eslint/scope-manager@8.35.0':
- resolution: {integrity: sha512-+AgL5+mcoLxl1vGjwNfiWq5fLDZM1TmTPYs2UkyHfFhgERxBbqHlNjRzhThJqz+ktBqTChRYY6zwbMwy0591AA==}
+ '@typescript-eslint/scope-manager@8.35.1':
+ resolution: {integrity: sha512-s/Bpd4i7ht2934nG+UoSPlYXd08KYz3bmjLEb7Ye1UVob0d1ENiT3lY8bsCmik4RqfSbPw9xJJHbugpPpP5JUg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- '@typescript-eslint/tsconfig-utils@8.35.0':
- resolution: {integrity: sha512-04k/7247kZzFraweuEirmvUj+W3bJLI9fX6fbo1Qm2YykuBvEhRTPl8tcxlYO8kZZW+HIXfkZNoasVb8EV4jpA==}
+ '@typescript-eslint/tsconfig-utils@8.35.1':
+ resolution: {integrity: sha512-K5/U9VmT9dTHoNowWZpz+/TObS3xqC5h0xAIjXPw+MNcKV9qg6eSatEnmeAwkjHijhACH0/N7bkhKvbt1+DXWQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
typescript: '>=4.8.4 <5.9.0'
- '@typescript-eslint/types@8.35.0':
- resolution: {integrity: sha512-0mYH3emanku0vHw2aRLNGqe7EXh9WHEhi7kZzscrMDf6IIRUQ5Jk4wp1QrledE/36KtdZrVfKnE32eZCf/vaVQ==}
+ '@typescript-eslint/types@8.35.1':
+ resolution: {integrity: sha512-q/O04vVnKHfrrhNAscndAn1tuQhIkwqnaW+eu5waD5IPts2eX1dgJxgqcPx5BX109/qAz7IG6VrEPTOYKCNfRQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- '@typescript-eslint/typescript-estree@8.35.0':
- resolution: {integrity: sha512-F+BhnaBemgu1Qf8oHrxyw14wq6vbL8xwWKKMwTMwYIRmFFY/1n/9T/jpbobZL8vp7QyEUcC6xGrnAO4ua8Kp7w==}
+ '@typescript-eslint/typescript-estree@8.35.1':
+ resolution: {integrity: sha512-Vvpuvj4tBxIka7cPs6Y1uvM7gJgdF5Uu9F+mBJBPY4MhvjrjWGK4H0lVgLJd/8PWZ23FTqsaJaLEkBCFUk8Y9g==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
typescript: '>=4.8.4 <5.9.0'
- '@typescript-eslint/utils@8.35.0':
- resolution: {integrity: sha512-nqoMu7WWM7ki5tPgLVsmPM8CkqtoPUG6xXGeefM5t4x3XumOEKMoUZPdi+7F+/EotukN4R9OWdmDxN80fqoZeg==}
+ '@typescript-eslint/utils@8.35.1':
+ resolution: {integrity: sha512-lhnwatFmOFcazAsUm3ZnZFpXSxiwoa1Lj50HphnDe1Et01NF4+hrdXONSUHIcbVu2eFb1bAf+5yjXkGVkXBKAQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
typescript: '>=4.8.4 <5.9.0'
- '@typescript-eslint/visitor-keys@8.35.0':
- resolution: {integrity: sha512-zTh2+1Y8ZpmeQaQVIc/ZZxsx8UzgKJyNg1PTvjzC7WMhPSVS8bfDX34k1SrwOf016qd5RU3az2UxUNue3IfQ5g==}
+ '@typescript-eslint/visitor-keys@8.35.1':
+ resolution: {integrity: sha512-VRwixir4zBWCSTP/ljEo091lbpypz57PoeAQ9imjG+vbeof9LplljsL1mos4ccG6H9IjfrVGM359RozUnuFhpw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@ungap/structured-clone@1.3.0':
@@ -2560,6 +2613,10 @@ packages:
commondir@1.0.1:
resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==}
+ complex-esm@2.1.1-esm1:
+ resolution: {integrity: sha512-IShBEWHILB9s7MnfyevqNGxV0A1cfcSnewL/4uPFiSxkcQL4Mm3FxJ0pXMtCXuWLjYz3lRRyk6OfkeDZcjD6nw==}
+ engines: {node: '>=16.14.2', npm: '>=8.5.0'}
+
compressible@2.0.18:
resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==}
engines: {node: '>= 0.6'}
@@ -2781,8 +2838,14 @@ packages:
resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==}
engines: {node: '>= 0.6'}
- core-js-compat@3.44.0:
- resolution: {integrity: sha512-JepmAj2zfl6ogy34qfWtcE7nHKAJnKsQFRn++scjVS2bZFllwptzw61BZcZFYBPpUznLfAvh0LGhxKppk04ClA==}
+ copy-webpack-plugin@13.0.0:
+ resolution: {integrity: sha512-FgR/h5a6hzJqATDGd9YG41SeDViH+0bkHn6WNXCi5zKAZkeESeSxLySSsFLHqLEVCh0E+rITmCf0dusXWYukeQ==}
+ engines: {node: '>= 18.12.0'}
+ peerDependencies:
+ webpack: ^5.1.0
+
+ core-js-compat@3.43.0:
+ resolution: {integrity: sha512-2GML2ZsCc5LR7hZYz4AXmjQw8zuy2T//2QntwdnpuYI7jteT6GVYJL7F6C2C57R7gSYrcqVW3lAALefdbhBLDA==}
core-js@2.6.12:
resolution: {integrity: sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==}
@@ -2896,8 +2959,8 @@ packages:
lightningcss:
optional: true
- css-select@5.1.0:
- resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==}
+ css-select@5.2.2:
+ resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==}
css-tree@2.2.1:
resolution: {integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==}
@@ -2911,8 +2974,8 @@ packages:
resolution: {integrity: sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==}
engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0}
- css-what@6.1.0:
- resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==}
+ css-what@6.2.2:
+ resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==}
engines: {node: '>= 6'}
css.escape@1.5.1:
@@ -3106,6 +3169,10 @@ packages:
resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==}
engines: {node: '>= 0.8'}
+ dequal@2.0.3:
+ resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
+ engines: {node: '>=6'}
+
destroy@1.2.0:
resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==}
engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16}
@@ -3117,6 +3184,9 @@ packages:
detect-node@2.1.0:
resolution: {integrity: sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==}
+ devlop@1.1.0:
+ resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==}
+
dexie-observable@3.0.0-beta.11:
resolution: {integrity: sha512-mKwSYy54Kj73Njp3Rs+GoldLxyDJK1LF7niBkZxSenGAlBCXB5RxafH2Mg6Ay0B1pLlDYvJCWH31s88/Uz0WSg==}
peerDependencies:
@@ -3206,8 +3276,8 @@ packages:
engines: {node: '>=0.10.0'}
hasBin: true
- electron-to-chromium@1.5.174:
- resolution: {integrity: sha512-HE43yYdUUiJVjewV2A9EP8o89Kb4AqMKplMQP2IxEPUws1Etu/ZkdsgUDabUZ/WmbP4ZbvJDOcunvbBUPPIfmw==}
+ electron-to-chromium@1.5.178:
+ resolution: {integrity: sha512-wObbz/ar3Bc6e4X5vf0iO8xTN8YAjN/tgiAOJLr7yjYFtP9wAjq8Mb5h0yn6kResir+VYx2DXBj9NNobs0ETSA==}
emittery@0.13.1:
resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==}
@@ -3605,6 +3675,14 @@ packages:
fb-watchman@2.0.2:
resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==}
+ fdir@6.4.6:
+ resolution: {integrity: sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==}
+ peerDependencies:
+ picomatch: ^3 || ^4
+ peerDependenciesMeta:
+ picomatch:
+ optional: true
+
file-entry-cache@6.0.1:
resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==}
engines: {node: ^10.12.0 || >=12.0.0}
@@ -3689,8 +3767,8 @@ packages:
flatted@3.3.3:
resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==}
- flow-parser@0.274.0:
- resolution: {integrity: sha512-pwmoGcWUSyamhv1DWhSFBROYqBfVJ/XAjqAdcrKSaisn5vI5dQ0Ni0Lawrp03TE2ZPC69vseFdeWkYlpCAqxtw==}
+ flow-parser@0.274.2:
+ resolution: {integrity: sha512-kCjoA1h5j+Ttu/9fekY9XzeKPG8SvNtxigiCkezmDIOlcKr+d9LysczrPylEeSYINE3sLlX45W5vT2CroD6sWA==}
engines: {node: '>=0.4.0'}
flush-promises@1.0.2:
@@ -3971,6 +4049,10 @@ packages:
resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
hasBin: true
+ highlight.js@11.11.1:
+ resolution: {integrity: sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==}
+ engines: {node: '>=12.0.0'}
+
hosted-git-info@2.8.9:
resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==}
@@ -4814,6 +4896,9 @@ packages:
linkify-it@5.0.0:
resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==}
+ linkifyjs@4.3.1:
+ resolution: {integrity: sha512-DRSlB9DKVW04c4SUdGvKK5FR6be45lTU9M76JnngqPeeGDqPwYc0zdUErtsNVMtxPXgUWV4HbXbnC4sNyBxkYg==}
+
load-bmfont@1.4.2:
resolution: {integrity: sha512-qElWkmjW9Oq1F9EI5Gt7aD9zcdHb9spJCW1L/dmPf7KzCCEJxq8nhHz5eCgI9aMf7vrG/wyaCqdsI+Iy9ZTlog==}
@@ -4897,6 +4982,9 @@ packages:
resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
hasBin: true
+ lowlight@3.3.0:
+ resolution: {integrity: sha512-0JNhgFoPvP6U6lE/UdVsSq99tn6DhjjpAj5MxG49ewd2mOBVtwWYIT8ClyABhq198aXXODMU6Ox8DrGy/CpTZQ==}
+
lru-cache@10.4.3:
resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
@@ -4965,6 +5053,9 @@ packages:
resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
engines: {node: '>= 0.4'}
+ mathlive@0.105.3:
+ resolution: {integrity: sha512-eEnJIlRm1ga18ymY79di5Iuc161CzHs3PTXIg8WUHeEt/jpxFHs2CPVYRNxAzOo+5t4S7lA+HDretW4i5dsTmg==}
+
mathml-tag-names@2.1.3:
resolution: {integrity: sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==}
@@ -4977,8 +5068,8 @@ packages:
mdn-data@2.12.2:
resolution: {integrity: sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==}
- mdn-data@2.21.0:
- resolution: {integrity: sha512-+ZKPQezM5vYJIkCxaC+4DTnRrVZR1CgsKLu5zsQERQx6Tea8Y+wMx5A24rq8A8NepCeatIQufVAekKNgiBMsGQ==}
+ mdn-data@2.22.0:
+ resolution: {integrity: sha512-IwcXqjPl4kgZbQH1WLb97/Pjt7XwPDSHnXsjENPhwx68bBf/Dw1/PwM8paXnFq974V1d8qP4o9ViVQqZuPAlCw==}
mdurl@2.0.0:
resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==}
@@ -5861,8 +5952,8 @@ packages:
engines: {node: '>=10.13.0'}
hasBin: true
- prettier@3.6.1:
- resolution: {integrity: sha512-5xGWRa90Sp2+x1dQtNpIpeOQpTDBs9cZDmA/qs2vDNN2i18PdapqY7CmBeyLlMuGqXJRIOPaCaVZTLNQRWUH/A==}
+ prettier@3.6.2:
+ resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==}
engines: {node: '>=14'}
hasBin: true
@@ -6928,6 +7019,10 @@ packages:
tinycolor2@1.6.0:
resolution: {integrity: sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==}
+ tinyglobby@0.2.14:
+ resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==}
+ engines: {node: '>=12.0.0'}
+
tippy.js@4.3.5:
resolution: {integrity: sha512-NDq3efte8nGK6BOJ1dDN1/WelAwfmh3UtIYXXck6+SxLzbIQNZE/cmRSnwScZ/FyiKdIcvFHvYUgqmoGx8CcyA==}
@@ -7414,8 +7509,8 @@ packages:
resolution: {integrity: sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==}
engines: {node: '>=10.13.0'}
- webpack@5.99.7:
- resolution: {integrity: sha512-CNqKBRMQjwcmKR0idID5va1qlhrqVUKpovi+Ec79ksW8ux7iS1+A6VqzfZXgVYCFRKl7XL5ap3ZoMpwBJxcg0w==}
+ webpack@5.99.9:
+ resolution: {integrity: sha512-brOPwM3JnmOa+7kd3NsmOUOwbDAj8FT9xDsG3IW0MgbN9yZV7Oi/s/+MNQ/EcSMqw7qfoRyXPoeEWT8zLVdVGg==}
engines: {node: '>=10.13.0'}
hasBin: true
peerDependencies:
@@ -7559,8 +7654,8 @@ packages:
resolution: {integrity: sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==}
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
- ws@8.18.2:
- resolution: {integrity: sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==}
+ ws@8.18.3:
+ resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==}
engines: {node: '>=10.0.0'}
peerDependencies:
bufferutil: ^4.0.1
@@ -8295,7 +8390,7 @@ snapshots:
'@babel/core': 7.28.0
'@babel/helper-plugin-utils': 7.27.1
- '@babel/plugin-transform-typescript@7.27.1(@babel/core@7.28.0)':
+ '@babel/plugin-transform-typescript@7.28.0(@babel/core@7.28.0)':
dependencies:
'@babel/core': 7.28.0
'@babel/helper-annotate-as-pure': 7.27.3
@@ -8400,7 +8495,7 @@ snapshots:
babel-plugin-polyfill-corejs2: 0.4.14(@babel/core@7.28.0)
babel-plugin-polyfill-corejs3: 0.13.0(@babel/core@7.28.0)
babel-plugin-polyfill-regenerator: 0.6.5(@babel/core@7.28.0)
- core-js-compat: 3.44.0
+ core-js-compat: 3.43.0
semver: 6.3.1
transitivePeerDependencies:
- supports-color
@@ -8426,7 +8521,7 @@ snapshots:
'@babel/helper-validator-option': 7.27.1
'@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.0)
'@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.28.0)
- '@babel/plugin-transform-typescript': 7.27.1(@babel/core@7.28.0)
+ '@babel/plugin-transform-typescript': 7.28.0(@babel/core@7.28.0)
transitivePeerDependencies:
- supports-color
@@ -8470,6 +8565,11 @@ snapshots:
'@bcoe/v8-coverage@0.2.3': {}
+ '@cortex-js/compute-engine@0.28.0':
+ dependencies:
+ complex-esm: 2.1.1-esm1
+ decimal.js: 10.5.0
+
'@csstools/css-parser-algorithms@2.7.1(@csstools/css-tokenizer@2.4.1)':
dependencies:
'@csstools/css-tokenizer': 2.4.1
@@ -8570,7 +8670,7 @@ snapshots:
'@jest/console@29.7.0':
dependencies:
'@jest/types': 29.6.3
- '@types/node': 24.0.4
+ '@types/node': 24.0.10
chalk: 4.1.2
jest-message-util: 29.7.0
jest-util: 29.7.0
@@ -8583,14 +8683,14 @@ snapshots:
'@jest/test-result': 29.7.0
'@jest/transform': 29.7.0
'@jest/types': 29.6.3
- '@types/node': 24.0.4
+ '@types/node': 24.0.10
ansi-escapes: 4.3.2
chalk: 4.1.2
ci-info: 3.9.0
exit: 0.1.2
graceful-fs: 4.2.11
jest-changed-files: 29.7.0
- jest-config: 29.7.0(@types/node@24.0.4)
+ jest-config: 29.7.0(@types/node@24.0.10)
jest-haste-map: 29.7.0
jest-message-util: 29.7.0
jest-regex-util: 29.6.3
@@ -8615,7 +8715,7 @@ snapshots:
dependencies:
'@jest/fake-timers': 29.7.0
'@jest/types': 29.6.3
- '@types/node': 24.0.4
+ '@types/node': 24.0.10
jest-mock: 29.7.0
'@jest/expect-utils@29.7.0':
@@ -8633,7 +8733,7 @@ snapshots:
dependencies:
'@jest/types': 29.6.3
'@sinonjs/fake-timers': 10.3.0
- '@types/node': 24.0.4
+ '@types/node': 24.0.10
jest-message-util: 29.7.0
jest-mock: 29.7.0
jest-util: 29.7.0
@@ -8655,7 +8755,7 @@ snapshots:
'@jest/transform': 29.7.0
'@jest/types': 29.6.3
'@jridgewell/trace-mapping': 0.3.29
- '@types/node': 24.0.4
+ '@types/node': 24.0.10
chalk: 4.1.2
collect-v8-coverage: 1.0.2
exit: 0.1.2
@@ -8704,7 +8804,7 @@ snapshots:
dependencies:
'@babel/core': 7.28.0
'@jest/types': 29.6.3
- '@jridgewell/trace-mapping': 0.3.25
+ '@jridgewell/trace-mapping': 0.3.29
babel-plugin-istanbul: 6.1.1
chalk: 4.1.2
convert-source-map: 2.0.0
@@ -8725,7 +8825,7 @@ snapshots:
'@jest/schemas': 29.6.3
'@types/istanbul-lib-coverage': 2.0.6
'@types/istanbul-reports': 3.0.4
- '@types/node': 24.0.4
+ '@types/node': 24.0.10
'@types/yargs': 17.0.33
chalk: 4.1.2
@@ -8816,20 +8916,13 @@ snapshots:
'@jridgewell/resolve-uri@3.1.2': {}
- '@jridgewell/source-map@0.3.6':
+ '@jridgewell/source-map@0.3.10':
dependencies:
'@jridgewell/gen-mapping': 0.3.12
- '@jridgewell/trace-mapping': 0.3.25
-
- '@jridgewell/sourcemap-codec@1.5.0': {}
+ '@jridgewell/trace-mapping': 0.3.29
'@jridgewell/sourcemap-codec@1.5.4': {}
- '@jridgewell/trace-mapping@0.3.25':
- dependencies:
- '@jridgewell/resolve-uri': 3.1.2
- '@jridgewell/sourcemap-codec': 1.5.0
-
'@jridgewell/trace-mapping@0.3.29':
dependencies:
'@jridgewell/resolve-uri': 3.1.2
@@ -8946,7 +9039,7 @@ snapshots:
'@rtsao/scc@1.1.0': {}
- '@rushstack/eslint-patch@1.11.0': {}
+ '@rushstack/eslint-patch@1.12.0': {}
'@sentry-internal/feedback@7.120.3':
dependencies:
@@ -9061,108 +9154,130 @@ snapshots:
vue: 2.7.16
vue-template-compiler: 2.7.16
- '@tiptap/core@2.22.3(@tiptap/pm@2.22.3)':
+ '@tiptap/core@2.23.1(@tiptap/pm@2.23.1)':
dependencies:
- '@tiptap/pm': 2.22.3
+ '@tiptap/pm': 2.23.1
- '@tiptap/extension-blockquote@2.22.3(@tiptap/core@2.22.3(@tiptap/pm@2.22.3))':
+ '@tiptap/extension-blockquote@2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))':
dependencies:
- '@tiptap/core': 2.22.3(@tiptap/pm@2.22.3)
+ '@tiptap/core': 2.23.1(@tiptap/pm@2.23.1)
- '@tiptap/extension-bold@2.22.3(@tiptap/core@2.22.3(@tiptap/pm@2.22.3))':
+ '@tiptap/extension-bold@2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))':
dependencies:
- '@tiptap/core': 2.22.3(@tiptap/pm@2.22.3)
+ '@tiptap/core': 2.23.1(@tiptap/pm@2.23.1)
- '@tiptap/extension-bubble-menu@2.22.3(@tiptap/core@2.22.3(@tiptap/pm@2.22.3))(@tiptap/pm@2.22.3)':
+ '@tiptap/extension-bubble-menu@2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))(@tiptap/pm@2.23.1)':
dependencies:
- '@tiptap/core': 2.22.3(@tiptap/pm@2.22.3)
- '@tiptap/pm': 2.22.3
+ '@tiptap/core': 2.23.1(@tiptap/pm@2.23.1)
+ '@tiptap/pm': 2.23.1
tippy.js: 6.3.7
- '@tiptap/extension-bullet-list@2.22.3(@tiptap/core@2.22.3(@tiptap/pm@2.22.3))':
+ '@tiptap/extension-bullet-list@2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))':
+ dependencies:
+ '@tiptap/core': 2.23.1(@tiptap/pm@2.23.1)
+
+ '@tiptap/extension-code-block-lowlight@2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))(@tiptap/extension-code-block@2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))(@tiptap/pm@2.23.1))(@tiptap/pm@2.23.1)(highlight.js@11.11.1)(lowlight@3.3.0)':
dependencies:
- '@tiptap/core': 2.22.3(@tiptap/pm@2.22.3)
+ '@tiptap/core': 2.23.1(@tiptap/pm@2.23.1)
+ '@tiptap/extension-code-block': 2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))(@tiptap/pm@2.23.1)
+ '@tiptap/pm': 2.23.1
+ highlight.js: 11.11.1
+ lowlight: 3.3.0
- '@tiptap/extension-code-block@2.22.3(@tiptap/core@2.22.3(@tiptap/pm@2.22.3))(@tiptap/pm@2.22.3)':
+ '@tiptap/extension-code-block@2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))(@tiptap/pm@2.23.1)':
dependencies:
- '@tiptap/core': 2.22.3(@tiptap/pm@2.22.3)
- '@tiptap/pm': 2.22.3
+ '@tiptap/core': 2.23.1(@tiptap/pm@2.23.1)
+ '@tiptap/pm': 2.23.1
- '@tiptap/extension-code@2.22.3(@tiptap/core@2.22.3(@tiptap/pm@2.22.3))':
+ '@tiptap/extension-code@2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))':
dependencies:
- '@tiptap/core': 2.22.3(@tiptap/pm@2.22.3)
+ '@tiptap/core': 2.23.1(@tiptap/pm@2.23.1)
- '@tiptap/extension-document@2.22.3(@tiptap/core@2.22.3(@tiptap/pm@2.22.3))':
+ '@tiptap/extension-document@2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))':
dependencies:
- '@tiptap/core': 2.22.3(@tiptap/pm@2.22.3)
+ '@tiptap/core': 2.23.1(@tiptap/pm@2.23.1)
- '@tiptap/extension-dropcursor@2.22.3(@tiptap/core@2.22.3(@tiptap/pm@2.22.3))(@tiptap/pm@2.22.3)':
+ '@tiptap/extension-dropcursor@2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))(@tiptap/pm@2.23.1)':
dependencies:
- '@tiptap/core': 2.22.3(@tiptap/pm@2.22.3)
- '@tiptap/pm': 2.22.3
+ '@tiptap/core': 2.23.1(@tiptap/pm@2.23.1)
+ '@tiptap/pm': 2.23.1
- '@tiptap/extension-floating-menu@2.22.3(@tiptap/core@2.22.3(@tiptap/pm@2.22.3))(@tiptap/pm@2.22.3)':
+ '@tiptap/extension-floating-menu@2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))(@tiptap/pm@2.23.1)':
dependencies:
- '@tiptap/core': 2.22.3(@tiptap/pm@2.22.3)
- '@tiptap/pm': 2.22.3
+ '@tiptap/core': 2.23.1(@tiptap/pm@2.23.1)
+ '@tiptap/pm': 2.23.1
tippy.js: 6.3.7
- '@tiptap/extension-gapcursor@2.22.3(@tiptap/core@2.22.3(@tiptap/pm@2.22.3))(@tiptap/pm@2.22.3)':
+ '@tiptap/extension-gapcursor@2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))(@tiptap/pm@2.23.1)':
+ dependencies:
+ '@tiptap/core': 2.23.1(@tiptap/pm@2.23.1)
+ '@tiptap/pm': 2.23.1
+
+ '@tiptap/extension-hard-break@2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))':
dependencies:
- '@tiptap/core': 2.22.3(@tiptap/pm@2.22.3)
- '@tiptap/pm': 2.22.3
+ '@tiptap/core': 2.23.1(@tiptap/pm@2.23.1)
- '@tiptap/extension-hard-break@2.22.3(@tiptap/core@2.22.3(@tiptap/pm@2.22.3))':
+ '@tiptap/extension-heading@2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))':
dependencies:
- '@tiptap/core': 2.22.3(@tiptap/pm@2.22.3)
+ '@tiptap/core': 2.23.1(@tiptap/pm@2.23.1)
- '@tiptap/extension-heading@2.22.3(@tiptap/core@2.22.3(@tiptap/pm@2.22.3))':
+ '@tiptap/extension-history@2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))(@tiptap/pm@2.23.1)':
dependencies:
- '@tiptap/core': 2.22.3(@tiptap/pm@2.22.3)
+ '@tiptap/core': 2.23.1(@tiptap/pm@2.23.1)
+ '@tiptap/pm': 2.23.1
- '@tiptap/extension-history@2.22.3(@tiptap/core@2.22.3(@tiptap/pm@2.22.3))(@tiptap/pm@2.22.3)':
+ '@tiptap/extension-horizontal-rule@2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))(@tiptap/pm@2.23.1)':
dependencies:
- '@tiptap/core': 2.22.3(@tiptap/pm@2.22.3)
- '@tiptap/pm': 2.22.3
+ '@tiptap/core': 2.23.1(@tiptap/pm@2.23.1)
+ '@tiptap/pm': 2.23.1
- '@tiptap/extension-horizontal-rule@2.22.3(@tiptap/core@2.22.3(@tiptap/pm@2.22.3))(@tiptap/pm@2.22.3)':
+ '@tiptap/extension-italic@2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))':
dependencies:
- '@tiptap/core': 2.22.3(@tiptap/pm@2.22.3)
- '@tiptap/pm': 2.22.3
+ '@tiptap/core': 2.23.1(@tiptap/pm@2.23.1)
- '@tiptap/extension-italic@2.22.3(@tiptap/core@2.22.3(@tiptap/pm@2.22.3))':
+ '@tiptap/extension-link@2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))(@tiptap/pm@2.23.1)':
dependencies:
- '@tiptap/core': 2.22.3(@tiptap/pm@2.22.3)
+ '@tiptap/core': 2.23.1(@tiptap/pm@2.23.1)
+ '@tiptap/pm': 2.23.1
+ linkifyjs: 4.3.1
- '@tiptap/extension-list-item@2.22.3(@tiptap/core@2.22.3(@tiptap/pm@2.22.3))':
+ '@tiptap/extension-list-item@2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))':
dependencies:
- '@tiptap/core': 2.22.3(@tiptap/pm@2.22.3)
+ '@tiptap/core': 2.23.1(@tiptap/pm@2.23.1)
- '@tiptap/extension-ordered-list@2.22.3(@tiptap/core@2.22.3(@tiptap/pm@2.22.3))':
+ '@tiptap/extension-ordered-list@2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))':
dependencies:
- '@tiptap/core': 2.22.3(@tiptap/pm@2.22.3)
+ '@tiptap/core': 2.23.1(@tiptap/pm@2.23.1)
- '@tiptap/extension-paragraph@2.22.3(@tiptap/core@2.22.3(@tiptap/pm@2.22.3))':
+ '@tiptap/extension-paragraph@2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))':
dependencies:
- '@tiptap/core': 2.22.3(@tiptap/pm@2.22.3)
+ '@tiptap/core': 2.23.1(@tiptap/pm@2.23.1)
- '@tiptap/extension-strike@2.22.3(@tiptap/core@2.22.3(@tiptap/pm@2.22.3))':
+ '@tiptap/extension-strike@2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))':
dependencies:
- '@tiptap/core': 2.22.3(@tiptap/pm@2.22.3)
+ '@tiptap/core': 2.23.1(@tiptap/pm@2.23.1)
- '@tiptap/extension-text-style@2.22.3(@tiptap/core@2.22.3(@tiptap/pm@2.22.3))':
+ '@tiptap/extension-subscript@2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))':
dependencies:
- '@tiptap/core': 2.22.3(@tiptap/pm@2.22.3)
+ '@tiptap/core': 2.23.1(@tiptap/pm@2.23.1)
- '@tiptap/extension-text@2.22.3(@tiptap/core@2.22.3(@tiptap/pm@2.22.3))':
+ '@tiptap/extension-superscript@2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))':
dependencies:
- '@tiptap/core': 2.22.3(@tiptap/pm@2.22.3)
+ '@tiptap/core': 2.23.1(@tiptap/pm@2.23.1)
- '@tiptap/extension-underline@2.22.3(@tiptap/core@2.22.3(@tiptap/pm@2.22.3))':
+ '@tiptap/extension-text-style@2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))':
dependencies:
- '@tiptap/core': 2.22.3(@tiptap/pm@2.22.3)
+ '@tiptap/core': 2.23.1(@tiptap/pm@2.23.1)
- '@tiptap/pm@2.22.3':
+ '@tiptap/extension-text@2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))':
+ dependencies:
+ '@tiptap/core': 2.23.1(@tiptap/pm@2.23.1)
+
+ '@tiptap/extension-underline@2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))':
+ dependencies:
+ '@tiptap/core': 2.23.1(@tiptap/pm@2.23.1)
+
+ '@tiptap/pm@2.23.1':
dependencies:
prosemirror-changeset: 2.3.1
prosemirror-collab: 1.3.1
@@ -9183,36 +9298,36 @@ snapshots:
prosemirror-transform: 1.10.4
prosemirror-view: 1.40.0
- '@tiptap/starter-kit@2.22.3':
- dependencies:
- '@tiptap/core': 2.22.3(@tiptap/pm@2.22.3)
- '@tiptap/extension-blockquote': 2.22.3(@tiptap/core@2.22.3(@tiptap/pm@2.22.3))
- '@tiptap/extension-bold': 2.22.3(@tiptap/core@2.22.3(@tiptap/pm@2.22.3))
- '@tiptap/extension-bullet-list': 2.22.3(@tiptap/core@2.22.3(@tiptap/pm@2.22.3))
- '@tiptap/extension-code': 2.22.3(@tiptap/core@2.22.3(@tiptap/pm@2.22.3))
- '@tiptap/extension-code-block': 2.22.3(@tiptap/core@2.22.3(@tiptap/pm@2.22.3))(@tiptap/pm@2.22.3)
- '@tiptap/extension-document': 2.22.3(@tiptap/core@2.22.3(@tiptap/pm@2.22.3))
- '@tiptap/extension-dropcursor': 2.22.3(@tiptap/core@2.22.3(@tiptap/pm@2.22.3))(@tiptap/pm@2.22.3)
- '@tiptap/extension-gapcursor': 2.22.3(@tiptap/core@2.22.3(@tiptap/pm@2.22.3))(@tiptap/pm@2.22.3)
- '@tiptap/extension-hard-break': 2.22.3(@tiptap/core@2.22.3(@tiptap/pm@2.22.3))
- '@tiptap/extension-heading': 2.22.3(@tiptap/core@2.22.3(@tiptap/pm@2.22.3))
- '@tiptap/extension-history': 2.22.3(@tiptap/core@2.22.3(@tiptap/pm@2.22.3))(@tiptap/pm@2.22.3)
- '@tiptap/extension-horizontal-rule': 2.22.3(@tiptap/core@2.22.3(@tiptap/pm@2.22.3))(@tiptap/pm@2.22.3)
- '@tiptap/extension-italic': 2.22.3(@tiptap/core@2.22.3(@tiptap/pm@2.22.3))
- '@tiptap/extension-list-item': 2.22.3(@tiptap/core@2.22.3(@tiptap/pm@2.22.3))
- '@tiptap/extension-ordered-list': 2.22.3(@tiptap/core@2.22.3(@tiptap/pm@2.22.3))
- '@tiptap/extension-paragraph': 2.22.3(@tiptap/core@2.22.3(@tiptap/pm@2.22.3))
- '@tiptap/extension-strike': 2.22.3(@tiptap/core@2.22.3(@tiptap/pm@2.22.3))
- '@tiptap/extension-text': 2.22.3(@tiptap/core@2.22.3(@tiptap/pm@2.22.3))
- '@tiptap/extension-text-style': 2.22.3(@tiptap/core@2.22.3(@tiptap/pm@2.22.3))
- '@tiptap/pm': 2.22.3
-
- '@tiptap/vue-2@2.22.3(@tiptap/core@2.22.3(@tiptap/pm@2.22.3))(@tiptap/pm@2.22.3)(vue@2.7.16)':
- dependencies:
- '@tiptap/core': 2.22.3(@tiptap/pm@2.22.3)
- '@tiptap/extension-bubble-menu': 2.22.3(@tiptap/core@2.22.3(@tiptap/pm@2.22.3))(@tiptap/pm@2.22.3)
- '@tiptap/extension-floating-menu': 2.22.3(@tiptap/core@2.22.3(@tiptap/pm@2.22.3))(@tiptap/pm@2.22.3)
- '@tiptap/pm': 2.22.3
+ '@tiptap/starter-kit@2.23.1':
+ dependencies:
+ '@tiptap/core': 2.23.1(@tiptap/pm@2.23.1)
+ '@tiptap/extension-blockquote': 2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))
+ '@tiptap/extension-bold': 2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))
+ '@tiptap/extension-bullet-list': 2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))
+ '@tiptap/extension-code': 2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))
+ '@tiptap/extension-code-block': 2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))(@tiptap/pm@2.23.1)
+ '@tiptap/extension-document': 2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))
+ '@tiptap/extension-dropcursor': 2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))(@tiptap/pm@2.23.1)
+ '@tiptap/extension-gapcursor': 2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))(@tiptap/pm@2.23.1)
+ '@tiptap/extension-hard-break': 2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))
+ '@tiptap/extension-heading': 2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))
+ '@tiptap/extension-history': 2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))(@tiptap/pm@2.23.1)
+ '@tiptap/extension-horizontal-rule': 2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))(@tiptap/pm@2.23.1)
+ '@tiptap/extension-italic': 2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))
+ '@tiptap/extension-list-item': 2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))
+ '@tiptap/extension-ordered-list': 2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))
+ '@tiptap/extension-paragraph': 2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))
+ '@tiptap/extension-strike': 2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))
+ '@tiptap/extension-text': 2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))
+ '@tiptap/extension-text-style': 2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))
+ '@tiptap/pm': 2.23.1
+
+ '@tiptap/vue-2@2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))(@tiptap/pm@2.23.1)(vue@2.7.16)':
+ dependencies:
+ '@tiptap/core': 2.23.1(@tiptap/pm@2.23.1)
+ '@tiptap/extension-bubble-menu': 2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))(@tiptap/pm@2.23.1)
+ '@tiptap/extension-floating-menu': 2.23.1(@tiptap/core@2.23.1(@tiptap/pm@2.23.1))(@tiptap/pm@2.23.1)
+ '@tiptap/pm': 2.23.1
vue: 2.7.16
vue-ts-types: 1.6.2(vue@2.7.16)
@@ -9255,11 +9370,11 @@ snapshots:
'@types/body-parser@1.19.6':
dependencies:
'@types/connect': 3.4.38
- '@types/node': 24.0.4
+ '@types/node': 24.0.10
'@types/bonjour@3.5.13':
dependencies:
- '@types/node': 24.0.4
+ '@types/node': 24.0.10
'@types/codemirror@0.0.71':
dependencies:
@@ -9268,11 +9383,11 @@ snapshots:
'@types/connect-history-api-fallback@1.5.4':
dependencies:
'@types/express-serve-static-core': 4.19.6
- '@types/node': 24.0.4
+ '@types/node': 24.0.10
'@types/connect@3.4.38':
dependencies:
- '@types/node': 24.0.4
+ '@types/node': 24.0.10
'@types/eslint-scope@3.7.7':
dependencies:
@@ -9290,7 +9405,7 @@ snapshots:
'@types/express-serve-static-core@4.19.6':
dependencies:
- '@types/node': 24.0.4
+ '@types/node': 24.0.10
'@types/qs': 6.14.0
'@types/range-parser': 1.2.7
'@types/send': 0.17.5
@@ -9304,13 +9419,17 @@ snapshots:
'@types/graceful-fs@4.1.9':
dependencies:
- '@types/node': 24.0.4
+ '@types/node': 24.0.10
+
+ '@types/hast@3.0.4':
+ dependencies:
+ '@types/unist': 3.0.3
'@types/http-errors@2.0.5': {}
'@types/http-proxy@1.17.16':
dependencies:
- '@types/node': 24.0.4
+ '@types/node': 24.0.10
'@types/istanbul-lib-coverage@2.0.6': {}
@@ -9324,7 +9443,7 @@ snapshots:
'@types/jsdom@20.0.1':
dependencies:
- '@types/node': 24.0.4
+ '@types/node': 24.0.10
'@types/tough-cookie': 4.0.5
parse5: 7.3.0
@@ -9338,7 +9457,7 @@ snapshots:
dependencies:
localforage: 1.10.0
- '@types/lodash@4.17.18': {}
+ '@types/lodash@4.17.20': {}
'@types/markdown-it@14.1.2':
dependencies:
@@ -9353,13 +9472,13 @@ snapshots:
'@types/node-forge@1.3.11':
dependencies:
- '@types/node': 24.0.4
+ '@types/node': 24.0.10
'@types/node@10.17.60': {}
'@types/node@16.9.1': {}
- '@types/node@24.0.4':
+ '@types/node@24.0.10':
dependencies:
undici-types: 7.8.0
@@ -9376,7 +9495,7 @@ snapshots:
'@types/send@0.17.5':
dependencies:
'@types/mime': 1.3.5
- '@types/node': 24.0.4
+ '@types/node': 24.0.10
'@types/serve-index@1.9.4':
dependencies:
@@ -9385,12 +9504,12 @@ snapshots:
'@types/serve-static@1.15.8':
dependencies:
'@types/http-errors': 2.0.5
- '@types/node': 24.0.4
+ '@types/node': 24.0.10
'@types/send': 0.17.5
'@types/sockjs@0.3.36':
dependencies:
- '@types/node': 24.0.4
+ '@types/node': 24.0.10
'@types/stack-utils@2.0.3': {}
@@ -9406,11 +9525,13 @@ snapshots:
'@types/trusted-types@2.0.7': {}
+ '@types/unist@3.0.3': {}
+
'@types/web-bluetooth@0.0.20': {}
'@types/ws@8.18.1':
dependencies:
- '@types/node': 24.0.4
+ '@types/node': 24.0.10
'@types/yargs-parser@21.0.3': {}
@@ -9418,32 +9539,32 @@ snapshots:
dependencies:
'@types/yargs-parser': 21.0.3
- '@typescript-eslint/project-service@8.35.0(typescript@5.8.3)':
+ '@typescript-eslint/project-service@8.35.1(typescript@5.8.3)':
dependencies:
- '@typescript-eslint/tsconfig-utils': 8.35.0(typescript@5.8.3)
- '@typescript-eslint/types': 8.35.0
+ '@typescript-eslint/tsconfig-utils': 8.35.1(typescript@5.8.3)
+ '@typescript-eslint/types': 8.35.1
debug: 4.4.1
typescript: 5.8.3
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/scope-manager@8.35.0':
+ '@typescript-eslint/scope-manager@8.35.1':
dependencies:
- '@typescript-eslint/types': 8.35.0
- '@typescript-eslint/visitor-keys': 8.35.0
+ '@typescript-eslint/types': 8.35.1
+ '@typescript-eslint/visitor-keys': 8.35.1
- '@typescript-eslint/tsconfig-utils@8.35.0(typescript@5.8.3)':
+ '@typescript-eslint/tsconfig-utils@8.35.1(typescript@5.8.3)':
dependencies:
typescript: 5.8.3
- '@typescript-eslint/types@8.35.0': {}
+ '@typescript-eslint/types@8.35.1': {}
- '@typescript-eslint/typescript-estree@8.35.0(typescript@5.8.3)':
+ '@typescript-eslint/typescript-estree@8.35.1(typescript@5.8.3)':
dependencies:
- '@typescript-eslint/project-service': 8.35.0(typescript@5.8.3)
- '@typescript-eslint/tsconfig-utils': 8.35.0(typescript@5.8.3)
- '@typescript-eslint/types': 8.35.0
- '@typescript-eslint/visitor-keys': 8.35.0
+ '@typescript-eslint/project-service': 8.35.1(typescript@5.8.3)
+ '@typescript-eslint/tsconfig-utils': 8.35.1(typescript@5.8.3)
+ '@typescript-eslint/types': 8.35.1
+ '@typescript-eslint/visitor-keys': 8.35.1
debug: 4.4.1
fast-glob: 3.3.3
is-glob: 4.0.3
@@ -9454,20 +9575,20 @@ snapshots:
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/utils@8.35.0(eslint@8.57.1)(typescript@5.8.3)':
+ '@typescript-eslint/utils@8.35.1(eslint@8.57.1)(typescript@5.8.3)':
dependencies:
'@eslint-community/eslint-utils': 4.7.0(eslint@8.57.1)
- '@typescript-eslint/scope-manager': 8.35.0
- '@typescript-eslint/types': 8.35.0
- '@typescript-eslint/typescript-estree': 8.35.0(typescript@5.8.3)
+ '@typescript-eslint/scope-manager': 8.35.1
+ '@typescript-eslint/types': 8.35.1
+ '@typescript-eslint/typescript-estree': 8.35.1(typescript@5.8.3)
eslint: 8.57.1
typescript: 5.8.3
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/visitor-keys@8.35.0':
+ '@typescript-eslint/visitor-keys@8.35.1':
dependencies:
- '@typescript-eslint/types': 8.35.0
+ '@typescript-eslint/types': 8.35.1
eslint-visitor-keys: 4.2.1
'@ungap/structured-clone@1.3.0': {}
@@ -9650,22 +9771,22 @@ snapshots:
'@webassemblyjs/ast': 1.14.1
'@xtuc/long': 4.2.2
- '@webpack-cli/configtest@3.0.1(webpack-cli@6.0.1)(webpack@5.99.7)':
+ '@webpack-cli/configtest@3.0.1(webpack-cli@6.0.1)(webpack@5.99.9)':
dependencies:
- webpack: 5.99.7(webpack-cli@6.0.1)
- webpack-cli: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.7)
+ webpack: 5.99.9(webpack-cli@6.0.1)
+ webpack-cli: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.9)
- '@webpack-cli/info@3.0.1(webpack-cli@6.0.1)(webpack@5.99.7)':
+ '@webpack-cli/info@3.0.1(webpack-cli@6.0.1)(webpack@5.99.9)':
dependencies:
- webpack: 5.99.7(webpack-cli@6.0.1)
- webpack-cli: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.7)
+ webpack: 5.99.9(webpack-cli@6.0.1)
+ webpack-cli: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.9)
- '@webpack-cli/serve@3.0.1(webpack-cli@6.0.1)(webpack-dev-server@5.2.2)(webpack@5.99.7)':
+ '@webpack-cli/serve@3.0.1(webpack-cli@6.0.1)(webpack-dev-server@5.2.2)(webpack@5.99.9)':
dependencies:
- webpack: 5.99.7(webpack-cli@6.0.1)
- webpack-cli: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.7)
+ webpack: 5.99.9(webpack-cli@6.0.1)
+ webpack-cli: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.9)
optionalDependencies:
- webpack-dev-server: 5.2.2(webpack-cli@6.0.1)(webpack@5.99.7)
+ webpack-dev-server: 5.2.2(webpack-cli@6.0.1)(webpack@5.99.9)
'@xmldom/xmldom@0.7.13': {}
@@ -9971,18 +10092,18 @@ snapshots:
transitivePeerDependencies:
- supports-color
- babel-loader@10.0.0(@babel/core@7.28.0)(webpack@5.99.7):
+ babel-loader@10.0.0(@babel/core@7.28.0)(webpack@5.99.9):
dependencies:
'@babel/core': 7.28.0
find-up: 5.0.0
- webpack: 5.99.7(webpack-cli@6.0.1)
+ webpack: 5.99.9(webpack-cli@6.0.1)
- babel-loader@9.2.1(@babel/core@7.28.0)(webpack@5.99.7):
+ babel-loader@9.2.1(@babel/core@7.28.0)(webpack@5.99.9):
dependencies:
'@babel/core': 7.28.0
find-cache-dir: 4.0.0
schema-utils: 4.3.2
- webpack: 5.99.7(webpack-cli@6.0.1)
+ webpack: 5.99.9(webpack-cli@6.0.1)
babel-messages@6.23.0:
dependencies:
@@ -10018,7 +10139,7 @@ snapshots:
dependencies:
'@babel/core': 7.28.0
'@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.0)
- core-js-compat: 3.44.0
+ core-js-compat: 3.43.0
transitivePeerDependencies:
- supports-color
@@ -10197,7 +10318,7 @@ snapshots:
browserslist@4.25.1:
dependencies:
caniuse-lite: 1.0.30001726
- electron-to-chromium: 1.5.174
+ electron-to-chromium: 1.5.178
node-releases: 2.0.19
update-browserslist-db: 1.1.3(browserslist@4.25.1)
@@ -10388,9 +10509,9 @@ snapshots:
ci-info@3.9.0: {}
- circular-dependency-plugin@5.2.2(webpack@5.99.7):
+ circular-dependency-plugin@5.2.2(webpack@5.99.9):
dependencies:
- webpack: 5.99.7(webpack-cli@6.0.1)
+ webpack: 5.99.9(webpack-cli@6.0.1)
cjs-module-lexer@1.4.3: {}
@@ -10472,6 +10593,8 @@ snapshots:
commondir@1.0.1: {}
+ complex-esm@2.1.1-esm1: {}
+
compressible@2.0.18:
dependencies:
mime-db: 1.54.0
@@ -10533,7 +10656,16 @@ snapshots:
cookie@0.7.2: {}
- core-js-compat@3.44.0:
+ copy-webpack-plugin@13.0.0(webpack@5.99.9):
+ dependencies:
+ glob-parent: 6.0.2
+ normalize-path: 3.0.0
+ schema-utils: 4.3.2
+ serialize-javascript: 6.0.2
+ tinyglobby: 0.2.14
+ webpack: 5.99.9(webpack-cli@6.0.1)
+
+ core-js-compat@3.43.0:
dependencies:
browserslist: 4.25.1
@@ -10565,13 +10697,13 @@ snapshots:
crc-32@1.2.2: {}
- create-jest@29.7.0(@types/node@24.0.4):
+ create-jest@29.7.0(@types/node@24.0.10):
dependencies:
'@jest/types': 29.6.3
chalk: 4.1.2
exit: 0.1.2
graceful-fs: 4.2.11
- jest-config: 29.7.0(@types/node@24.0.4)
+ jest-config: 29.7.0(@types/node@24.0.10)
jest-util: 29.7.0
prompts: 2.4.2
transitivePeerDependencies:
@@ -10615,7 +10747,7 @@ snapshots:
dependencies:
utrie: 1.0.2
- css-loader@7.1.2(webpack@5.99.7):
+ css-loader@7.1.2(webpack@5.99.9):
dependencies:
icss-utils: 5.1.0(postcss@8.5.6)
postcss: 8.5.6
@@ -10626,22 +10758,22 @@ snapshots:
postcss-value-parser: 4.2.0
semver: 7.7.2
optionalDependencies:
- webpack: 5.99.7(webpack-cli@6.0.1)
+ webpack: 5.99.9(webpack-cli@6.0.1)
- css-minimizer-webpack-plugin@7.0.2(webpack@5.99.7):
+ css-minimizer-webpack-plugin@7.0.2(webpack@5.99.9):
dependencies:
- '@jridgewell/trace-mapping': 0.3.25
+ '@jridgewell/trace-mapping': 0.3.29
cssnano: 7.0.7(postcss@8.5.6)
jest-worker: 29.7.0
postcss: 8.5.6
schema-utils: 4.3.2
serialize-javascript: 6.0.2
- webpack: 5.99.7(webpack-cli@6.0.1)
+ webpack: 5.99.9(webpack-cli@6.0.1)
- css-select@5.1.0:
+ css-select@5.2.2:
dependencies:
boolbase: 1.0.0
- css-what: 6.1.0
+ css-what: 6.2.2
domhandler: 5.0.3
domutils: 3.2.2
nth-check: 2.1.1
@@ -10661,7 +10793,7 @@ snapshots:
mdn-data: 2.12.2
source-map-js: 1.2.1
- css-what@6.1.0: {}
+ css-what@6.2.2: {}
css.escape@1.5.1: {}
@@ -10874,12 +11006,18 @@ snapshots:
depd@2.0.0: {}
+ dequal@2.0.3: {}
+
destroy@1.2.0: {}
detect-newline@3.1.0: {}
detect-node@2.1.0: {}
+ devlop@1.1.0:
+ dependencies:
+ dequal: 2.0.3
+
dexie-observable@3.0.0-beta.11(dexie@3.2.7):
dependencies:
dexie: 3.2.7
@@ -10964,7 +11102,7 @@ snapshots:
dependencies:
jake: 10.9.2
- electron-to-chromium@1.5.174: {}
+ electron-to-chromium@1.5.178: {}
emittery@0.13.1: {}
@@ -11180,7 +11318,7 @@ snapshots:
transitivePeerDependencies:
- supports-color
- eslint-import-resolver-webpack@0.13.8(eslint-plugin-import@2.32.0)(webpack@5.99.7):
+ eslint-import-resolver-webpack@0.13.8(eslint-plugin-import@2.32.0)(webpack@5.99.9):
dependencies:
array.prototype.find: 2.2.3
debug: 3.2.7
@@ -11194,7 +11332,7 @@ snapshots:
lodash: 4.17.21
resolve: 2.0.0-next.5
semver: 5.7.2
- webpack: 5.99.7(webpack-cli@6.0.1)
+ webpack: 5.99.9(webpack-cli@6.0.1)
transitivePeerDependencies:
- supports-color
@@ -11204,7 +11342,7 @@ snapshots:
optionalDependencies:
eslint: 8.57.1
eslint-import-resolver-node: 0.3.9
- eslint-import-resolver-webpack: 0.13.8(eslint-plugin-import@2.32.0)(webpack@5.99.7)
+ eslint-import-resolver-webpack: 0.13.8(eslint-plugin-import@2.32.0)(webpack@5.99.9)
transitivePeerDependencies:
- supports-color
@@ -11243,12 +11381,12 @@ snapshots:
optionalDependencies:
'@testing-library/dom': 9.3.4
- eslint-plugin-jest@28.14.0(eslint@8.57.1)(jest@29.7.0(@types/node@24.0.4))(typescript@5.8.3):
+ eslint-plugin-jest@28.14.0(eslint@8.57.1)(jest@29.7.0(@types/node@24.0.10))(typescript@5.8.3):
dependencies:
- '@typescript-eslint/utils': 8.35.0(eslint@8.57.1)(typescript@5.8.3)
+ '@typescript-eslint/utils': 8.35.1(eslint@8.57.1)(typescript@5.8.3)
eslint: 8.57.1
optionalDependencies:
- jest: 29.7.0(@types/node@24.0.4)
+ jest: 29.7.0(@types/node@24.0.10)
transitivePeerDependencies:
- supports-color
- typescript
@@ -11573,6 +11711,10 @@ snapshots:
dependencies:
bser: 2.1.1
+ fdir@6.4.6(picomatch@4.0.2):
+ optionalDependencies:
+ picomatch: 4.0.2
+
file-entry-cache@6.0.1:
dependencies:
flat-cache: 3.2.0
@@ -11581,11 +11723,11 @@ snapshots:
dependencies:
flat-cache: 3.2.0
- file-loader@6.2.0(webpack@5.99.7):
+ file-loader@6.2.0(webpack@5.99.9):
dependencies:
loader-utils: 2.0.4
schema-utils: 3.3.0
- webpack: 5.99.7(webpack-cli@6.0.1)
+ webpack: 5.99.9(webpack-cli@6.0.1)
file-saver@2.0.1: {}
@@ -11677,7 +11819,7 @@ snapshots:
flatted@3.3.3: {}
- flow-parser@0.274.0: {}
+ flow-parser@0.274.2: {}
flush-promises@1.0.2: {}
@@ -11960,6 +12102,8 @@ snapshots:
he@1.2.0: {}
+ highlight.js@11.11.1: {}
+
hosted-git-info@2.8.9: {}
hosted-git-info@4.1.0:
@@ -12438,7 +12582,7 @@ snapshots:
'@jest/expect': 29.7.0
'@jest/test-result': 29.7.0
'@jest/types': 29.6.3
- '@types/node': 24.0.4
+ '@types/node': 24.0.10
chalk: 4.1.2
co: 4.6.0
dedent: 1.6.0
@@ -12458,16 +12602,16 @@ snapshots:
- babel-plugin-macros
- supports-color
- jest-cli@29.7.0(@types/node@24.0.4):
+ jest-cli@29.7.0(@types/node@24.0.10):
dependencies:
'@jest/core': 29.7.0
'@jest/test-result': 29.7.0
'@jest/types': 29.6.3
chalk: 4.1.2
- create-jest: 29.7.0(@types/node@24.0.4)
+ create-jest: 29.7.0(@types/node@24.0.10)
exit: 0.1.2
import-local: 3.2.0
- jest-config: 29.7.0(@types/node@24.0.4)
+ jest-config: 29.7.0(@types/node@24.0.10)
jest-util: 29.7.0
jest-validate: 29.7.0
yargs: 17.7.2
@@ -12477,7 +12621,7 @@ snapshots:
- supports-color
- ts-node
- jest-config@29.7.0(@types/node@24.0.4):
+ jest-config@29.7.0(@types/node@24.0.10):
dependencies:
'@babel/core': 7.28.0
'@jest/test-sequencer': 29.7.0
@@ -12502,7 +12646,7 @@ snapshots:
slash: 3.0.0
strip-json-comments: 3.1.1
optionalDependencies:
- '@types/node': 24.0.4
+ '@types/node': 24.0.10
transitivePeerDependencies:
- babel-plugin-macros
- supports-color
@@ -12532,7 +12676,7 @@ snapshots:
'@jest/fake-timers': 29.7.0
'@jest/types': 29.6.3
'@types/jsdom': 20.0.1
- '@types/node': 24.0.4
+ '@types/node': 24.0.10
jest-mock: 29.7.0
jest-util: 29.7.0
jsdom: 20.0.3
@@ -12546,7 +12690,7 @@ snapshots:
'@jest/environment': 29.7.0
'@jest/fake-timers': 29.7.0
'@jest/types': 29.6.3
- '@types/node': 24.0.4
+ '@types/node': 24.0.10
jest-mock: 29.7.0
jest-util: 29.7.0
@@ -12556,7 +12700,7 @@ snapshots:
dependencies:
'@jest/types': 29.6.3
'@types/graceful-fs': 4.1.9
- '@types/node': 24.0.4
+ '@types/node': 24.0.10
anymatch: 3.1.3
fb-watchman: 2.0.2
graceful-fs: 4.2.11
@@ -12595,7 +12739,7 @@ snapshots:
jest-mock@29.7.0:
dependencies:
'@jest/types': 29.6.3
- '@types/node': 24.0.4
+ '@types/node': 24.0.10
jest-util: 29.7.0
jest-pnp-resolver@1.2.3(jest-resolve@29.7.0):
@@ -12630,7 +12774,7 @@ snapshots:
'@jest/test-result': 29.7.0
'@jest/transform': 29.7.0
'@jest/types': 29.6.3
- '@types/node': 24.0.4
+ '@types/node': 24.0.10
chalk: 4.1.2
emittery: 0.13.1
graceful-fs: 4.2.11
@@ -12658,7 +12802,7 @@ snapshots:
'@jest/test-result': 29.7.0
'@jest/transform': 29.7.0
'@jest/types': 29.6.3
- '@types/node': 24.0.4
+ '@types/node': 24.0.10
chalk: 4.1.2
cjs-module-lexer: 1.4.3
collect-v8-coverage: 1.0.2
@@ -12708,7 +12852,7 @@ snapshots:
jest-util@29.7.0:
dependencies:
'@jest/types': 29.6.3
- '@types/node': 24.0.4
+ '@types/node': 24.0.10
chalk: 4.1.2
ci-info: 3.9.0
graceful-fs: 4.2.11
@@ -12727,7 +12871,7 @@ snapshots:
dependencies:
'@jest/test-result': 29.7.0
'@jest/types': 29.6.3
- '@types/node': 24.0.4
+ '@types/node': 24.0.10
ansi-escapes: 4.3.2
chalk: 4.1.2
emittery: 0.13.1
@@ -12736,23 +12880,23 @@ snapshots:
jest-worker@27.5.1:
dependencies:
- '@types/node': 24.0.4
+ '@types/node': 24.0.10
merge-stream: 2.0.0
supports-color: 8.1.1
jest-worker@29.7.0:
dependencies:
- '@types/node': 24.0.4
+ '@types/node': 24.0.10
jest-util: 29.7.0
merge-stream: 2.0.0
supports-color: 8.1.1
- jest@29.7.0(@types/node@24.0.4):
+ jest@29.7.0(@types/node@24.0.10):
dependencies:
'@jest/core': 29.7.0
'@jest/types': 29.6.3
import-local: 3.2.0
- jest-cli: 29.7.0(@types/node@24.0.4)
+ jest-cli: 29.7.0(@types/node@24.0.10)
transitivePeerDependencies:
- '@types/node'
- babel-plugin-macros
@@ -12808,7 +12952,7 @@ snapshots:
'@babel/preset-flow': 7.27.1(@babel/core@7.28.0)
'@babel/preset-typescript': 7.27.1(@babel/core@7.28.0)
'@babel/register': 7.27.1(@babel/core@7.28.0)
- flow-parser: 0.274.0
+ flow-parser: 0.274.2
graceful-fs: 4.2.11
micromatch: 4.0.8
neo-async: 2.6.2
@@ -12847,7 +12991,7 @@ snapshots:
whatwg-encoding: 2.0.0
whatwg-mimetype: 3.0.0
whatwg-url: 11.0.0
- ws: 8.18.2
+ ws: 8.18.3
xml-name-validator: 4.0.0
transitivePeerDependencies:
- bufferutil
@@ -12991,14 +13135,14 @@ snapshots:
vue2-teleport: 1.1.4
xstate: 4.38.3
- kolibri-format@1.0.1(@testing-library/dom@9.3.4)(eslint-import-resolver-webpack@0.13.8)(jest@29.7.0(@types/node@24.0.4))(postcss@8.5.6)(typescript@5.8.3):
+ kolibri-format@1.0.1(@testing-library/dom@9.3.4)(eslint-import-resolver-webpack@0.13.8)(jest@29.7.0(@types/node@24.0.10))(postcss@8.5.6)(typescript@5.8.3):
dependencies:
chalk: 4.1.2
commander: 13.1.0
eslint: 8.57.1
eslint-config-prettier: 10.1.5(eslint@8.57.1)
eslint-plugin-import: 2.32.0(eslint-import-resolver-webpack@0.13.8)(eslint@8.57.1)
- eslint-plugin-jest: 28.14.0(eslint@8.57.1)(jest@29.7.0(@types/node@24.0.4))(typescript@5.8.3)
+ eslint-plugin-jest: 28.14.0(eslint@8.57.1)(jest@29.7.0(@types/node@24.0.10))(typescript@5.8.3)
eslint-plugin-jest-dom: 5.5.0(@testing-library/dom@9.3.4)(eslint@8.57.1)
eslint-plugin-kolibri: 0.18.0
eslint-plugin-vue: 9.33.0(eslint@8.57.1)
@@ -13008,7 +13152,7 @@ snapshots:
postcss-less: 6.0.0(postcss@8.5.6)
postcss-sass: 0.5.0
postcss-scss: 4.0.9(postcss@8.5.6)
- prettier: 3.6.1
+ prettier: 3.6.2
stylelint: 15.11.0(typescript@5.8.3)
stylelint-config-html: 1.1.0(postcss-html@1.8.0)(stylelint@15.11.0(typescript@5.8.3))
stylelint-config-prettier: 9.0.5(stylelint@15.11.0(typescript@5.8.3))
@@ -13034,13 +13178,13 @@ snapshots:
chalk: 4.1.2
loglevel: 1.9.2
- kolibri-tools@0.18.2(@testing-library/dom@9.3.4)(@types/node@24.0.4)(ejs@3.1.10)(eslint-import-resolver-webpack@0.13.8)(file-loader@6.2.0(webpack@5.99.7))(postcss@8.5.6)(typescript@5.8.3)(vue@2.7.16):
+ kolibri-tools@0.18.2(@testing-library/dom@9.3.4)(@types/node@24.0.10)(ejs@3.1.10)(eslint-import-resolver-webpack@0.13.8)(file-loader@6.2.0(webpack@5.99.9))(postcss@8.5.6)(typescript@5.8.3)(vue@2.7.16):
dependencies:
'@babel/core': 7.28.0
'@babel/plugin-syntax-import-assertions': 7.27.1(@babel/core@7.28.0)
'@babel/plugin-transform-runtime': 7.28.0(@babel/core@7.28.0)
'@babel/preset-env': 7.28.0(@babel/core@7.28.0)
- '@rushstack/eslint-patch': 1.11.0
+ '@rushstack/eslint-patch': 1.12.0
'@testing-library/jest-dom': 6.6.3
'@testing-library/user-event': 14.6.1(@testing-library/dom@9.3.4)
'@testing-library/vue': 5.9.0(vue-template-compiler@2.7.16)(vue@2.7.16)
@@ -13049,15 +13193,15 @@ snapshots:
autoprefixer: 10.4.21(postcss@8.5.6)
babel-core: 7.0.0-bridge.0(@babel/core@7.28.0)
babel-jest: 29.7.0(@babel/core@7.28.0)
- babel-loader: 10.0.0(@babel/core@7.28.0)(webpack@5.99.7)
+ babel-loader: 10.0.0(@babel/core@7.28.0)(webpack@5.99.9)
browserslist-config-kolibri: 0.18.0
chalk: 4.1.2
check-node-version: 4.2.1
cli-table: 0.3.11
commander: 13.1.0
core-js: 3.43.0
- css-loader: 7.1.2(webpack@5.99.7)
- css-minimizer-webpack-plugin: 7.0.2(webpack@5.99.7)
+ css-loader: 7.1.2(webpack@5.99.9)
+ css-minimizer-webpack-plugin: 7.0.2(webpack@5.99.9)
csv-parse: 5.6.0
csv-writer: 1.6.0
del: 6.1.1
@@ -13065,39 +13209,39 @@ snapshots:
express: 5.1.0
fast-glob: 3.3.3
ini: 5.0.0
- jest: 29.7.0(@types/node@24.0.4)
+ jest: 29.7.0(@types/node@24.0.10)
jest-environment-jsdom: 29.7.0
jest-serializer-vue: 3.1.0
jscodeshift: 17.3.0(@babel/preset-env@7.28.0(@babel/core@7.28.0))
kolibri: 0.18.0
- kolibri-format: 1.0.1(@testing-library/dom@9.3.4)(eslint-import-resolver-webpack@0.13.8)(jest@29.7.0(@types/node@24.0.4))(postcss@8.5.6)(typescript@5.8.3)
+ kolibri-format: 1.0.1(@testing-library/dom@9.3.4)(eslint-import-resolver-webpack@0.13.8)(jest@29.7.0(@types/node@24.0.10))(postcss@8.5.6)(typescript@5.8.3)
launch-editor-middleware: 2.10.0
lodash: 4.17.21
- mini-css-extract-plugin: 2.9.2(webpack@5.99.7)
+ mini-css-extract-plugin: 2.9.2(webpack@5.99.9)
node-sass: 9.0.0
- postcss-loader: 8.1.1(postcss@8.5.6)(typescript@5.8.3)(webpack@5.99.7)
+ postcss-loader: 8.1.1(postcss@8.5.6)(typescript@5.8.3)(webpack@5.99.9)
process: 0.11.10
query-ast: 1.0.5
readline-sync: 1.4.10
recast: 0.23.11
rewire: 6.0.0
rtlcss: 4.3.0
- sass-loader: 16.0.5(node-sass@9.0.0)(webpack@5.99.7)
+ sass-loader: 16.0.5(node-sass@9.0.0)(webpack@5.99.9)
semver: 7.7.2
strip-ansi: 6.0.1
- style-loader: 4.0.0(webpack@5.99.7)
+ style-loader: 4.0.0(webpack@5.99.9)
temp: 0.8.4
- terser-webpack-plugin: 5.3.14(webpack@5.99.7)
+ terser-webpack-plugin: 5.3.14(webpack@5.99.9)
toml: 3.0.0
- url-loader: 4.1.1(file-loader@6.2.0(webpack@5.99.7))(webpack@5.99.7)
+ url-loader: 4.1.1(file-loader@6.2.0(webpack@5.99.9))(webpack@5.99.9)
vue-jest: 3.0.7(babel-core@7.0.0-bridge.0(@babel/core@7.28.0))(vue-template-compiler@2.7.16)(vue@2.7.16)
- vue-loader: 15.11.1(babel-core@7.0.0-bridge.0(@babel/core@7.28.0))(css-loader@7.1.2(webpack@5.99.7))(ejs@3.1.10)(lodash@4.17.21)(vue-template-compiler@2.7.16)(webpack@5.99.7)
+ vue-loader: 15.11.1(babel-core@7.0.0-bridge.0(@babel/core@7.28.0))(css-loader@7.1.2(webpack@5.99.9))(ejs@3.1.10)(lodash@4.17.21)(vue-template-compiler@2.7.16)(webpack@5.99.9)
vue-sfc-descriptor-to-string: 1.0.0
vue-style-loader: 4.1.3
vue-template-compiler: 2.7.16
- webpack: 5.99.7(webpack-cli@6.0.1)
- webpack-cli: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.7)
- webpack-dev-server: 5.2.2(webpack-cli@6.0.1)(webpack@5.99.7)
+ webpack: 5.99.9(webpack-cli@6.0.1)
+ webpack-cli: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.9)
+ webpack-dev-server: 5.2.2(webpack-cli@6.0.1)(webpack@5.99.9)
webpack-merge: 6.0.1
transitivePeerDependencies:
- '@parcel/css'
@@ -13246,6 +13390,8 @@ snapshots:
dependencies:
uc.micro: 2.1.0
+ linkifyjs@4.3.1: {}
+
load-bmfont@1.4.2:
dependencies:
buffer-equal: 0.0.1
@@ -13331,6 +13477,12 @@ snapshots:
dependencies:
js-tokens: 4.0.0
+ lowlight@3.3.0:
+ dependencies:
+ '@types/hast': 3.0.4
+ devlop: 1.1.0
+ highlight.js: 11.11.1
+
lru-cache@10.4.3: {}
lru-cache@4.1.5:
@@ -13432,6 +13584,10 @@ snapshots:
math-intrinsics@1.1.0: {}
+ mathlive@0.105.3:
+ dependencies:
+ '@cortex-js/compute-engine': 0.28.0
+
mathml-tag-names@2.1.3: {}
mdn-data@2.0.28: {}
@@ -13440,7 +13596,7 @@ snapshots:
mdn-data@2.12.2: {}
- mdn-data@2.21.0: {}
+ mdn-data@2.22.0: {}
mdurl@2.0.0: {}
@@ -13530,11 +13686,11 @@ snapshots:
min-indent@1.0.1: {}
- mini-css-extract-plugin@2.9.2(webpack@5.99.7):
+ mini-css-extract-plugin@2.9.2(webpack@5.99.9):
dependencies:
schema-utils: 4.3.2
tapable: 2.2.2
- webpack: 5.99.7(webpack-cli@6.0.1)
+ webpack: 5.99.9(webpack-cli@6.0.1)
minimalistic-assert@1.0.1: {}
@@ -13705,7 +13861,7 @@ snapshots:
'@jimp/custom': 0.16.13
'@jimp/plugin-resize': 0.16.13(@jimp/custom@0.16.13)
'@jimp/types': 0.16.13(@jimp/custom@0.16.13)
- '@types/lodash': 4.17.18
+ '@types/lodash': 4.17.20
'@types/node': 10.17.60
lodash: 4.17.21
url: 0.11.4
@@ -14100,14 +14256,14 @@ snapshots:
dependencies:
postcss: 8.5.6
- postcss-loader@8.1.1(postcss@8.5.6)(typescript@5.8.3)(webpack@5.99.7):
+ postcss-loader@8.1.1(postcss@8.5.6)(typescript@5.8.3)(webpack@5.99.9):
dependencies:
cosmiconfig: 9.0.0(typescript@5.8.3)
jiti: 1.21.7
postcss: 8.5.6
semver: 7.7.2
optionalDependencies:
- webpack: 5.99.7(webpack-cli@6.0.1)
+ webpack: 5.99.9(webpack-cli@6.0.1)
transitivePeerDependencies:
- typescript
@@ -14295,7 +14451,7 @@ snapshots:
prettier@2.8.8:
optional: true
- prettier@3.6.1: {}
+ prettier@3.6.2: {}
pretty-bytes@5.6.0: {}
@@ -14807,12 +14963,12 @@ snapshots:
scss-tokenizer: 0.4.3
yargs: 17.7.2
- sass-loader@16.0.5(node-sass@9.0.0)(webpack@5.99.7):
+ sass-loader@16.0.5(node-sass@9.0.0)(webpack@5.99.9):
dependencies:
neo-async: 2.6.2
optionalDependencies:
node-sass: 9.0.0
- webpack: 5.99.7(webpack-cli@6.0.1)
+ webpack: 5.99.9(webpack-cli@6.0.1)
sax@1.3.0: {}
@@ -15313,9 +15469,9 @@ snapshots:
'@tokenizer/token': 0.3.0
peek-readable: 4.1.0
- style-loader@4.0.0(webpack@5.99.7):
+ style-loader@4.0.0(webpack@5.99.9):
dependencies:
- webpack: 5.99.7(webpack-cli@6.0.1)
+ webpack: 5.99.9(webpack-cli@6.0.1)
style-search@0.1.0: {}
@@ -15393,7 +15549,7 @@ snapshots:
css-tree: 3.1.0
is-plain-object: 5.0.0
known-css-properties: 0.36.0
- mdn-data: 2.21.0
+ mdn-data: 2.22.0
postcss-media-query-parser: 0.2.3
postcss-resolve-nested-selector: 0.1.6
postcss-selector-parser: 7.1.0
@@ -15446,13 +15602,13 @@ snapshots:
- supports-color
- typescript
- stylus-loader@8.1.1(stylus@0.63.0)(webpack@5.99.7):
+ stylus-loader@8.1.1(stylus@0.63.0)(webpack@5.99.9):
dependencies:
fast-glob: 3.3.3
normalize-path: 3.0.0
stylus: 0.63.0
optionalDependencies:
- webpack: 5.99.7(webpack-cli@6.0.1)
+ webpack: 5.99.9(webpack-cli@6.0.1)
stylus@0.63.0:
dependencies:
@@ -15491,9 +15647,9 @@ snapshots:
dependencies:
'@trysound/sax': 0.2.0
commander: 7.2.0
- css-select: 5.1.0
+ css-select: 5.2.2
css-tree: 2.3.1
- css-what: 6.1.0
+ css-what: 6.2.2
csso: 5.0.5
picocolors: 1.1.1
@@ -15533,18 +15689,18 @@ snapshots:
type-fest: 0.16.0
unique-string: 2.0.0
- terser-webpack-plugin@5.3.14(webpack@5.99.7):
+ terser-webpack-plugin@5.3.14(webpack@5.99.9):
dependencies:
- '@jridgewell/trace-mapping': 0.3.25
+ '@jridgewell/trace-mapping': 0.3.29
jest-worker: 27.5.1
schema-utils: 4.3.2
serialize-javascript: 6.0.2
terser: 5.43.1
- webpack: 5.99.7(webpack-cli@6.0.1)
+ webpack: 5.99.9(webpack-cli@6.0.1)
terser@5.43.1:
dependencies:
- '@jridgewell/source-map': 0.3.6
+ '@jridgewell/source-map': 0.3.10
acorn: 8.15.0
commander: 2.20.3
source-map-support: 0.5.21
@@ -15573,6 +15729,11 @@ snapshots:
tinycolor2@1.6.0: {}
+ tinyglobby@0.2.14:
+ dependencies:
+ fdir: 6.4.6(picomatch@4.0.2)
+ picomatch: 4.0.2
+
tippy.js@4.3.5:
dependencies:
popper.js: 1.16.1
@@ -15796,14 +15957,14 @@ snapshots:
urix@0.1.0: {}
- url-loader@4.1.1(file-loader@6.2.0(webpack@5.99.7))(webpack@5.99.7):
+ url-loader@4.1.1(file-loader@6.2.0(webpack@5.99.9))(webpack@5.99.9):
dependencies:
loader-utils: 2.0.4
mime-types: 2.1.35
schema-utils: 3.3.0
- webpack: 5.99.7(webpack-cli@6.0.1)
+ webpack: 5.99.9(webpack-cli@6.0.1)
optionalDependencies:
- file-loader: 6.2.0(webpack@5.99.7)
+ file-loader: 6.2.0(webpack@5.99.9)
url-parse@1.5.10:
dependencies:
@@ -15907,15 +16068,15 @@ snapshots:
transitivePeerDependencies:
- supports-color
- vue-loader@15.11.1(babel-core@7.0.0-bridge.0(@babel/core@7.28.0))(css-loader@7.1.2(webpack@5.99.7))(ejs@3.1.10)(lodash@4.17.21)(vue-template-compiler@2.7.16)(webpack@5.99.7):
+ vue-loader@15.11.1(babel-core@7.0.0-bridge.0(@babel/core@7.28.0))(css-loader@7.1.2(webpack@5.99.9))(ejs@3.1.10)(lodash@4.17.21)(vue-template-compiler@2.7.16)(webpack@5.99.9):
dependencies:
'@vue/component-compiler-utils': 3.3.0(babel-core@7.0.0-bridge.0(@babel/core@7.28.0))(ejs@3.1.10)(lodash@4.17.21)
- css-loader: 7.1.2(webpack@5.99.7)
+ css-loader: 7.1.2(webpack@5.99.9)
hash-sum: 1.0.2
loader-utils: 1.4.2
vue-hot-reload-api: 2.3.4
vue-style-loader: 4.1.3
- webpack: 5.99.7(webpack-cli@6.0.1)
+ webpack: 5.99.9(webpack-cli@6.0.1)
optionalDependencies:
vue-template-compiler: 2.7.16
transitivePeerDependencies:
@@ -16045,12 +16206,12 @@ snapshots:
webidl-conversions@7.0.0: {}
- webpack-cli@6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.7):
+ webpack-cli@6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.9):
dependencies:
'@discoveryjs/json-ext': 0.6.3
- '@webpack-cli/configtest': 3.0.1(webpack-cli@6.0.1)(webpack@5.99.7)
- '@webpack-cli/info': 3.0.1(webpack-cli@6.0.1)(webpack@5.99.7)
- '@webpack-cli/serve': 3.0.1(webpack-cli@6.0.1)(webpack-dev-server@5.2.2)(webpack@5.99.7)
+ '@webpack-cli/configtest': 3.0.1(webpack-cli@6.0.1)(webpack@5.99.9)
+ '@webpack-cli/info': 3.0.1(webpack-cli@6.0.1)(webpack@5.99.9)
+ '@webpack-cli/serve': 3.0.1(webpack-cli@6.0.1)(webpack-dev-server@5.2.2)(webpack@5.99.9)
colorette: 2.0.20
commander: 12.1.0
cross-spawn: 7.0.6
@@ -16059,12 +16220,12 @@ snapshots:
import-local: 3.2.0
interpret: 3.1.1
rechoir: 0.8.0
- webpack: 5.99.7(webpack-cli@6.0.1)
+ webpack: 5.99.9(webpack-cli@6.0.1)
webpack-merge: 6.0.1
optionalDependencies:
- webpack-dev-server: 5.2.2(webpack-cli@6.0.1)(webpack@5.99.7)
+ webpack-dev-server: 5.2.2(webpack-cli@6.0.1)(webpack@5.99.9)
- webpack-dev-middleware@7.4.2(webpack@5.99.7):
+ webpack-dev-middleware@7.4.2(webpack@5.99.9):
dependencies:
colorette: 2.0.20
memfs: 4.17.2
@@ -16073,9 +16234,9 @@ snapshots:
range-parser: 1.2.1
schema-utils: 4.3.2
optionalDependencies:
- webpack: 5.99.7(webpack-cli@6.0.1)
+ webpack: 5.99.9(webpack-cli@6.0.1)
- webpack-dev-server@5.2.2(webpack-cli@6.0.1)(webpack@5.99.7):
+ webpack-dev-server@5.2.2(webpack-cli@6.0.1)(webpack@5.99.9):
dependencies:
'@types/bonjour': 3.5.13
'@types/connect-history-api-fallback': 1.5.4
@@ -16103,11 +16264,11 @@ snapshots:
serve-index: 1.9.1
sockjs: 0.3.24
spdy: 4.0.2
- webpack-dev-middleware: 7.4.2(webpack@5.99.7)
- ws: 8.18.2
+ webpack-dev-middleware: 7.4.2(webpack@5.99.9)
+ ws: 8.18.3
optionalDependencies:
- webpack: 5.99.7(webpack-cli@6.0.1)
- webpack-cli: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.7)
+ webpack: 5.99.9(webpack-cli@6.0.1)
+ webpack-cli: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.9)
transitivePeerDependencies:
- bufferutil
- debug
@@ -16127,7 +16288,7 @@ snapshots:
webpack-sources@3.3.3: {}
- webpack@5.99.7(webpack-cli@6.0.1):
+ webpack@5.99.9(webpack-cli@6.0.1):
dependencies:
'@types/eslint-scope': 3.7.7
'@types/estree': 1.0.8
@@ -16150,11 +16311,11 @@ snapshots:
neo-async: 2.6.2
schema-utils: 4.3.2
tapable: 2.2.2
- terser-webpack-plugin: 5.3.14(webpack@5.99.7)
+ terser-webpack-plugin: 5.3.14(webpack@5.99.9)
watchpack: 2.4.4
webpack-sources: 3.3.3
optionalDependencies:
- webpack-cli: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.7)
+ webpack-cli: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.9)
transitivePeerDependencies:
- '@swc/core'
- esbuild
@@ -16355,12 +16516,12 @@ snapshots:
workbox-sw@7.3.0: {}
- workbox-webpack-plugin@7.3.0(@types/babel__core@7.20.5)(webpack@5.99.7):
+ workbox-webpack-plugin@7.3.0(@types/babel__core@7.20.5)(webpack@5.99.9):
dependencies:
fast-json-stable-stringify: 2.1.0
pretty-bytes: 5.6.0
upath: 1.2.0
- webpack: 5.99.7(webpack-cli@6.0.1)
+ webpack: 5.99.9(webpack-cli@6.0.1)
webpack-sources: 1.4.3
workbox-build: 7.3.0(@types/babel__core@7.20.5)
transitivePeerDependencies:
@@ -16396,7 +16557,7 @@ snapshots:
imurmurhash: 0.1.4
signal-exit: 4.1.0
- ws@8.18.2: {}
+ ws@8.18.3: {}
xhr@2.6.0:
dependencies:
diff --git a/webpack.config.js b/webpack.config.js
index cca2abe8c2..def4a8687e 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -16,6 +16,8 @@ const WebpackRTLPlugin = require('kolibri-tools/lib/webpackRtlPlugin');
const { InjectManifest } = require('workbox-webpack-plugin');
+const CopyPlugin = require('copy-webpack-plugin');
+
// Function to detect if running in WSL
function isWSL() {
try {
@@ -167,6 +169,14 @@ module.exports = (env = {}) => {
new WebpackRTLPlugin({
minify: false,
}),
+ new CopyPlugin({
+ patterns: [
+ {
+ from: path.resolve(__dirname, 'node_modules/mathlive/fonts'),
+ to: path.join(bundleOutputDir, 'fonts'),
+ },
+ ],
+ }),
new CircularDependencyPlugin({
// exclude detection of files based on a RegExp
exclude: /a\.js|node_modules/,