From ea3f19b78e55a53ef08b2de7f4a433ccc47dcb5a Mon Sep 17 00:00:00 2001 From: Raphael Voellmy Date: Sun, 17 Nov 2019 13:18:24 +0100 Subject: [PATCH] refactor(renderers): refactor of renderers and more Rename graphics to renderer, embed base64 encoded font in the handdrawn chord diagram, implement ability to add arbitrary defs to the handdrawn svg diagram, add the correct namespaces and other attributes to the handdrawn svg, add remove method to the renderer interface to remove the complete svg from the dom, adapt demo to allow changing the diagram style --- demo/index.html | 10 +- package.json | 9 +- rollup.config.ts | 5 + src/renderer/index.ts | 3 + src/{graphics.ts => renderer/renderer.ts} | 5 +- src/renderer/roughjs/defs.ts | 14 ++ .../roughjs/roughjs-renderer.ts} | 83 ++++++-- .../svgjs/svg-js-renderer.ts} | 12 +- src/svguitar.ts | 59 +++--- test/svguitar.test.ts | 10 + yarn.lock | 184 ++++++++++++++---- 11 files changed, 304 insertions(+), 90 deletions(-) create mode 100644 src/renderer/index.ts rename src/{graphics.ts => renderer/renderer.ts} (94%) create mode 100644 src/renderer/roughjs/defs.ts rename src/{roughjs-graphics.ts => renderer/roughjs/roughjs-renderer.ts} (67%) rename src/{svgjs-graphics.ts => renderer/svgjs/svg-js-renderer.ts} (91%) diff --git a/demo/index.html b/demo/index.html index 85dee88..bf99042 100644 --- a/demo/index.html +++ b/demo/index.html @@ -43,6 +43,13 @@

Chord

Configuration

+
+ + +
@@ -102,7 +109,8 @@

Result

frets: 4, position: 9, nutSize: 0.65, - strokeWidth: 2 + strokeWidth: 2, + style: 'normal', } var initialChord = { diff --git a/package.json b/package.json index fa653bb..8abf830 100644 --- a/package.json +++ b/package.json @@ -102,12 +102,13 @@ "lint-staged": "^9.2.5", "lodash.camelcase": "^4.3.0", "npm-run-all-v2": "^1.0.0", - "prettier": "^1.14.3", + "prettier": "^1.19.1", "prompt": "^1.0.0", "replace-in-file": "^4.1.3", "rimraf": "^3.0.0", "rollup": "^1.21.3", "rollup-plugin-commonjs": "^10.1.0", + "rollup-plugin-html": "^0.2.1", "rollup-plugin-json": "^4.0.0", "rollup-plugin-node-resolve": "^5.2.0", "rollup-plugin-sourcemaps": "^0.4.2", @@ -118,10 +119,10 @@ "ts-jest": "^24.1.0", "ts-node": "^8.3.0", "tslint": "^5.11.0", - "tslint-config-prettier": "^1.15.0", + "tslint-config-prettier": "^1.18.0", "tslint-config-standard": "^9.0.0", - "typedoc": "^0.15.0", - "typescript": "^3.0.3" + "typedoc": "^0.15.2", + "typescript": "^3.7.2" }, "dependencies": { "@svgdotjs/svg.js": "^3.0.13", diff --git a/rollup.config.ts b/rollup.config.ts index 1137b5e..aa07591 100644 --- a/rollup.config.ts +++ b/rollup.config.ts @@ -4,6 +4,7 @@ import sourceMaps from 'rollup-plugin-sourcemaps' import camelCase from 'lodash.camelcase' import typescript from 'rollup-plugin-typescript2' import json from 'rollup-plugin-json' +import html from 'rollup-plugin-html'; const pkg = require('./package.json') @@ -23,6 +24,10 @@ export default { plugins: [ // Allow json resolution json(), + // Allow importing HTML + html({ + include: '**/*.html' + }), // Compile TypeScript files typescript({ useTsconfigDeclarationDir: true }), // Allow bundling cjs modules (unlike webpack, rollup doesn't understand cjs) diff --git a/src/renderer/index.ts b/src/renderer/index.ts new file mode 100644 index 0000000..50bffa8 --- /dev/null +++ b/src/renderer/index.ts @@ -0,0 +1,3 @@ +export { RoughJsRenderer } from './roughjs/roughjs-renderer' +export { SvgJsRenderer } from './svgjs/svg-js-renderer' +export { Renderer, Alignment, GraphcisElement } from './renderer' diff --git a/src/graphics.ts b/src/renderer/renderer.ts similarity index 94% rename from src/graphics.ts rename to src/renderer/renderer.ts index 4c986de..7911d44 100644 --- a/src/graphics.ts +++ b/src/renderer/renderer.ts @@ -14,7 +14,7 @@ export interface GraphcisElement { remove: () => void } -export abstract class Graphics { +export abstract class Renderer { constructor(protected container: QuerySelector | HTMLElement) {} abstract line( @@ -30,6 +30,8 @@ export abstract class Graphics { abstract clear(): void + abstract remove(): void + abstract text( text: string, x: number, @@ -48,7 +50,6 @@ export abstract class Graphics { strokeColor: string, fill?: string ): GraphcisElement - abstract rect( x: number, y: number, diff --git a/src/renderer/roughjs/defs.ts b/src/renderer/roughjs/defs.ts new file mode 100644 index 0000000..2d47048 --- /dev/null +++ b/src/renderer/roughjs/defs.ts @@ -0,0 +1,14 @@ +export default ` + + + +` diff --git a/src/roughjs-graphics.ts b/src/renderer/roughjs/roughjs-renderer.ts similarity index 67% rename from src/roughjs-graphics.ts rename to src/renderer/roughjs/roughjs-renderer.ts index c55688f..f406a62 100644 --- a/src/roughjs-graphics.ts +++ b/src/renderer/roughjs/roughjs-renderer.ts @@ -5,13 +5,22 @@ that there is no SVG implementation for JSDOM. If that changes at some point thi tested just like the svg.js implementation */ -import { Alignment, GraphcisElement, Graphics } from './graphics' -import { Box, QuerySelector } from '@svgdotjs/svg.js' +import { Alignment, GraphcisElement, Renderer } from '../renderer' +import { QuerySelector } from '@svgdotjs/svg.js' import { RoughSVG } from 'roughjs/bin/svg' import rough from 'roughjs' import { Options } from 'roughjs/src/core' +import defs from './defs' -export class RoughJsGraphics extends Graphics { +/** + * Currently the font is hard-coded to 'Patrick Hand' when using the handdrawn chord diagram style. + * The reason is that the font needs to be base64 encoded and embedded in the SVG. In theory a web-font + * could be downloaded, base64 encoded and embedded in the SVG but that's too much of a hassle. But if the + * need arises it should be possible. + */ +const FONT_FAMLILY = 'Patrick Hand' + +export class RoughJsRenderer extends Renderer { private rc: RoughSVG private containerNode: HTMLElement private svgNode: SVGSVGElement @@ -20,7 +29,7 @@ export class RoughJsGraphics extends Graphics { super(container) // initialize the container - if (container instanceof Element) { + if (container instanceof HTMLElement) { this.containerNode = container } else { this.containerNode = (container as unknown) as HTMLElement @@ -35,15 +44,61 @@ export class RoughJsGraphics extends Graphics { // create an empty SVG element this.svgNode = document.createElementNS('http://www.w3.org/2000/svg', 'svg') + this.svgNode.setAttribute('xmlns', 'http://www.w3.org/2000/svg') + this.svgNode.setAttribute('version', '1.1') + this.svgNode.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink') + this.svgNode.setAttribute('xmlns:svgjs', 'http://svgjs.com/svgjs') this.svgNode.setAttribute('preserveAspectRatio', 'xMidYMid meet') - this.svgNode.setAttribute('viewBox', '0 0 400 402') + this.svgNode.setAttribute('viewBox', '0 0 400 400') + + this.embedDefs() this.containerNode.appendChild(this.svgNode) this.rc = rough.svg(this.svgNode) } + /** + * This will embed all defs defined in the defs.html file. Specifically this is used to embed the base64 + * encoded font into the SVG so that the font always looks correct. + */ + private embedDefs() { + /* + Embed the base64 encoded font. This is done in a timeout because roughjs also creates defs which will simply overwrite existing defs. + By putting this in a timeout we make sure that the style tag is added after roughjs finished rendering. + ATTENTION: This will only work as long as we're synchronously rendering the diagram! If we ever switch to asynchronous rendering a different + solution must be found. + */ + setTimeout(() => { + // check if defs were already added + if (this.svgNode.querySelector('defs [data-svguitar-def]')) { + return + } + + let currentDefs = this.svgNode.querySelector('defs') + + if (!currentDefs) { + currentDefs = document.createElementNS('http://www.w3.org/2000/svg', 'defs') + this.svgNode.prepend(currentDefs) + } + + // create dom nodes from HTML string + const template = document.createElement('template') + template.innerHTML = defs.trim() + + // typescript is complaining when I access content.firstChild.children, therefore this ugly workaround. + const defsToAdd = template.content.firstChild?.firstChild?.parentElement?.children + + if (defsToAdd) { + Array.from(defsToAdd).forEach(def => { + def.setAttribute('data-svguitar-def', 'true') + currentDefs?.appendChild(def) + }) + } + }) + } + circle( x: number, y: number, @@ -76,6 +131,11 @@ export class RoughJsGraphics extends Graphics { } this.rc = rough.svg(this.svgNode) + this.embedDefs() + } + + remove(): void { + this.svgNode.remove() } line(x1: number, y1: number, x2: number, y2: number, strokeWidth: number, color: string): void { @@ -147,8 +207,9 @@ export class RoughJsGraphics extends Graphics { txtElem.setAttributeNS(null, 'x', String(x)) txtElem.setAttributeNS(null, 'y', String(y)) txtElem.setAttributeNS(null, 'font-size', String(fontSize)) - txtElem.setAttributeNS(null, 'font-family', fontFamily) + txtElem.setAttributeNS(null, 'font-family', FONT_FAMLILY) txtElem.setAttributeNS(null, 'align', alignment) + txtElem.setAttributeNS(null, 'fill', color) txtElem.appendChild(document.createTextNode(text)) @@ -188,16 +249,6 @@ export class RoughJsGraphics extends Graphics { } } - private svgJsBoxToElement(box: Box, remove: () => void): GraphcisElement { - return { - width: box.width, - height: box.height, - x: box.x, - y: box.y, - remove - } - } - private roundedRectData( w: number, h: number, diff --git a/src/svgjs-graphics.ts b/src/renderer/svgjs/svg-js-renderer.ts similarity index 91% rename from src/svgjs-graphics.ts rename to src/renderer/svgjs/svg-js-renderer.ts index 47caa47..1da0300 100644 --- a/src/svgjs-graphics.ts +++ b/src/renderer/svgjs/svg-js-renderer.ts @@ -1,9 +1,9 @@ -import { Alignment, GraphcisElement, Graphics } from './graphics' +import { Alignment, GraphcisElement, Renderer } from '../renderer' import { Box, Container, QuerySelector, SVG } from '@svgdotjs/svg.js' -import { constants } from './constants' -import { isNode } from './utils' +import { constants } from '../../constants' +import { isNode } from '../../utils' -export class SvgJsGraphics extends Graphics { +export class SvgJsRenderer extends Renderer { private svg: Container constructor(container: QuerySelector | HTMLElement) { @@ -44,6 +44,10 @@ export class SvgJsGraphics extends Graphics { } } + remove(): void { + this.svg.remove() + } + text( text: string, x: number, diff --git a/src/svguitar.ts b/src/svguitar.ts index 1d3adf0..4ce32e6 100644 --- a/src/svguitar.ts +++ b/src/svguitar.ts @@ -1,9 +1,7 @@ import { QuerySelector } from '@svgdotjs/svg.js' import { range } from './utils' import { constants } from './constants' -import { Alignment, GraphcisElement, Graphics } from './graphics' -import { SvgJsGraphics } from './svgjs-graphics' -import { RoughJsGraphics } from './roughjs-graphics' +import { SvgJsRenderer, RoughJsRenderer, Alignment, GraphcisElement, Renderer } from './renderer' // Chart input types (compatible with Vexchords input, see https://github.com/0xfe/vexchords) export type SilentString = 'x' @@ -218,39 +216,40 @@ const defaultSettings: RequiredChordSettings = { } export class SVGuitarChord { - private _graphics?: Graphics + private _renderer?: Renderer private settings: ChordSettings = {} private _chord: Chord = { fingers: [], barres: [] } constructor(private container: QuerySelector | HTMLElement) {} - private get graphics(): Graphics { - if (!this._graphics) { + private get renderer(): Renderer { + if (!this._renderer) { const style = this.settings.style || defaultSettings.style switch (style) { case ChordStyle.normal: - this._graphics = new SvgJsGraphics(this.container) + this._renderer = new SvgJsRenderer(this.container) break case ChordStyle.handdrawn: - this._graphics = new RoughJsGraphics(this.container) + this._renderer = new RoughJsRenderer(this.container) break default: throw new Error(`${style} is not a valid chord diagram style.`) } } - return this._graphics + return this._renderer } configure(settings: ChordSettings) { this.sanityCheckSettings(settings) - // special case for style: remove current graphics instance if style changed. The new graphics + // special case for style: remove current renderer instance if style changed. The new renderer // instance will be created lazily. if (settings.style !== this.settings.style) { - delete this._graphics + this.renderer.remove() + delete this._renderer } this.settings = { ...this.settings, ...settings } @@ -280,7 +279,7 @@ export class SVGuitarChord { // now set the final height of the svg (and add some padding relative to the fret spacing) y = y + this.fretSpacing() / 10 - this.graphics.size(constants.width, y) + this.renderer.size(constants.width, y) return { width: constants.width, @@ -328,7 +327,7 @@ export class SVGuitarChord { tuning.map((tuning, i) => { if (i < strings) { - const tuningText = this.graphics.text( + const tuningText = this.renderer.text( tuning, stringXPositions[i], y + padding, @@ -381,7 +380,7 @@ export class SVGuitarChord { } if (fretLabelPosition === FretLabelPosition.RIGHT) { - const svgText = this.graphics.text( + const svgText = this.renderer.text( text, endX + padding, y, @@ -397,7 +396,7 @@ export class SVGuitarChord { drawText(sizeMultiplier * 0.9) } } else { - const svgText = this.graphics.text( + const svgText = this.renderer.text( text, 1 / sizeMultiplier + startX - padding, y, @@ -423,8 +422,8 @@ export class SVGuitarChord { * fixed width */ private drawTopEdges() { - this.graphics.circle(constants.width, 0, 0, 0, 'transparent', 'none') - this.graphics.circle(0, 0, 0, 0, 'transparent', 'none') + this.renderer.circle(constants.width, 0, 0, 0, 'transparent', 'none') + this.renderer.circle(0, 0, 0, 0, 'transparent', 'none') } private drawTopFret(y: number): number { @@ -443,7 +442,7 @@ export class SVGuitarChord { fretSize = topFretWidth } - this.graphics.line(startX, y + fretSize / 2, endX, y + fretSize / 2, fretSize, color) + this.renderer.line(startX, y + fretSize / 2, endX, y + fretSize / 2, fretSize, color) return y + fretSize } @@ -512,7 +511,7 @@ export class SVGuitarChord { if (value === OPEN) { // draw an O - this.graphics.circle( + this.renderer.circle( stringXPositions[stringIndex] - size / 2, y + padding, size, @@ -526,8 +525,8 @@ export class SVGuitarChord { const startY = y + padding const endY = startY + size - this.graphics.line(startX, startY, endX, endY, strokeWidth, color) - this.graphics.line(startX, endY, endX, startY, strokeWidth, color) + this.renderer.line(startX, startY, endX, endY, strokeWidth, color) + this.renderer.line(startX, endY, endX, startY, strokeWidth, color) } }) @@ -556,12 +555,12 @@ export class SVGuitarChord { // draw frets fretYPositions.forEach(fretY => { - this.graphics.line(startX, fretY, endX, fretY, strokeWidth, fretColor) + this.renderer.line(startX, fretY, endX, fretY, strokeWidth, fretColor) }) // draw strings stringXPositions.forEach(stringX => { - this.graphics.line(stringX, y, stringX, y + height, strokeWidth, fretColor) + this.renderer.line(stringX, y, stringX, y + height, strokeWidth, fretColor) }) // draw fingers @@ -569,7 +568,7 @@ export class SVGuitarChord { .filter(([_, value]) => value !== SILENT && value !== OPEN) .map(([stringIndex, fretIndex]) => [this.toArrayIndex(stringIndex), fretIndex as number]) .forEach(([stringIndex, fretIndex]) => { - this.graphics.circle( + this.renderer.circle( startX - nutSize / 2 + stringIndex * stringSpacing, y - fretSpacing / 2 - nutSize / 2 + fretIndex * fretSpacing, nutSize, @@ -581,7 +580,7 @@ export class SVGuitarChord { // draw barre chords this._chord.barres.forEach(({ fret, fromString, toString }) => { - this.graphics.rect( + this.renderer.rect( stringXPositions[this.toArrayIndex(fromString)] - stringSpacing / 4, fretYPositions[fret - 1] - fretSpacing / 2 - nutSize / 2, Math.abs(toString - fromString) * stringSpacing + stringSpacing / 2, @@ -602,7 +601,7 @@ export class SVGuitarChord { const fontFamily = this.settings.fontFamily || defaultSettings.fontFamily // draw the title - const { x, y, width, height, remove } = this.graphics.text( + const { x, y, width, height, remove } = this.renderer.text( this.settings.title || '', constants.width / 2, 5, @@ -624,6 +623,12 @@ export class SVGuitarChord { } clear() { - this.graphics.clear() + this.renderer.clear() + } + /** + * Completely remove the diagram from the DOM + */ + remove() { + this.renderer.remove() } } diff --git a/test/svguitar.test.ts b/test/svguitar.test.ts index 4381b34..4db8210 100644 --- a/test/svguitar.test.ts +++ b/test/svguitar.test.ts @@ -15,6 +15,16 @@ describe('SVGuitarChord', () => { it('Should create an instance of the SVGuitarChord class', () => { expect(svguitar).toBeTruthy() }) + it('Should completely remove the diagram from the DOM when removing', () => { + // given + svguitar.draw() + + // when + svguitar.remove() + + // then + expect(container.querySelector('svg')).toBeNull() + }) it('Should render an svg of an arbitrary chord', () => { svguitar diff --git a/yarn.lock b/yarn.lock index 6c75f93..e3d157e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1926,6 +1926,14 @@ callsites@^3.0.0: resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== +camel-case@3.0.x: + version "3.0.0" + resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-3.0.0.tgz#ca3c3688a4e9cf3a4cda777dc4dcbc713249cf73" + integrity sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M= + dependencies: + no-case "^2.2.0" + upper-case "^1.1.1" + camelcase-keys@^4.0.0: version "4.2.0" resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-4.2.0.tgz#a2aa5fb1af688758259c32c141426d78923b9b77" @@ -2032,6 +2040,13 @@ class-utils@^0.3.5: isobject "^3.0.0" static-extend "^0.1.1" +clean-css@4.2.x: + version "4.2.1" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.1.tgz#2d411ef76b8569b6d0c84068dabe85b0aa5e5c17" + integrity sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g== + dependencies: + source-map "~0.6.0" + clean-stack@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" @@ -2180,11 +2195,21 @@ combined-stream@^1.0.6, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" +commander@2.17.x: + version "2.17.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" + integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg== + commander@^2.12.1, commander@^2.20.0, commander@~2.20.0: version "2.20.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ== +commander@~2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" + integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== + commitizen@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/commitizen/-/commitizen-4.0.3.tgz#c19a4213257d0525b85139e2f36db7cc3b4f6dae" @@ -2998,6 +3023,11 @@ estraverse@~1.5.0: resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.5.1.tgz#867a3e8e58a9f84618afb6c2ddbcd916b7cbaf71" integrity sha1-hno+jlip+EYYr7bC3bzZFrfLr3E= +estree-walker@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.2.1.tgz#bdafe8095383d8414d5dc2ecf4c9173b6db9412e" + integrity sha1-va/oCVOD2EFNXcLs9MkXO225QS4= + estree-walker@^0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.6.1.tgz#53049143f40c6eb918b23671d1fe3219f3a1b362" @@ -3712,6 +3742,17 @@ handlebars@^4.1.2: optionalDependencies: uglify-js "^3.1.4" +handlebars@^4.5.1: + version "4.5.2" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.5.2.tgz#5a4eb92ab5962ca3415ac188c86dc7f784f76a0f" + integrity sha512-29Zxv/cynYB7mkT1rVWQnV7mGX6v7H/miQ6dbEpYTKq5eJBN7PsRB+ViYJlcT6JINTSu4dVB9kOqEun78h6Exg== + dependencies: + neo-async "^2.6.0" + optimist "^0.6.1" + source-map "^0.6.1" + optionalDependencies: + uglify-js "^3.1.4" + har-schema@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" @@ -3790,10 +3831,15 @@ has@^1.0.1, has@^1.0.3: dependencies: function-bind "^1.1.1" -highlight.js@^9.15.8: - version "9.15.10" - resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.15.10.tgz#7b18ed75c90348c045eef9ed08ca1319a2219ad2" - integrity sha512-RoV7OkQm0T3os3Dd2VHLNMoaoDVx77Wygln3n9l5YV172XonWG6rgQD3XnF/BuFFZw9A0TJgmMSO8FEWQgvcXw== +he@1.2.x: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + +highlight.js@^9.16.2: + version "9.16.2" + resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.16.2.tgz#68368d039ffe1c6211bcc07e483daf95de3e403e" + integrity sha512-feMUrVLZvjy0oC7FVJQcSQRqbBq9kwqnYE4+Kj9ZjbHh3g+BisiPgF49NyQbVLNdrL/qqZr3Ca9yOKwgn2i/tw== homedir-polyfill@^1.0.1: version "1.0.3" @@ -3826,6 +3872,19 @@ html-encoding-sniffer@^1.0.2: dependencies: whatwg-encoding "^1.0.1" +html-minifier@^3.0.2: + version "3.5.21" + resolved "https://registry.yarnpkg.com/html-minifier/-/html-minifier-3.5.21.tgz#d0040e054730e354db008463593194015212d20c" + integrity sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA== + dependencies: + camel-case "3.0.x" + clean-css "4.2.x" + commander "2.17.x" + he "1.2.x" + param-case "2.1.x" + relateurl "0.2.x" + uglify-js "3.4.x" + http-cache-semantics@^3.8.1: version "3.8.1" resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2" @@ -4655,6 +4714,11 @@ jest-pnp-resolver@^1.2.1: resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.1.tgz#ecdae604c077a7fbc70defb6d517c3c1c898923a" integrity sha512-pgFw2tm54fzgYvc/OHrnysABEObZCUNFnhjoRjaVOCN8NYc032/gVjPaHD4Aq6ApkSieWtfKAFQtmDKAmhupnQ== +jest-raw-loader@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/jest-raw-loader/-/jest-raw-loader-1.0.1.tgz#ce9f56d54650f157c4a7d16d224ba5d613bcd626" + integrity sha1-zp9W1UZQ8VfEp9FtIkul1hO81iY= + jest-regex-util@^24.3.0, jest-regex-util@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-24.9.0.tgz#c13fb3380bde22bf6575432c493ea8fe37965636" @@ -5458,6 +5522,11 @@ loud-rejection@^1.0.0: currently-unhandled "^0.4.1" signal-exit "^3.0.0" +lower-case@^1.1.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac" + integrity sha1-miyr0bno4K6ZOkv31YdcOcQujqw= + lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" @@ -5483,10 +5552,10 @@ lru-cache@^5.1.1: dependencies: yallist "^3.0.2" -lunr@^2.3.6: - version "2.3.6" - resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.6.tgz#f278beee7ffd56ad86e6e478ce02ab2b98c78dd5" - integrity sha512-swStvEyDqQ85MGpABCMBclZcLI/pBIlu8FFDtmX197+oEgKloJ67QnB+Tidh0340HmLMs39c4GrkPY3cmkXp6Q== +lunr@^2.3.8: + version "2.3.8" + resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.8.tgz#a8b89c31f30b5a044b97d2d28e2da191b6ba2072" + integrity sha512-oxMeX/Y35PNFuZoHp+jUj5OSEmLCaIH4KTFJh7a93cHBoFmpw2IoPs22VIz7vyO2YUnx2Tn9dzIwO2P/4quIRg== macos-release@^2.2.0: version "2.3.0" @@ -5746,7 +5815,7 @@ mimic-response@^1.0.0, mimic-response@^1.0.1: resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== -minimatch@^3.0.0, minimatch@^3.0.4: +minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== @@ -5915,6 +5984,13 @@ nice-try@^1.0.4: resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== +no-case@^2.2.0: + version "2.3.2" + resolved "https://registry.yarnpkg.com/no-case/-/no-case-2.3.2.tgz#60b813396be39b3f1288a4c1ed5d1e7d28b464ac" + integrity sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ== + dependencies: + lower-case "^1.1.1" + node-emoji@^1.4.1: version "1.10.0" resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.10.0.tgz#8886abd25d9c7bb61802a658523d1f8d2a89b2da" @@ -6658,6 +6734,13 @@ parallel-transform@^1.1.0: inherits "^2.0.3" readable-stream "^2.1.5" +param-case@2.1.x: + version "2.1.1" + resolved "https://registry.yarnpkg.com/param-case/-/param-case-2.1.1.tgz#df94fd8cf6531ecf75e6bef9a0858fbc72be2247" + integrity sha1-35T9jPZTHs915r75oIWPvHK+Ikc= + dependencies: + no-case "^2.2.0" + parent-module@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" @@ -6848,10 +6931,10 @@ prepend-http@^2.0.0: resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= -prettier@^1.14.3: - version "1.18.2" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.18.2.tgz#6823e7c5900017b4bd3acf46fe9ac4b4d7bda9ea" - integrity sha512-OeHeMc0JhFE9idD4ZdtNibzY0+TPHSpSSb9h8FqtP+YnoZZ1sl8Vc9b1sasjfymH3SonAF4QcA2+mzHPhMvIiw== +prettier@^1.19.1: + version "1.19.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb" + integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew== pretty-format@^24.9.0: version "24.9.0" @@ -7310,6 +7393,11 @@ regjsparser@^0.6.0: dependencies: jsesc "~0.5.0" +relateurl@0.2.x: + version "0.2.7" + resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" + integrity sha1-VNvzd+UUQKypCkzSdGANP/LYiKk= + remove-trailing-separator@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" @@ -7522,6 +7610,14 @@ rollup-plugin-commonjs@^10.1.0: resolve "^1.11.0" rollup-pluginutils "^2.8.1" +rollup-plugin-html@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/rollup-plugin-html/-/rollup-plugin-html-0.2.1.tgz#a1862eca87ae54b677689d0d4133911e8226463d" + integrity sha1-oYYuyoeuVLZ3aJ0NQTORHoImRj0= + dependencies: + html-minifier "^3.0.2" + rollup-pluginutils "^1.5.0" + rollup-plugin-json@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/rollup-plugin-json/-/rollup-plugin-json-4.0.0.tgz#a18da0a4b30bf5ca1ee76ddb1422afbb84ae2b9e" @@ -7566,6 +7662,14 @@ rollup-pluginutils@2.8.1: dependencies: estree-walker "^0.6.1" +rollup-pluginutils@^1.5.0: + version "1.5.2" + resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-1.5.2.tgz#1e156e778f94b7255bfa1b3d0178be8f5c552408" + integrity sha1-HhVud4+UtyVb+hs9AXi+j1xVJAg= + dependencies: + estree-walker "^0.2.1" + minimatch "^3.0.2" + rollup-pluginutils@^2.0.1, rollup-pluginutils@^2.5.0, rollup-pluginutils@^2.8.1: version "2.8.2" resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz#72f2af0748b592364dbd3389e600e5a9444a351e" @@ -7940,7 +8044,7 @@ source-map@^0.5.0, source-map@^0.5.6: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= -source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== @@ -8578,7 +8682,7 @@ tslib@1.9.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.0.tgz#e37a86fda8cbbaf23a057f473c9f4dc64e5fc2e8" integrity sha512-f/qGG2tUkrISBlQZEjEqoZ3B2+npJjIf04H1wuAv9iA8i04Icp+61KRXxFdha22670NJopsZCIjhC3SnjPRKrQ== -tslint-config-prettier@^1.15.0: +tslint-config-prettier@^1.18.0: version "1.18.0" resolved "https://registry.yarnpkg.com/tslint-config-prettier/-/tslint-config-prettier-1.18.0.tgz#75f140bde947d35d8f0d238e0ebf809d64592c37" integrity sha512-xPw9PgNPLG3iKRxmK7DWr+Ea/SzrvfHtjFt5LBl61gk2UBG/DB9kCXRjv+xyIU1rUtnayLeMUVJBcMX8Z17nDg== @@ -8666,42 +8770,45 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= -typedoc-default-themes@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/typedoc-default-themes/-/typedoc-default-themes-0.6.0.tgz#7e73bf54dd9e11550dd0fb576d5176b758f8f8b5" - integrity sha512-MdTROOojxod78CEv22rIA69o7crMPLnVZPefuDLt/WepXqJwgiSu8Xxq+H36x0Jj3YGc7lOglI2vPJ2GhoOybw== +typedoc-default-themes@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/typedoc-default-themes/-/typedoc-default-themes-0.6.1.tgz#e2e471188983df995f4f9df49f713044fced6802" + integrity sha512-z5AWKqQDz7igl9WkUuafx8cEm4MPVQGMpbWE+3lwVOaq+U4UoLKBMnpFQWh/4fqQ3bGysXpOstMxy2OOzHezyw== dependencies: backbone "^1.4.0" jquery "^3.4.1" - lunr "^2.3.6" + lunr "^2.3.8" underscore "^1.9.1" -typedoc@^0.15.0: - version "0.15.0" - resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.15.0.tgz#21eaf4db41cf2797bad027a74f2a75cd08ae0c2d" - integrity sha512-NOtfq5Tis4EFt+J2ozhVq9RCeUnfEYMFKoU6nCXCXUULJz1UQynOM+yH3TkfZCPLzigbqB0tQYGVlktUWweKlw== +typedoc@^0.15.2: + version "0.15.2" + resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.15.2.tgz#f0f79abd12e8b9785f96ce205e2dadf282c32cf4" + integrity sha512-K2nFEtyDQTVdXOzYtECw3TwuT3lM91Zc0dzGSLuor5R8qzZbwqBoCw7xYGVBow6+mEZAvKGznLFsl7FzG+wAgQ== dependencies: "@types/minimatch" "3.0.3" fs-extra "^8.1.0" - handlebars "^4.1.2" - highlight.js "^9.15.8" + handlebars "^4.5.1" + highlight.js "^9.16.2" lodash "^4.17.15" marked "^0.7.0" minimatch "^3.0.0" progress "^2.0.3" shelljs "^0.8.3" - typedoc-default-themes "^0.6.0" - typescript "3.5.x" + typedoc-default-themes "^0.6.1" + typescript "3.7.x" -typescript@3.5.x: - version "3.5.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.5.3.tgz#c830f657f93f1ea846819e929092f5fe5983e977" - integrity sha512-ACzBtm/PhXBDId6a6sDJfroT2pOWt/oOnk4/dElG5G33ZL776N3Y6/6bKZJBFpd+b05F3Ct9qDjMeJmRWtE2/g== +typescript@3.7.x, typescript@^3.7.2: + version "3.7.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.7.2.tgz#27e489b95fa5909445e9fef5ee48d81697ad18fb" + integrity sha512-ml7V7JfiN2Xwvcer+XAf2csGO1bPBdRbFCkYBczNZggrBZ9c7G3riSUeJmqEU5uOtXNPMhE3n+R4FA/3YOAWOQ== -typescript@^3.0.3: - version "3.6.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.6.3.tgz#fea942fabb20f7e1ca7164ff626f1a9f3f70b4da" - integrity sha512-N7bceJL1CtRQ2RiG0AQME13ksR7DiuQh/QehubYcghzv20tnh+MQnQIuJddTmsbqYj+dztchykemz0zFzlvdQw== +uglify-js@3.4.x: + version "3.4.10" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.10.tgz#9ad9563d8eb3acdfb8d38597d2af1d815f6a755f" + integrity sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw== + dependencies: + commander "~2.19.0" + source-map "~0.6.1" uglify-js@^3.1.4: version "3.6.0" @@ -8850,6 +8957,11 @@ update-notifier@^2.3.0, update-notifier@^2.5.0: semver-diff "^2.0.0" xdg-basedir "^3.0.0" +upper-case@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-1.1.3.tgz#f6b4501c2ec4cdd26ba78be7222961de77621598" + integrity sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg= + uri-js@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0"