'use strict'; // https://www.w3.org/TR/SVG11/intro.html#Definitions /** * @type {Record>} */ exports.elemsGroups = { animation: new Set([ 'animate', 'animateColor', 'animateMotion', 'animateTransform', 'set', ]), descriptive: new Set(['desc', 'metadata', 'title']), shape: new Set([ 'circle', 'ellipse', 'line', 'path', 'polygon', 'polyline', 'rect', ]), structural: new Set(['defs', 'g', 'svg', 'symbol', 'use']), paintServer: new Set([ 'hatch', 'linearGradient', 'meshGradient', 'pattern', 'radialGradient', 'solidColor', ]), nonRendering: new Set([ 'clipPath', 'filter', 'linearGradient', 'marker', 'mask', 'pattern', 'radialGradient', 'solidColor', 'symbol', ]), container: new Set([ 'a', 'defs', 'foreignObject', 'g', 'marker', 'mask', 'missing-glyph', 'pattern', 'svg', 'switch', 'symbol', ]), textContent: new Set([ 'altGlyph', 'altGlyphDef', 'altGlyphItem', 'glyph', 'glyphRef', 'text', 'textPath', 'tref', 'tspan', ]), textContentChild: new Set(['altGlyph', 'textPath', 'tref', 'tspan']), lightSource: new Set([ 'feDiffuseLighting', 'feDistantLight', 'fePointLight', 'feSpecularLighting', 'feSpotLight', ]), filterPrimitive: new Set([ 'feBlend', 'feColorMatrix', 'feComponentTransfer', 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap', 'feDropShadow', 'feFlood', 'feFuncA', 'feFuncB', 'feFuncG', 'feFuncR', 'feGaussianBlur', 'feImage', 'feMerge', 'feMergeNode', 'feMorphology', 'feOffset', 'feSpecularLighting', 'feTile', 'feTurbulence', ]), }; /** * Elements where adding or removing whitespace may effect rendering, metadata, * or semantic meaning. * * @see https://developer.mozilla.org/docs/Web/HTML/Element/pre */ exports.textElems = new Set([ ...exports.elemsGroups.textContent, 'pre', 'title', ]); exports.pathElems = new Set(['glyph', 'missing-glyph', 'path']); /** * @type {Record>} * @see https://www.w3.org/TR/SVG11/intro.html#Definitions */ exports.attrsGroups = { animationAddition: new Set(['additive', 'accumulate']), animationAttributeTarget: new Set(['attributeType', 'attributeName']), animationEvent: new Set(['onbegin', 'onend', 'onrepeat', 'onload']), animationTiming: new Set([ 'begin', 'dur', 'end', 'fill', 'max', 'min', 'repeatCount', 'repeatDur', 'restart', ]), animationValue: new Set([ 'by', 'calcMode', 'from', 'keySplines', 'keyTimes', 'to', 'values', ]), conditionalProcessing: new Set([ 'requiredExtensions', 'requiredFeatures', 'systemLanguage', ]), core: new Set(['id', 'tabindex', 'xml:base', 'xml:lang', 'xml:space']), graphicalEvent: new Set([ 'onactivate', 'onclick', 'onfocusin', 'onfocusout', 'onload', 'onmousedown', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', ]), presentation: new Set([ 'alignment-baseline', 'baseline-shift', 'clip-path', 'clip-rule', 'clip', 'color-interpolation-filters', 'color-interpolation', 'color-profile', 'color-rendering', 'color', 'cursor', 'direction', 'display', 'dominant-baseline', 'enable-background', 'fill-opacity', 'fill-rule', 'fill', 'filter', 'flood-color', 'flood-opacity', 'font-family', 'font-size-adjust', 'font-size', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'glyph-orientation-horizontal', 'glyph-orientation-vertical', 'image-rendering', 'letter-spacing', 'lighting-color', 'marker-end', 'marker-mid', 'marker-start', 'mask', 'opacity', 'overflow', 'paint-order', 'pointer-events', 'shape-rendering', 'stop-color', 'stop-opacity', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'stroke', 'text-anchor', 'text-decoration', 'text-overflow', 'text-rendering', 'transform-origin', 'transform', 'unicode-bidi', 'vector-effect', 'visibility', 'word-spacing', 'writing-mode', ]), xlink: new Set([ 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', ]), documentEvent: new Set([ 'onabort', 'onerror', 'onresize', 'onscroll', 'onunload', 'onzoom', ]), documentElementEvent: new Set(['oncopy', 'oncut', 'onpaste']), globalEvent: new Set([ 'oncancel', 'oncanplay', 'oncanplaythrough', 'onchange', 'onclick', 'onclose', 'oncuechange', 'ondblclick', 'ondrag', 'ondragend', 'ondragenter', 'ondragleave', 'ondragover', 'ondragstart', 'ondrop', 'ondurationchange', 'onemptied', 'onended', 'onerror', 'onfocus', 'oninput', 'oninvalid', 'onkeydown', 'onkeypress', 'onkeyup', 'onload', 'onloadeddata', 'onloadedmetadata', 'onloadstart', 'onmousedown', 'onmouseenter', 'onmouseleave', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'onmousewheel', 'onpause', 'onplay', 'onplaying', 'onprogress', 'onratechange', 'onreset', 'onresize', 'onscroll', 'onseeked', 'onseeking', 'onselect', 'onshow', 'onstalled', 'onsubmit', 'onsuspend', 'ontimeupdate', 'ontoggle', 'onvolumechange', 'onwaiting', ]), filterPrimitive: new Set(['x', 'y', 'width', 'height', 'result']), transferFunction: new Set([ 'amplitude', 'exponent', 'intercept', 'offset', 'slope', 'tableValues', 'type', ]), }; /** * @type {Record>} */ exports.attrsGroupsDefaults = { core: { 'xml:space': 'default' }, presentation: { clip: 'auto', 'clip-path': 'none', 'clip-rule': 'nonzero', mask: 'none', opacity: '1', 'stop-color': '#000', 'stop-opacity': '1', 'fill-opacity': '1', 'fill-rule': 'nonzero', fill: '#000', stroke: 'none', 'stroke-width': '1', 'stroke-linecap': 'butt', 'stroke-linejoin': 'miter', 'stroke-miterlimit': '4', 'stroke-dasharray': 'none', 'stroke-dashoffset': '0', 'stroke-opacity': '1', 'paint-order': 'normal', 'vector-effect': 'none', display: 'inline', visibility: 'visible', 'marker-start': 'none', 'marker-mid': 'none', 'marker-end': 'none', 'color-interpolation': 'sRGB', 'color-interpolation-filters': 'linearRGB', 'color-rendering': 'auto', 'shape-rendering': 'auto', 'text-rendering': 'auto', 'image-rendering': 'auto', 'font-style': 'normal', 'font-variant': 'normal', 'font-weight': 'normal', 'font-stretch': 'normal', 'font-size': 'medium', 'font-size-adjust': 'none', kerning: 'auto', 'letter-spacing': 'normal', 'word-spacing': 'normal', 'text-decoration': 'none', 'text-anchor': 'start', 'text-overflow': 'clip', 'writing-mode': 'lr-tb', 'glyph-orientation-vertical': 'auto', 'glyph-orientation-horizontal': '0deg', direction: 'ltr', 'unicode-bidi': 'normal', 'dominant-baseline': 'auto', 'alignment-baseline': 'baseline', 'baseline-shift': 'baseline', }, transferFunction: { slope: '1', intercept: '0', amplitude: '1', exponent: '1', offset: '0', }, }; /** * @type {Record, * attrs?: Set, * defaults?: Record, * contentGroups?: Set, * content?: Set, * }>} * @see https://www.w3.org/TR/SVG11/eltindex.html */ exports.elems = { a: { attrsGroups: new Set([ 'conditionalProcessing', 'core', 'graphicalEvent', 'presentation', 'xlink', ]), attrs: new Set([ 'class', 'externalResourcesRequired', 'style', 'target', 'transform', ]), defaults: { target: '_self', }, contentGroups: new Set([ 'animation', 'descriptive', 'paintServer', 'shape', 'structural', ]), content: new Set([ 'a', 'altGlyphDef', 'clipPath', 'color-profile', 'cursor', 'filter', 'font-face', 'font', 'foreignObject', 'image', 'marker', 'mask', 'pattern', 'script', 'style', 'switch', 'text', 'view', // not spec compliant 'tspan', ]), }, altGlyph: { attrsGroups: new Set([ 'conditionalProcessing', 'core', 'graphicalEvent', 'presentation', 'xlink', ]), attrs: new Set([ 'class', 'dx', 'dy', 'externalResourcesRequired', 'format', 'glyphRef', 'rotate', 'style', 'x', 'y', ]), }, altGlyphDef: { attrsGroups: new Set(['core']), content: new Set(['glyphRef']), }, altGlyphItem: { attrsGroups: new Set(['core']), content: new Set(['glyphRef', 'altGlyphItem']), }, animate: { attrsGroups: new Set([ 'animationAddition', 'animationAttributeTarget', 'animationEvent', 'animationTiming', 'animationValue', 'conditionalProcessing', 'core', 'presentation', 'xlink', ]), attrs: new Set(['externalResourcesRequired']), contentGroups: new Set(['descriptive']), }, animateColor: { attrsGroups: new Set([ 'animationAddition', 'animationAttributeTarget', 'animationEvent', 'animationTiming', 'animationValue', 'conditionalProcessing', 'core', 'presentation', 'xlink', ]), attrs: new Set(['externalResourcesRequired']), contentGroups: new Set(['descriptive']), }, animateMotion: { attrsGroups: new Set([ 'animationAddition', 'animationEvent', 'animationTiming', 'animationValue', 'conditionalProcessing', 'core', 'xlink', ]), attrs: new Set([ 'externalResourcesRequired', 'keyPoints', 'origin', 'path', 'rotate', ]), defaults: { rotate: '0', }, contentGroups: new Set(['descriptive']), content: new Set(['mpath']), }, animateTransform: { attrsGroups: new Set([ 'animationAddition', 'animationAttributeTarget', 'animationEvent', 'animationTiming', 'animationValue', 'conditionalProcessing', 'core', 'xlink', ]), attrs: new Set(['externalResourcesRequired', 'type']), contentGroups: new Set(['descriptive']), }, circle: { attrsGroups: new Set([ 'conditionalProcessing', 'core', 'graphicalEvent', 'presentation', ]), attrs: new Set([ 'class', 'cx', 'cy', 'externalResourcesRequired', 'r', 'style', 'transform', ]), defaults: { cx: '0', cy: '0', }, contentGroups: new Set(['animation', 'descriptive']), }, clipPath: { attrsGroups: new Set(['conditionalProcessing', 'core', 'presentation']), attrs: new Set([ 'class', 'clipPathUnits', 'externalResourcesRequired', 'style', 'transform', ]), defaults: { clipPathUnits: 'userSpaceOnUse', }, contentGroups: new Set(['animation', 'descriptive', 'shape']), content: new Set(['text', 'use']), }, 'color-profile': { attrsGroups: new Set(['core', 'xlink']), attrs: new Set(['local', 'name', 'rendering-intent']), defaults: { name: 'sRGB', 'rendering-intent': 'auto', }, contentGroups: new Set(['descriptive']), }, cursor: { attrsGroups: new Set(['core', 'conditionalProcessing', 'xlink']), attrs: new Set(['externalResourcesRequired', 'x', 'y']), defaults: { x: '0', y: '0', }, contentGroups: new Set(['descriptive']), }, defs: { attrsGroups: new Set([ 'conditionalProcessing', 'core', 'graphicalEvent', 'presentation', ]), attrs: new Set([ 'class', 'externalResourcesRequired', 'style', 'transform', ]), contentGroups: new Set([ 'animation', 'descriptive', 'paintServer', 'shape', 'structural', ]), content: new Set([ 'a', 'altGlyphDef', 'clipPath', 'color-profile', 'cursor', 'filter', 'font-face', 'font', 'foreignObject', 'image', 'marker', 'mask', 'pattern', 'script', 'style', 'switch', 'text', 'view', ]), }, desc: { attrsGroups: new Set(['core']), attrs: new Set(['class', 'style']), }, ellipse: { attrsGroups: new Set([ 'conditionalProcessing', 'core', 'graphicalEvent', 'presentation', ]), attrs: new Set([ 'class', 'cx', 'cy', 'externalResourcesRequired', 'rx', 'ry', 'style', 'transform', ]), defaults: { cx: '0', cy: '0', }, contentGroups: new Set(['animation', 'descriptive']), }, feBlend: { attrsGroups: new Set(['core', 'presentation', 'filterPrimitive']), attrs: new Set([ 'class', 'style', // TODO: in - 'If no value is provided and this is the first filter primitive, // then this filter primitive will use SourceGraphic as its input' 'in', 'in2', 'mode', ]), defaults: { mode: 'normal', }, content: new Set(['animate', 'set']), }, feColorMatrix: { attrsGroups: new Set(['core', 'presentation', 'filterPrimitive']), attrs: new Set(['class', 'style', 'in', 'type', 'values']), defaults: { type: 'matrix', }, content: new Set(['animate', 'set']), }, feComponentTransfer: { attrsGroups: new Set(['core', 'presentation', 'filterPrimitive']), attrs: new Set(['class', 'style', 'in']), content: new Set(['feFuncA', 'feFuncB', 'feFuncG', 'feFuncR']), }, feComposite: { attrsGroups: new Set(['core', 'presentation', 'filterPrimitive']), attrs: new Set([ 'class', 'in', 'in2', 'k1', 'k2', 'k3', 'k4', 'operator', 'style', ]), defaults: { operator: 'over', k1: '0', k2: '0', k3: '0', k4: '0', }, content: new Set(['animate', 'set']), }, feConvolveMatrix: { attrsGroups: new Set(['core', 'presentation', 'filterPrimitive']), attrs: new Set([ 'class', 'in', 'kernelMatrix', 'order', 'style', // TODO: divisor - 'The default value is the sum of all values in kernelMatrix, // with the exception that if the sum is zero, then the divisor is set to 1' 'bias', 'divisor', // TODO: targetX - 'By default, the convolution matrix is centered in X over each // pixel of the input image (i.e., targetX = floor ( orderX / 2 ))' 'edgeMode', 'targetX', 'targetY', // TODO: kernelUnitLength - 'The first number is the value. The second number // is the value. If the value is not specified, it defaults to the same value as ' 'kernelUnitLength', 'preserveAlpha', ]), defaults: { order: '3', bias: '0', edgeMode: 'duplicate', preserveAlpha: 'false', }, content: new Set(['animate', 'set']), }, feDiffuseLighting: { attrsGroups: new Set(['core', 'presentation', 'filterPrimitive']), attrs: new Set([ 'class', 'diffuseConstant', 'in', 'kernelUnitLength', 'style', 'surfaceScale', ]), defaults: { surfaceScale: '1', diffuseConstant: '1', }, contentGroups: new Set(['descriptive']), content: new Set([ // TODO: 'exactly one light source element, in any order' 'feDistantLight', 'fePointLight', 'feSpotLight', ]), }, feDisplacementMap: { attrsGroups: new Set(['core', 'presentation', 'filterPrimitive']), attrs: new Set([ 'class', 'in', 'in2', 'scale', 'style', 'xChannelSelector', 'yChannelSelector', ]), defaults: { scale: '0', xChannelSelector: 'A', yChannelSelector: 'A', }, content: new Set(['animate', 'set']), }, feDistantLight: { attrsGroups: new Set(['core']), attrs: new Set(['azimuth', 'elevation']), defaults: { azimuth: '0', elevation: '0', }, content: new Set(['animate', 'set']), }, feFlood: { attrsGroups: new Set(['core', 'presentation', 'filterPrimitive']), attrs: new Set(['class', 'style']), content: new Set(['animate', 'animateColor', 'set']), }, feFuncA: { attrsGroups: new Set(['core', 'transferFunction']), content: new Set(['set', 'animate']), }, feFuncB: { attrsGroups: new Set(['core', 'transferFunction']), content: new Set(['set', 'animate']), }, feFuncG: { attrsGroups: new Set(['core', 'transferFunction']), content: new Set(['set', 'animate']), }, feFuncR: { attrsGroups: new Set(['core', 'transferFunction']), content: new Set(['set', 'animate']), }, feGaussianBlur: { attrsGroups: new Set(['core', 'presentation', 'filterPrimitive']), attrs: new Set(['class', 'style', 'in', 'stdDeviation']), defaults: { stdDeviation: '0', }, content: new Set(['set', 'animate']), }, feImage: { attrsGroups: new Set(['core', 'presentation', 'filterPrimitive', 'xlink']), attrs: new Set([ 'class', 'externalResourcesRequired', 'href', 'preserveAspectRatio', 'style', 'xlink:href', ]), defaults: { preserveAspectRatio: 'xMidYMid meet', }, content: new Set(['animate', 'animateTransform', 'set']), }, feMerge: { attrsGroups: new Set(['core', 'presentation', 'filterPrimitive']), attrs: new Set(['class', 'style']), content: new Set(['feMergeNode']), }, feMergeNode: { attrsGroups: new Set(['core']), attrs: new Set(['in']), content: new Set(['animate', 'set']), }, feMorphology: { attrsGroups: new Set(['core', 'presentation', 'filterPrimitive']), attrs: new Set(['class', 'style', 'in', 'operator', 'radius']), defaults: { operator: 'erode', radius: '0', }, content: new Set(['animate', 'set']), }, feOffset: { attrsGroups: new Set(['core', 'presentation', 'filterPrimitive']), attrs: new Set(['class', 'style', 'in', 'dx', 'dy']), defaults: { dx: '0', dy: '0', }, content: new Set(['animate', 'set']), }, fePointLight: { attrsGroups: new Set(['core']), attrs: new Set(['x', 'y', 'z']), defaults: { x: '0', y: '0', z: '0', }, content: new Set(['animate', 'set']), }, feSpecularLighting: { attrsGroups: new Set(['core', 'presentation', 'filterPrimitive']), attrs: new Set([ 'class', 'in', 'kernelUnitLength', 'specularConstant', 'specularExponent', 'style', 'surfaceScale', ]), defaults: { surfaceScale: '1', specularConstant: '1', specularExponent: '1', }, contentGroups: new Set([ 'descriptive', // TODO: exactly one 'light source element' 'lightSource', ]), }, feSpotLight: { attrsGroups: new Set(['core']), attrs: new Set([ 'limitingConeAngle', 'pointsAtX', 'pointsAtY', 'pointsAtZ', 'specularExponent', 'x', 'y', 'z', ]), defaults: { x: '0', y: '0', z: '0', pointsAtX: '0', pointsAtY: '0', pointsAtZ: '0', specularExponent: '1', }, content: new Set(['animate', 'set']), }, feTile: { attrsGroups: new Set(['core', 'presentation', 'filterPrimitive']), attrs: new Set(['class', 'style', 'in']), content: new Set(['animate', 'set']), }, feTurbulence: { attrsGroups: new Set(['core', 'presentation', 'filterPrimitive']), attrs: new Set([ 'baseFrequency', 'class', 'numOctaves', 'seed', 'stitchTiles', 'style', 'type', ]), defaults: { baseFrequency: '0', numOctaves: '1', seed: '0', stitchTiles: 'noStitch', type: 'turbulence', }, content: new Set(['animate', 'set']), }, filter: { attrsGroups: new Set(['core', 'presentation', 'xlink']), attrs: new Set([ 'class', 'externalResourcesRequired', 'filterRes', 'filterUnits', 'height', 'href', 'primitiveUnits', 'style', 'width', 'x', 'xlink:href', 'y', ]), defaults: { primitiveUnits: 'userSpaceOnUse', x: '-10%', y: '-10%', width: '120%', height: '120%', }, contentGroups: new Set(['descriptive', 'filterPrimitive']), content: new Set(['animate', 'set']), }, font: { attrsGroups: new Set(['core', 'presentation']), attrs: new Set([ 'class', 'externalResourcesRequired', 'horiz-adv-x', 'horiz-origin-x', 'horiz-origin-y', 'style', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', ]), defaults: { 'horiz-origin-x': '0', 'horiz-origin-y': '0', }, contentGroups: new Set(['descriptive']), content: new Set(['font-face', 'glyph', 'hkern', 'missing-glyph', 'vkern']), }, 'font-face': { attrsGroups: new Set(['core']), attrs: new Set([ 'font-family', 'font-style', 'font-variant', 'font-weight', 'font-stretch', 'font-size', 'unicode-range', 'units-per-em', 'panose-1', 'stemv', 'stemh', 'slope', 'cap-height', 'x-height', 'accent-height', 'ascent', 'descent', 'widths', 'bbox', 'ideographic', 'alphabetic', 'mathematical', 'hanging', 'v-ideographic', 'v-alphabetic', 'v-mathematical', 'v-hanging', 'underline-position', 'underline-thickness', 'strikethrough-position', 'strikethrough-thickness', 'overline-position', 'overline-thickness', ]), defaults: { 'font-style': 'all', 'font-variant': 'normal', 'font-weight': 'all', 'font-stretch': 'normal', 'unicode-range': 'U+0-10FFFF', 'units-per-em': '1000', 'panose-1': '0 0 0 0 0 0 0 0 0 0', slope: '0', }, contentGroups: new Set(['descriptive']), content: new Set([ // TODO: "at most one 'font-face-src' element" 'font-face-src', ]), }, // TODO: empty content 'font-face-format': { attrsGroups: new Set(['core']), attrs: new Set(['string']), }, 'font-face-name': { attrsGroups: new Set(['core']), attrs: new Set(['name']), }, 'font-face-src': { attrsGroups: new Set(['core']), content: new Set(['font-face-name', 'font-face-uri']), }, 'font-face-uri': { attrsGroups: new Set(['core', 'xlink']), attrs: new Set(['href', 'xlink:href']), content: new Set(['font-face-format']), }, foreignObject: { attrsGroups: new Set([ 'conditionalProcessing', 'core', 'graphicalEvent', 'presentation', ]), attrs: new Set([ 'class', 'externalResourcesRequired', 'height', 'style', 'transform', 'width', 'x', 'y', ]), defaults: { x: '0', y: '0', }, }, g: { attrsGroups: new Set([ 'conditionalProcessing', 'core', 'graphicalEvent', 'presentation', ]), attrs: new Set([ 'class', 'externalResourcesRequired', 'style', 'transform', ]), contentGroups: new Set([ 'animation', 'descriptive', 'paintServer', 'shape', 'structural', ]), content: new Set([ 'a', 'altGlyphDef', 'clipPath', 'color-profile', 'cursor', 'filter', 'font-face', 'font', 'foreignObject', 'image', 'marker', 'mask', 'pattern', 'script', 'style', 'switch', 'text', 'view', ]), }, glyph: { attrsGroups: new Set(['core', 'presentation']), attrs: new Set([ 'arabic-form', 'class', 'd', 'glyph-name', 'horiz-adv-x', 'lang', 'orientation', 'style', 'unicode', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', ]), defaults: { 'arabic-form': 'initial', }, contentGroups: new Set([ 'animation', 'descriptive', 'paintServer', 'shape', 'structural', ]), content: new Set([ 'a', 'altGlyphDef', 'clipPath', 'color-profile', 'cursor', 'filter', 'font-face', 'font', 'foreignObject', 'image', 'marker', 'mask', 'pattern', 'script', 'style', 'switch', 'text', 'view', ]), }, glyphRef: { attrsGroups: new Set(['core', 'presentation']), attrs: new Set([ 'class', 'd', 'horiz-adv-x', 'style', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', ]), contentGroups: new Set([ 'animation', 'descriptive', 'paintServer', 'shape', 'structural', ]), content: new Set([ 'a', 'altGlyphDef', 'clipPath', 'color-profile', 'cursor', 'filter', 'font-face', 'font', 'foreignObject', 'image', 'marker', 'mask', 'pattern', 'script', 'style', 'switch', 'text', 'view', ]), }, hatch: { attrsGroups: new Set(['core', 'presentation', 'xlink']), attrs: new Set([ 'class', 'hatchContentUnits', 'hatchUnits', 'pitch', 'rotate', 'style', 'transform', 'x', 'y', ]), defaults: { hatchUnits: 'objectBoundingBox', hatchContentUnits: 'userSpaceOnUse', x: '0', y: '0', pitch: '0', rotate: '0', }, contentGroups: new Set(['animation', 'descriptive']), content: new Set(['hatchPath']), }, hatchPath: { attrsGroups: new Set(['core', 'presentation', 'xlink']), attrs: new Set(['class', 'style', 'd', 'offset']), defaults: { offset: '0', }, contentGroups: new Set(['animation', 'descriptive']), }, hkern: { attrsGroups: new Set(['core']), attrs: new Set(['u1', 'g1', 'u2', 'g2', 'k']), }, image: { attrsGroups: new Set([ 'conditionalProcessing', 'core', 'graphicalEvent', 'presentation', 'xlink', ]), attrs: new Set([ 'class', 'externalResourcesRequired', 'height', 'href', 'preserveAspectRatio', 'style', 'transform', 'width', 'x', 'xlink:href', 'y', ]), defaults: { x: '0', y: '0', preserveAspectRatio: 'xMidYMid meet', }, contentGroups: new Set(['animation', 'descriptive']), }, line: { attrsGroups: new Set([ 'conditionalProcessing', 'core', 'graphicalEvent', 'presentation', ]), attrs: new Set([ 'class', 'externalResourcesRequired', 'style', 'transform', 'x1', 'x2', 'y1', 'y2', ]), defaults: { x1: '0', y1: '0', x2: '0', y2: '0', }, contentGroups: new Set(['animation', 'descriptive']), }, linearGradient: { attrsGroups: new Set(['core', 'presentation', 'xlink']), attrs: new Set([ 'class', 'externalResourcesRequired', 'gradientTransform', 'gradientUnits', 'href', 'spreadMethod', 'style', 'x1', 'x2', 'xlink:href', 'y1', 'y2', ]), defaults: { x1: '0', y1: '0', x2: '100%', y2: '0', spreadMethod: 'pad', }, contentGroups: new Set(['descriptive']), content: new Set(['animate', 'animateTransform', 'set', 'stop']), }, marker: { attrsGroups: new Set(['core', 'presentation']), attrs: new Set([ 'class', 'externalResourcesRequired', 'markerHeight', 'markerUnits', 'markerWidth', 'orient', 'preserveAspectRatio', 'refX', 'refY', 'style', 'viewBox', ]), defaults: { markerUnits: 'strokeWidth', refX: '0', refY: '0', markerWidth: '3', markerHeight: '3', }, contentGroups: new Set([ 'animation', 'descriptive', 'paintServer', 'shape', 'structural', ]), content: new Set([ 'a', 'altGlyphDef', 'clipPath', 'color-profile', 'cursor', 'filter', 'font-face', 'font', 'foreignObject', 'image', 'marker', 'mask', 'pattern', 'script', 'style', 'switch', 'text', 'view', ]), }, mask: { attrsGroups: new Set(['conditionalProcessing', 'core', 'presentation']), attrs: new Set([ 'class', 'externalResourcesRequired', 'height', 'mask-type', 'maskContentUnits', 'maskUnits', 'style', 'width', 'x', 'y', ]), defaults: { maskUnits: 'objectBoundingBox', maskContentUnits: 'userSpaceOnUse', x: '-10%', y: '-10%', width: '120%', height: '120%', }, contentGroups: new Set([ 'animation', 'descriptive', 'paintServer', 'shape', 'structural', ]), content: new Set([ 'a', 'altGlyphDef', 'clipPath', 'color-profile', 'cursor', 'filter', 'font-face', 'font', 'foreignObject', 'image', 'marker', 'mask', 'pattern', 'script', 'style', 'switch', 'text', 'view', ]), }, metadata: { attrsGroups: new Set(['core']), }, 'missing-glyph': { attrsGroups: new Set(['core', 'presentation']), attrs: new Set([ 'class', 'd', 'horiz-adv-x', 'style', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', ]), contentGroups: new Set([ 'animation', 'descriptive', 'paintServer', 'shape', 'structural', ]), content: new Set([ 'a', 'altGlyphDef', 'clipPath', 'color-profile', 'cursor', 'filter', 'font-face', 'font', 'foreignObject', 'image', 'marker', 'mask', 'pattern', 'script', 'style', 'switch', 'text', 'view', ]), }, mpath: { attrsGroups: new Set(['core', 'xlink']), attrs: new Set(['externalResourcesRequired', 'href', 'xlink:href']), contentGroups: new Set(['descriptive']), }, path: { attrsGroups: new Set([ 'conditionalProcessing', 'core', 'graphicalEvent', 'presentation', ]), attrs: new Set([ 'class', 'd', 'externalResourcesRequired', 'pathLength', 'style', 'transform', ]), contentGroups: new Set(['animation', 'descriptive']), }, pattern: { attrsGroups: new Set([ 'conditionalProcessing', 'core', 'presentation', 'xlink', ]), attrs: new Set([ 'class', 'externalResourcesRequired', 'height', 'href', 'patternContentUnits', 'patternTransform', 'patternUnits', 'preserveAspectRatio', 'style', 'viewBox', 'width', 'x', 'xlink:href', 'y', ]), defaults: { patternUnits: 'objectBoundingBox', patternContentUnits: 'userSpaceOnUse', x: '0', y: '0', width: '0', height: '0', preserveAspectRatio: 'xMidYMid meet', }, contentGroups: new Set([ 'animation', 'descriptive', 'paintServer', 'shape', 'structural', ]), content: new Set([ 'a', 'altGlyphDef', 'clipPath', 'color-profile', 'cursor', 'filter', 'font-face', 'font', 'foreignObject', 'image', 'marker', 'mask', 'pattern', 'script', 'style', 'switch', 'text', 'view', ]), }, polygon: { attrsGroups: new Set([ 'conditionalProcessing', 'core', 'graphicalEvent', 'presentation', ]), attrs: new Set([ 'class', 'externalResourcesRequired', 'points', 'style', 'transform', ]), contentGroups: new Set(['animation', 'descriptive']), }, polyline: { attrsGroups: new Set([ 'conditionalProcessing', 'core', 'graphicalEvent', 'presentation', ]), attrs: new Set([ 'class', 'externalResourcesRequired', 'points', 'style', 'transform', ]), contentGroups: new Set(['animation', 'descriptive']), }, radialGradient: { attrsGroups: new Set(['core', 'presentation', 'xlink']), attrs: new Set([ 'class', 'cx', 'cy', 'externalResourcesRequired', 'fr', 'fx', 'fy', 'gradientTransform', 'gradientUnits', 'href', 'r', 'spreadMethod', 'style', 'xlink:href', ]), defaults: { gradientUnits: 'objectBoundingBox', cx: '50%', cy: '50%', r: '50%', }, contentGroups: new Set(['descriptive']), content: new Set(['animate', 'animateTransform', 'set', 'stop']), }, meshGradient: { attrsGroups: new Set(['core', 'presentation', 'xlink']), attrs: new Set(['class', 'style', 'x', 'y', 'gradientUnits', 'transform']), contentGroups: new Set(['descriptive', 'paintServer', 'animation']), content: new Set(['meshRow']), }, meshRow: { attrsGroups: new Set(['core', 'presentation']), attrs: new Set(['class', 'style']), contentGroups: new Set(['descriptive']), content: new Set(['meshPatch']), }, meshPatch: { attrsGroups: new Set(['core', 'presentation']), attrs: new Set(['class', 'style']), contentGroups: new Set(['descriptive']), content: new Set(['stop']), }, rect: { attrsGroups: new Set([ 'conditionalProcessing', 'core', 'graphicalEvent', 'presentation', ]), attrs: new Set([ 'class', 'externalResourcesRequired', 'height', 'rx', 'ry', 'style', 'transform', 'width', 'x', 'y', ]), defaults: { x: '0', y: '0', }, contentGroups: new Set(['animation', 'descriptive']), }, script: { attrsGroups: new Set(['core', 'xlink']), attrs: new Set(['externalResourcesRequired', 'type', 'href', 'xlink:href']), }, set: { attrsGroups: new Set([ 'animation', 'animationAttributeTarget', 'animationTiming', 'conditionalProcessing', 'core', 'xlink', ]), attrs: new Set(['externalResourcesRequired', 'to']), contentGroups: new Set(['descriptive']), }, solidColor: { attrsGroups: new Set(['core', 'presentation']), attrs: new Set(['class', 'style']), contentGroups: new Set(['paintServer']), }, stop: { attrsGroups: new Set(['core', 'presentation']), attrs: new Set(['class', 'style', 'offset', 'path']), content: new Set(['animate', 'animateColor', 'set']), }, style: { attrsGroups: new Set(['core']), attrs: new Set(['type', 'media', 'title']), defaults: { type: 'text/css', }, }, svg: { attrsGroups: new Set([ 'conditionalProcessing', 'core', 'documentEvent', 'graphicalEvent', 'presentation', ]), attrs: new Set([ 'baseProfile', 'class', 'contentScriptType', 'contentStyleType', 'height', 'preserveAspectRatio', 'style', 'version', 'viewBox', 'width', 'x', 'y', 'zoomAndPan', ]), defaults: { x: '0', y: '0', width: '100%', height: '100%', preserveAspectRatio: 'xMidYMid meet', zoomAndPan: 'magnify', version: '1.1', baseProfile: 'none', contentScriptType: 'application/ecmascript', contentStyleType: 'text/css', }, contentGroups: new Set([ 'animation', 'descriptive', 'paintServer', 'shape', 'structural', ]), content: new Set([ 'a', 'altGlyphDef', 'clipPath', 'color-profile', 'cursor', 'filter', 'font-face', 'font', 'foreignObject', 'image', 'marker', 'mask', 'pattern', 'script', 'style', 'switch', 'text', 'view', ]), }, switch: { attrsGroups: new Set([ 'conditionalProcessing', 'core', 'graphicalEvent', 'presentation', ]), attrs: new Set([ 'class', 'externalResourcesRequired', 'style', 'transform', ]), contentGroups: new Set(['animation', 'descriptive', 'shape']), content: new Set([ 'a', 'foreignObject', 'g', 'image', 'svg', 'switch', 'text', 'use', ]), }, symbol: { attrsGroups: new Set(['core', 'graphicalEvent', 'presentation']), attrs: new Set([ 'class', 'externalResourcesRequired', 'preserveAspectRatio', 'refX', 'refY', 'style', 'viewBox', ]), defaults: { refX: '0', refY: '0', }, contentGroups: new Set([ 'animation', 'descriptive', 'paintServer', 'shape', 'structural', ]), content: new Set([ 'a', 'altGlyphDef', 'clipPath', 'color-profile', 'cursor', 'filter', 'font-face', 'font', 'foreignObject', 'image', 'marker', 'mask', 'pattern', 'script', 'style', 'switch', 'text', 'view', ]), }, text: { attrsGroups: new Set([ 'conditionalProcessing', 'core', 'graphicalEvent', 'presentation', ]), attrs: new Set([ 'class', 'dx', 'dy', 'externalResourcesRequired', 'lengthAdjust', 'rotate', 'style', 'textLength', 'transform', 'x', 'y', ]), defaults: { x: '0', y: '0', lengthAdjust: 'spacing', }, contentGroups: new Set(['animation', 'descriptive', 'textContentChild']), content: new Set(['a']), }, textPath: { attrsGroups: new Set([ 'conditionalProcessing', 'core', 'graphicalEvent', 'presentation', 'xlink', ]), attrs: new Set([ 'class', 'd', 'externalResourcesRequired', 'href', 'method', 'spacing', 'startOffset', 'style', 'xlink:href', ]), defaults: { startOffset: '0', method: 'align', spacing: 'exact', }, contentGroups: new Set(['descriptive']), content: new Set([ 'a', 'altGlyph', 'animate', 'animateColor', 'set', 'tref', 'tspan', ]), }, title: { attrsGroups: new Set(['core']), attrs: new Set(['class', 'style']), }, tref: { attrsGroups: new Set([ 'conditionalProcessing', 'core', 'graphicalEvent', 'presentation', 'xlink', ]), attrs: new Set([ 'class', 'externalResourcesRequired', 'href', 'style', 'xlink:href', ]), contentGroups: new Set(['descriptive']), content: new Set(['animate', 'animateColor', 'set']), }, tspan: { attrsGroups: new Set([ 'conditionalProcessing', 'core', 'graphicalEvent', 'presentation', ]), attrs: new Set([ 'class', 'dx', 'dy', 'externalResourcesRequired', 'lengthAdjust', 'rotate', 'style', 'textLength', 'x', 'y', ]), contentGroups: new Set(['descriptive']), content: new Set([ 'a', 'altGlyph', 'animate', 'animateColor', 'set', 'tref', 'tspan', ]), }, use: { attrsGroups: new Set([ 'conditionalProcessing', 'core', 'graphicalEvent', 'presentation', 'xlink', ]), attrs: new Set([ 'class', 'externalResourcesRequired', 'height', 'href', 'style', 'transform', 'width', 'x', 'xlink:href', 'y', ]), defaults: { x: '0', y: '0', }, contentGroups: new Set(['animation', 'descriptive']), }, view: { attrsGroups: new Set(['core']), attrs: new Set([ 'externalResourcesRequired', 'preserveAspectRatio', 'viewBox', 'viewTarget', 'zoomAndPan', ]), contentGroups: new Set(['descriptive']), }, vkern: { attrsGroups: new Set(['core']), attrs: new Set(['u1', 'g1', 'u2', 'g2', 'k']), }, }; // https://wiki.inkscape.org/wiki/index.php/Inkscape-specific_XML_attributes exports.editorNamespaces = new Set([ 'http://creativecommons.org/ns#', 'http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd', 'http://ns.adobe.com/AdobeIllustrator/10.0/', 'http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/', 'http://ns.adobe.com/Extensibility/1.0/', 'http://ns.adobe.com/Flows/1.0/', 'http://ns.adobe.com/GenericCustomNamespace/1.0/', 'http://ns.adobe.com/Graphs/1.0/', 'http://ns.adobe.com/ImageReplacement/1.0/', 'http://ns.adobe.com/SaveForWeb/1.0/', 'http://ns.adobe.com/Variables/1.0/', 'http://ns.adobe.com/XPath/1.0/', 'http://purl.org/dc/elements/1.1/', 'http://schemas.microsoft.com/visio/2003/SVGExtensions/', 'http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd', 'http://taptrix.com/vectorillustrator/svg_extensions', 'http://www.bohemiancoding.com/sketch/ns', 'http://www.figma.com/figma/ns', 'http://www.inkscape.org/namespaces/inkscape', 'http://www.serif.com/', 'http://www.vector.evaxdesign.sk', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#', ]); /** * @see https://www.w3.org/TR/SVG11/linking.html#processingIRI */ exports.referencesProps = new Set([ 'clip-path', 'color-profile', 'fill', 'filter', 'marker-end', 'marker-mid', 'marker-start', 'mask', 'stroke', 'style', ]); /** * @see https://www.w3.org/TR/SVG11/propidx.html */ exports.inheritableAttrs = new Set([ 'clip-rule', 'color-interpolation-filters', 'color-interpolation', 'color-profile', 'color-rendering', 'color', 'cursor', 'direction', 'dominant-baseline', 'fill-opacity', 'fill-rule', 'fill', 'font-family', 'font-size-adjust', 'font-size', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'font', 'glyph-orientation-horizontal', 'glyph-orientation-vertical', 'image-rendering', 'letter-spacing', 'marker-end', 'marker-mid', 'marker-start', 'marker', 'paint-order', 'pointer-events', 'shape-rendering', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'stroke', 'text-anchor', 'text-rendering', 'transform', 'visibility', 'word-spacing', 'writing-mode', ]); exports.presentationNonInheritableGroupAttrs = new Set([ 'clip-path', 'display', 'filter', 'mask', 'opacity', 'text-decoration', 'transform', 'unicode-bidi', ]); /** * https://www.w3.org/TR/SVG11/single-page.html#types-ColorKeywords * * @type {Record} */ exports.colorsNames = { aliceblue: '#f0f8ff', antiquewhite: '#faebd7', aqua: '#0ff', aquamarine: '#7fffd4', azure: '#f0ffff', beige: '#f5f5dc', bisque: '#ffe4c4', black: '#000', blanchedalmond: '#ffebcd', blue: '#00f', blueviolet: '#8a2be2', brown: '#a52a2a', burlywood: '#deb887', cadetblue: '#5f9ea0', chartreuse: '#7fff00', chocolate: '#d2691e', coral: '#ff7f50', cornflowerblue: '#6495ed', cornsilk: '#fff8dc', crimson: '#dc143c', cyan: '#0ff', darkblue: '#00008b', darkcyan: '#008b8b', darkgoldenrod: '#b8860b', darkgray: '#a9a9a9', darkgreen: '#006400', darkgrey: '#a9a9a9', darkkhaki: '#bdb76b', darkmagenta: '#8b008b', darkolivegreen: '#556b2f', darkorange: '#ff8c00', darkorchid: '#9932cc', darkred: '#8b0000', darksalmon: '#e9967a', darkseagreen: '#8fbc8f', darkslateblue: '#483d8b', darkslategray: '#2f4f4f', darkslategrey: '#2f4f4f', darkturquoise: '#00ced1', darkviolet: '#9400d3', deeppink: '#ff1493', deepskyblue: '#00bfff', dimgray: '#696969', dimgrey: '#696969', dodgerblue: '#1e90ff', firebrick: '#b22222', floralwhite: '#fffaf0', forestgreen: '#228b22', fuchsia: '#f0f', gainsboro: '#dcdcdc', ghostwhite: '#f8f8ff', gold: '#ffd700', goldenrod: '#daa520', gray: '#808080', green: '#008000', greenyellow: '#adff2f', grey: '#808080', honeydew: '#f0fff0', hotpink: '#ff69b4', indianred: '#cd5c5c', indigo: '#4b0082', ivory: '#fffff0', khaki: '#f0e68c', lavender: '#e6e6fa', lavenderblush: '#fff0f5', lawngreen: '#7cfc00', lemonchiffon: '#fffacd', lightblue: '#add8e6', lightcoral: '#f08080', lightcyan: '#e0ffff', lightgoldenrodyellow: '#fafad2', lightgray: '#d3d3d3', lightgreen: '#90ee90', lightgrey: '#d3d3d3', lightpink: '#ffb6c1', lightsalmon: '#ffa07a', lightseagreen: '#20b2aa', lightskyblue: '#87cefa', lightslategray: '#789', lightslategrey: '#789', lightsteelblue: '#b0c4de', lightyellow: '#ffffe0', lime: '#0f0', limegreen: '#32cd32', linen: '#faf0e6', magenta: '#f0f', maroon: '#800000', mediumaquamarine: '#66cdaa', mediumblue: '#0000cd', mediumorchid: '#ba55d3', mediumpurple: '#9370db', mediumseagreen: '#3cb371', mediumslateblue: '#7b68ee', mediumspringgreen: '#00fa9a', mediumturquoise: '#48d1cc', mediumvioletred: '#c71585', midnightblue: '#191970', mintcream: '#f5fffa', mistyrose: '#ffe4e1', moccasin: '#ffe4b5', navajowhite: '#ffdead', navy: '#000080', oldlace: '#fdf5e6', olive: '#808000', olivedrab: '#6b8e23', orange: '#ffa500', orangered: '#ff4500', orchid: '#da70d6', palegoldenrod: '#eee8aa', palegreen: '#98fb98', paleturquoise: '#afeeee', palevioletred: '#db7093', papayawhip: '#ffefd5', peachpuff: '#ffdab9', peru: '#cd853f', pink: '#ffc0cb', plum: '#dda0dd', powderblue: '#b0e0e6', purple: '#800080', rebeccapurple: '#639', red: '#f00', rosybrown: '#bc8f8f', royalblue: '#4169e1', saddlebrown: '#8b4513', salmon: '#fa8072', sandybrown: '#f4a460', seagreen: '#2e8b57', seashell: '#fff5ee', sienna: '#a0522d', silver: '#c0c0c0', skyblue: '#87ceeb', slateblue: '#6a5acd', slategray: '#708090', slategrey: '#708090', snow: '#fffafa', springgreen: '#00ff7f', steelblue: '#4682b4', tan: '#d2b48c', teal: '#008080', thistle: '#d8bfd8', tomato: '#ff6347', turquoise: '#40e0d0', violet: '#ee82ee', wheat: '#f5deb3', white: '#fff', whitesmoke: '#f5f5f5', yellow: '#ff0', yellowgreen: '#9acd32', }; /** * @type {Record} */ exports.colorsShortNames = { '#f0ffff': 'azure', '#f5f5dc': 'beige', '#ffe4c4': 'bisque', '#a52a2a': 'brown', '#ff7f50': 'coral', '#ffd700': 'gold', '#808080': 'gray', '#008000': 'green', '#4b0082': 'indigo', '#fffff0': 'ivory', '#f0e68c': 'khaki', '#faf0e6': 'linen', '#800000': 'maroon', '#000080': 'navy', '#808000': 'olive', '#ffa500': 'orange', '#da70d6': 'orchid', '#cd853f': 'peru', '#ffc0cb': 'pink', '#dda0dd': 'plum', '#800080': 'purple', '#f00': 'red', '#ff0000': 'red', '#fa8072': 'salmon', '#a0522d': 'sienna', '#c0c0c0': 'silver', '#fffafa': 'snow', '#d2b48c': 'tan', '#008080': 'teal', '#ff6347': 'tomato', '#ee82ee': 'violet', '#f5deb3': 'wheat', }; /** * @see https://www.w3.org/TR/SVG11/single-page.html#types-DataTypeColor */ exports.colorsProps = new Set([ 'color', 'fill', 'flood-color', 'lighting-color', 'stop-color', 'stroke', ]); /** @see https://developer.mozilla.org/docs/Web/CSS/Pseudo-classes */ exports.pseudoClasses = { displayState: new Set(['fullscreen', 'modal', 'picture-in-picture']), input: new Set([ 'autofill', 'blank', 'checked', 'default', 'disabled', 'enabled', 'in-range', 'indetermined', 'invalid', 'optional', 'out-of-range', 'placeholder-shown', 'read-only', 'read-write', 'required', 'user-invalid', 'valid', ]), linguistic: new Set(['dir', 'lang']), location: new Set([ 'any-link', 'link', 'local-link', 'scope', 'target-within', 'target', 'visited', ]), resourceState: new Set(['playing', 'paused']), timeDimensional: new Set(['current', 'past', 'future']), treeStructural: new Set([ 'empty', 'first-child', 'first-of-type', 'last-child', 'last-of-type', 'nth-child', 'nth-last-child', 'nth-last-of-type', 'nth-of-type', 'only-child', 'only-of-type', 'root', ]), userAction: new Set([ 'active', 'focus-visible', 'focus-within', 'focus', 'hover', ]), functional: new Set(['is', 'not', 'where', 'has']), };