diff --git a/.gitignore b/.gitignore index b0b8318..aa383c0 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,6 @@ testem.log # System Files .DS_Store Thumbs.db + + +/ckeditor/build diff --git a/.travis.yml b/.travis.yml index 46746b7..09d9790 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,4 +15,4 @@ before_install: install: - npm install script: -- npm run lint && npm run coverage && ng e2e && cat coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js +- npm run build-ckeditor && npm run lint && npm run coverage && ng e2e && cat coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js diff --git a/ckeditor/src/ckeditor.js b/ckeditor/src/ckeditor.js new file mode 100644 index 0000000..422ba8c --- /dev/null +++ b/ckeditor/src/ckeditor.js @@ -0,0 +1,109 @@ +/** + * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +// The editor creator to use. +import ClassicEditorBase from '@ckeditor/ckeditor5-editor-classic/src/classiceditor'; + +import Essentials from '@ckeditor/ckeditor5-essentials/src/essentials'; +import UploadAdapter from '@ckeditor/ckeditor5-adapter-ckfinder/src/uploadadapter'; +import Autoformat from '@ckeditor/ckeditor5-autoformat/src/autoformat'; +import Bold from '@ckeditor/ckeditor5-basic-styles/src/bold'; +import Italic from '@ckeditor/ckeditor5-basic-styles/src/italic'; +import BlockQuote from '@ckeditor/ckeditor5-block-quote/src/blockquote'; +import CKFinder from '@ckeditor/ckeditor5-ckfinder/src/ckfinder'; +import EasyImage from '@ckeditor/ckeditor5-easy-image/src/easyimage'; +import Heading from '@ckeditor/ckeditor5-heading/src/heading'; +import Image from '@ckeditor/ckeditor5-image/src/image'; +import ImageCaption from '@ckeditor/ckeditor5-image/src/imagecaption'; +import ImageStyle from '@ckeditor/ckeditor5-image/src/imagestyle'; +import ImageToolbar from '@ckeditor/ckeditor5-image/src/imagetoolbar'; +import ImageUpload from '@ckeditor/ckeditor5-image/src/imageupload'; +import Indent from '@ckeditor/ckeditor5-indent/src/indent'; +import Link from '@ckeditor/ckeditor5-link/src/link'; +import List from '@ckeditor/ckeditor5-list/src/list'; +import MediaEmbed from '@ckeditor/ckeditor5-media-embed/src/mediaembed'; +import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph'; +import PasteFromOffice from '@ckeditor/ckeditor5-paste-from-office/src/pastefromoffice'; +import Table from '@ckeditor/ckeditor5-table/src/table'; +import TableToolbar from '@ckeditor/ckeditor5-table/src/tabletoolbar'; + +import Context from '@ckeditor/ckeditor5-core/src/context'; +import ContextWatchdog from '@ckeditor/ckeditor5-watchdog/src/contextwatchdog'; + +class ClassicEditor extends ClassicEditorBase {} + +// Plugins to include in the build. +ClassicEditor.builtinPlugins = [ + Essentials, + UploadAdapter, + Autoformat, + Bold, + Italic, + BlockQuote, + CKFinder, + EasyImage, + Heading, + Image, + ImageCaption, + ImageStyle, + ImageToolbar, + ImageUpload, + Indent, + Link, + List, + MediaEmbed, + Paragraph, + PasteFromOffice, + Table, + TableToolbar +]; + +// Editor configuration. +ClassicEditor.defaultConfig = { + toolbar: { + items: [ + 'heading', + '|', + 'bold', + 'italic', + 'link', + 'bulletedList', + 'numberedList', + '|', + 'indent', + 'outdent', + '|', + 'imageUpload', + 'blockQuote', + 'insertTable', + 'mediaEmbed', + 'undo', + 'redo' + ] + }, + image: { + toolbar: [ + 'imageStyle:full', + 'imageStyle:side', + '|', + 'imageTextAlternative' + ] + }, + table: { + contentToolbar: [ + 'tableColumn', + 'tableRow', + 'mergeTableCells' + ] + }, + // This value must be kept in sync with the language defined in webpack.config.js. + language: 'en' +}; + +export default { + ClassicEditor, + Context, + ContextWatchdog +}; diff --git a/ckeditor/webpack.config.js b/ckeditor/webpack.config.js new file mode 100644 index 0000000..95790ba --- /dev/null +++ b/ckeditor/webpack.config.js @@ -0,0 +1,88 @@ +/** + * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +'use strict'; + +/* eslint-env node */ + +const path = require( 'path' ); +const webpack = require( 'webpack' ); +const { bundler, styles } = require( '@ckeditor/ckeditor5-dev-utils' ); +const CKEditorWebpackPlugin = require( '@ckeditor/ckeditor5-dev-webpack-plugin' ); +const TerserPlugin = require( 'terser-webpack-plugin' ); + +module.exports = { + devtool: 'source-map', + performance: { hints: false }, + + entry: path.resolve( __dirname, 'src', 'ckeditor.js' ), + + output: { + // The name under which the editor will be exported. + library: 'CKSource', + + path: path.resolve( __dirname, 'build' ), + filename: 'cksource.js', + libraryTarget: 'umd', + libraryExport: 'default' + }, + + optimization: { + minimizer: [ + new TerserPlugin( { + sourceMap: true, + terserOptions: { + output: { + // Preserve CKEditor 5 license comments. + comments: /^!/ + } + }, + extractComments: false + } ) + ] + }, + + plugins: [ + new CKEditorWebpackPlugin( { + // UI language. Language codes follow the https://en.wikipedia.org/wiki/ISO_639-1 format. + // When changing the built-in language, remember to also change it in the editor's configuration (src/ckeditor.js). + language: 'en', + additionalLanguages: 'all' + } ), + new webpack.BannerPlugin( { + banner: bundler.getLicenseBanner(), + raw: true + } ) + ], + + module: { + rules: [ + { + test: /\.svg$/, + use: [ 'raw-loader' ] + }, + { + test: /\.css$/, + use: [ + { + loader: 'style-loader', + options: { + injectType: 'singletonStyleTag' + } + }, + { + loader: 'postcss-loader', + options: styles.getPostCssConfig( { + themeImporter: { + themePath: require.resolve( '@ckeditor/ckeditor5-theme-lark' ) + }, + minify: true + } ) + }, + ] + } + ] + } +}; diff --git a/package-lock.json b/package-lock.json index 9ed2b13..38bb935 100644 --- a/package-lock.json +++ b/package-lock.json @@ -141,6 +141,37 @@ "requires": { "tslib": "^1.9.0" } + }, + "webpack": { + "version": "4.39.2", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.39.2.tgz", + "integrity": "sha512-AKgTfz3xPSsEibH00JfZ9sHXGUwIQ6eZ9tLN8+VLzachk1Cw2LVmy+4R7ZiwTa9cZZ15tzySjeMui/UnSCAZhA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-module-context": "1.8.5", + "@webassemblyjs/wasm-edit": "1.8.5", + "@webassemblyjs/wasm-parser": "1.8.5", + "acorn": "^6.2.1", + "ajv": "^6.10.2", + "ajv-keywords": "^3.4.1", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^4.1.0", + "eslint-scope": "^4.0.3", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^2.4.0", + "loader-utils": "^1.2.3", + "memory-fs": "^0.4.1", + "micromatch": "^3.1.10", + "mkdirp": "^0.5.1", + "neo-async": "^2.6.1", + "node-libs-browser": "^2.2.1", + "schema-utils": "^1.0.0", + "tapable": "^1.1.3", + "terser-webpack-plugin": "^1.4.1", + "watchpack": "^1.6.0", + "webpack-sources": "^1.4.1" + } } } }, @@ -2013,11 +2044,100 @@ "to-fast-properties": "^2.0.0" } }, - "@ckeditor/ckeditor5-build-classic": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-build-classic/-/ckeditor5-build-classic-15.0.0.tgz", - "integrity": "sha512-oIEYT4obF3+aPgA2BkzCZsK4vzOohpZRWn549dz/FWU6TIIBH7g5wE7CQtsMJG8KnnqC5Y+eh+HNURQxDGvj/g==", - "dev": true + "@ckeditor/ckeditor-cloud-services-core": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor-cloud-services-core/-/ckeditor-cloud-services-core-17.0.0.tgz", + "integrity": "sha512-XaAYhASEI5ALSm3o+AeZ717A1DzWWwy0OKMgvlr7yVLCOFZcJqeofnLiukDvNuxpO/mjNzRLoC5itQkQmI6bhA==", + "dev": true, + "requires": { + "@ckeditor/ckeditor5-utils": "^17.0.0" + } + }, + "@ckeditor/ckeditor5-adapter-ckfinder": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-adapter-ckfinder/-/ckeditor5-adapter-ckfinder-17.0.0.tgz", + "integrity": "sha512-66lwJHXBnCw0HUNHbNzbqTSx6SjkylJV0rT+HosiNgCRDPARkT1V/eB16DVM1Ikw/ZdvTVfzOVWcLvFlcOYSLg==", + "dev": true, + "requires": { + "@ckeditor/ckeditor5-core": "^17.0.0", + "@ckeditor/ckeditor5-upload": "^17.0.0" + } + }, + "@ckeditor/ckeditor5-autoformat": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-autoformat/-/ckeditor5-autoformat-17.0.0.tgz", + "integrity": "sha512-LmDxTpzteBv/BvEiEe5QSZiUOlrbxeHqncxO6ts+gRfmyubpjLD48MJVNe8g3uX2BNw8n6wCX9YWq2dSj849sA==", + "dev": true, + "requires": { + "@ckeditor/ckeditor5-core": "^17.0.0", + "@ckeditor/ckeditor5-typing": "^17.0.0" + } + }, + "@ckeditor/ckeditor5-basic-styles": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-basic-styles/-/ckeditor5-basic-styles-17.0.0.tgz", + "integrity": "sha512-CrjnkASIDZt+uB3V/ZM4plHxxzvzNZvb91GOH8/yefLeAJiV3WnE5gAMfKhquwbmTA2zkTPDcJrOikdbhQf3ZA==", + "dev": true, + "requires": { + "@ckeditor/ckeditor5-core": "^17.0.0", + "@ckeditor/ckeditor5-ui": "^17.0.0" + } + }, + "@ckeditor/ckeditor5-block-quote": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-block-quote/-/ckeditor5-block-quote-17.0.0.tgz", + "integrity": "sha512-ayC3LSNIuWyaDJjAJ6+1DYYd0ITCYrMc9lL/A+3G66muVm54n9GsuoOAykZowiYGZk/ChIxKv12FkPwLIcVD/g==", + "dev": true, + "requires": { + "@ckeditor/ckeditor5-core": "^17.0.0", + "@ckeditor/ckeditor5-ui": "^17.0.0", + "@ckeditor/ckeditor5-utils": "^17.0.0" + } + }, + "@ckeditor/ckeditor5-ckfinder": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-ckfinder/-/ckeditor5-ckfinder-17.0.0.tgz", + "integrity": "sha512-55F7qZG75s07nKcazJohsnHhgq2qmvnAu2I74BX0BTxuCQ56cl/5hsr7eNdjXr5bkZfdgV7El95qLaU280uZmA==", + "dev": true, + "requires": { + "@ckeditor/ckeditor5-adapter-ckfinder": "^17.0.0", + "@ckeditor/ckeditor5-core": "^17.0.0", + "@ckeditor/ckeditor5-image": "^17.0.0", + "@ckeditor/ckeditor5-link": "^17.0.0", + "@ckeditor/ckeditor5-ui": "^17.0.0" + } + }, + "@ckeditor/ckeditor5-clipboard": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-clipboard/-/ckeditor5-clipboard-17.0.0.tgz", + "integrity": "sha512-ltUmytwI94dqcReHxsJmB1U9pxLKCxOdLPqltffC409INXa5d9O3mGrB0eBCh3ACKR783IzRRkbtElFASGznrg==", + "dev": true, + "requires": { + "@ckeditor/ckeditor5-core": "^17.0.0", + "@ckeditor/ckeditor5-engine": "^17.0.0", + "@ckeditor/ckeditor5-utils": "^17.0.0" + } + }, + "@ckeditor/ckeditor5-cloud-services": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-cloud-services/-/ckeditor5-cloud-services-17.0.0.tgz", + "integrity": "sha512-MReubl6usOWZZCm1ieVgxUHDwQsDAD+pbypTQ+XfJXJMvkl2er4W7CXjnWKdGYyb7xUklmM7cxlU+CEEM3YyYA==", + "dev": true, + "requires": { + "@ckeditor/ckeditor-cloud-services-core": "^17.0.0", + "@ckeditor/ckeditor5-core": "^17.0.0" + } + }, + "@ckeditor/ckeditor5-core": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-core/-/ckeditor5-core-17.0.0.tgz", + "integrity": "sha512-exgZOMd3YMJky++ytiAQ1fMtqtKyvEc1xikNBVwAeP38ekZcZSLLi2gP8X8ge2yZTFPmO0TiB8fiU//pLQpeJg==", + "dev": true, + "requires": { + "@ckeditor/ckeditor5-engine": "^17.0.0", + "@ckeditor/ckeditor5-utils": "^17.0.0", + "lodash-es": "^4.17.10" + } }, "@ckeditor/ckeditor5-dev-env": { "version": "17.0.0", @@ -2282,110 +2402,554 @@ } } }, - "@mrmlnc/readdir-enhanced": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", - "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", - "dev": true, - "requires": { - "call-me-maybe": "^1.0.1", - "glob-to-regexp": "^0.3.0" - } - }, - "@ngtools/json-schema": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@ngtools/json-schema/-/json-schema-1.1.0.tgz", - "integrity": "sha1-w6DFRNYjkqzCgTpCyKDcb1j4aSI=", - "dev": true - }, - "@ngtools/webpack": { - "version": "8.3.17", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-8.3.17.tgz", - "integrity": "sha512-p25r68mDut9TGwaBMX98loTlq00gos++LRINgi4wRBAYbYmQQ2GDQw+1hWicx9V+gNEJ21Vm96miUoiQJwxNsg==", + "@ckeditor/ckeditor5-dev-webpack-plugin": { + "version": "8.0.8", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-dev-webpack-plugin/-/ckeditor5-dev-webpack-plugin-8.0.8.tgz", + "integrity": "sha512-x0vorVOrjagcDQqHpfGA037uWnu86zgYOTtRxgu/Dxf0UCEznaiMZcmodZRMjBb6hpXrKHsUnTadM0CWNJNacg==", "dev": true, "requires": { - "@angular-devkit/core": "8.3.17", - "enhanced-resolve": "4.1.0", - "rxjs": "6.4.0", - "tree-kill": "1.2.1", - "webpack-sources": "1.4.3" + "@ckeditor/ckeditor5-dev-utils": "^12.0.8", + "chalk": "^3.0.0", + "rimraf": "^2.6.2", + "webpack-sources": "^1.1.0" }, "dependencies": { - "@angular-devkit/core": { - "version": "8.3.17", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-8.3.17.tgz", - "integrity": "sha512-cR2H/7OxxqagwGfzxwNWDOYN4QpOZ56Fei9JED/2p/K/5UDAowl20o3qP9mTfia/lEhFeyjMBcM8gsHxhJNYJQ==", + "@ckeditor/ckeditor5-dev-utils": { + "version": "12.0.8", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-dev-utils/-/ckeditor5-dev-utils-12.0.8.tgz", + "integrity": "sha512-plWPyka9zNPyqogbU0jownpWTfTBgaH5LugiwuDRHOoMfSlSp/WN61oea82iDQjE/qiOE979HIsSL3sKGxl+Qw==", + "dev": true, + "requires": { + "acorn": "^6.2.1", + "acorn-walk": "^6.2.0", + "chalk": "^3.0.0", + "cssnano": "^4.0.0", + "del": "^5.0.0", + "escodegen": "^1.9.0", + "fs-extra": "^8.1.0", + "javascript-stringify": "^1.6.0", + "pofile": "^1.0.9", + "postcss": "^7.0.17", + "postcss-import": "^12.0.0", + "postcss-mixins": "^6.2.0", + "postcss-nesting": "^7.0.0", + "shelljs": "^0.8.1", + "through2": "^3.0.1" + } + }, + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", "dev": true, "requires": { - "ajv": "6.10.2", - "fast-json-stable-stringify": "2.0.0", - "magic-string": "0.25.3", - "rxjs": "6.4.0", - "source-map": "0.7.3" + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" } }, - "rxjs": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.4.0.tgz", - "integrity": "sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw==", + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "dev": true, "requires": { - "tslib": "^1.9.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "del": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/del/-/del-5.1.0.tgz", + "integrity": "sha512-wH9xOVHnczo9jN2IW68BabcecVPxacIA3g/7z6vhSU/4stOKQzeCRK0yD0A24WiAAUJmmVpWqrERcTxnLo3AnA==", + "dev": true, + "requires": { + "globby": "^10.0.1", + "graceful-fs": "^4.2.2", + "is-glob": "^4.0.1", + "is-path-cwd": "^2.2.0", + "is-path-inside": "^3.0.1", + "p-map": "^3.0.0", + "rimraf": "^3.0.0", + "slash": "^3.0.0" + }, + "dependencies": { + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, + "globby": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", + "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", + "dev": true, + "requires": { + "@types/glob": "^7.1.1", + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.0.3", + "glob": "^7.1.3", + "ignore": "^5.1.1", + "merge2": "^1.2.3", + "slash": "^3.0.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "ignore": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz", + "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==", + "dev": true + }, + "is-path-inside": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz", + "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==", + "dev": true + }, + "p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "through2": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.1.tgz", + "integrity": "sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww==", + "dev": true, + "requires": { + "readable-stream": "2 || 3" } } } }, - "@nodelib/fs.scandir": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", - "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", + "@ckeditor/ckeditor5-easy-image": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-easy-image/-/ckeditor5-easy-image-17.0.0.tgz", + "integrity": "sha512-5VrzdgNE3FbX0q3kj1OAzZuhx2SLSmQcl7fvRw7DPAcUmizEJBeIHqcmGpEDzaZ5a/+QU/Zwt7Y6UIDCqnreLw==", "dev": true, "requires": { - "@nodelib/fs.stat": "2.0.3", - "run-parallel": "^1.1.9" + "@ckeditor/ckeditor-cloud-services-core": "^17.0.0", + "@ckeditor/ckeditor5-cloud-services": "^17.0.0", + "@ckeditor/ckeditor5-core": "^17.0.0", + "@ckeditor/ckeditor5-image": "^17.0.0", + "@ckeditor/ckeditor5-upload": "^17.0.0" } }, - "@nodelib/fs.stat": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", - "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", - "dev": true - }, - "@nodelib/fs.walk": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", - "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", + "@ckeditor/ckeditor5-editor-classic": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-editor-classic/-/ckeditor5-editor-classic-17.0.0.tgz", + "integrity": "sha512-53LB+KG7556U/qM4UDyz/Sj4WtPCGn+sWLooUqzXyMtHvicVyLwi/k0Van6jvC+pLmeyEZHl3yADVLMhU+o5MQ==", "dev": true, "requires": { - "@nodelib/fs.scandir": "2.1.3", - "fastq": "^1.6.0" + "@ckeditor/ckeditor5-core": "^17.0.0", + "@ckeditor/ckeditor5-engine": "^17.0.0", + "@ckeditor/ckeditor5-ui": "^17.0.0", + "@ckeditor/ckeditor5-utils": "^17.0.0", + "lodash-es": "^4.17.10" } }, - "@octokit/endpoint": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-5.4.1.tgz", - "integrity": "sha512-iwn46orWg3F4iqIzAVRfbzhnROyx7BQ7zJE0B7SEeaMIBvk3qmWtswtRk14QkMNUuNiCHQ6mAM00VJxWqrdM1g==", + "@ckeditor/ckeditor5-engine": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-engine/-/ckeditor5-engine-17.0.0.tgz", + "integrity": "sha512-3+m7Hc1QCn97JHLjJWRYg2GcI9hTcU3XGSZnsLeolyPgwBbEnkvfUGId2K5O91Bg3SKkSP4vgvydZE9JM2Q7Mg==", "dev": true, "requires": { - "is-plain-object": "^3.0.0", - "universal-user-agent": "^4.0.0" - }, - "dependencies": { - "is-plain-object": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.0.tgz", - "integrity": "sha512-tZIpofR+P05k8Aocp7UI/2UTa9lTJSebCXpFFoR9aibpokDj/uXBsJ8luUu0tTVYKkMU6URDUuOfJZ7koewXvg==", - "dev": true, - "requires": { - "isobject": "^4.0.0" - } - }, - "isobject": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-4.0.0.tgz", - "integrity": "sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA==", - "dev": true - } + "@ckeditor/ckeditor5-utils": "^17.0.0", + "lodash-es": "^4.17.10" + } + }, + "@ckeditor/ckeditor5-enter": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-enter/-/ckeditor5-enter-17.0.0.tgz", + "integrity": "sha512-ipWFM0YuupXw22WrYRXJJp/1MSwho/v34+YRZhYUPRTcsnastTDFzR8jmJ1DEnhDxzj7D2EanYfUJrA8d1xV+A==", + "dev": true, + "requires": { + "@ckeditor/ckeditor5-core": "^17.0.0", + "@ckeditor/ckeditor5-engine": "^17.0.0", + "@ckeditor/ckeditor5-utils": "^17.0.0" + } + }, + "@ckeditor/ckeditor5-essentials": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-essentials/-/ckeditor5-essentials-17.0.0.tgz", + "integrity": "sha512-2oNP4+lPadeIKioIWhyOP18cGLtaiS7TlKN52e88QhCZYOndgTPRKSVfKSUrpA3MGDj4bSmsWVzOHLt7+Q/+1Q==", + "dev": true, + "requires": { + "@ckeditor/ckeditor5-clipboard": "^17.0.0", + "@ckeditor/ckeditor5-core": "^17.0.0", + "@ckeditor/ckeditor5-enter": "^17.0.0", + "@ckeditor/ckeditor5-typing": "^17.0.0", + "@ckeditor/ckeditor5-undo": "^17.0.0" + } + }, + "@ckeditor/ckeditor5-heading": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-heading/-/ckeditor5-heading-17.0.0.tgz", + "integrity": "sha512-s/s8bEGo/Dr5ZkmJ335GavFz+m7klo8mOkNFkTdzWtYIoA80LT6/ViiPuZbbCL1Lg3KZh0EUteJLa/jHcgB3mw==", + "dev": true, + "requires": { + "@ckeditor/ckeditor5-core": "^17.0.0", + "@ckeditor/ckeditor5-paragraph": "^17.0.0", + "@ckeditor/ckeditor5-ui": "^17.0.0", + "@ckeditor/ckeditor5-utils": "^17.0.0" + } + }, + "@ckeditor/ckeditor5-image": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-image/-/ckeditor5-image-17.0.0.tgz", + "integrity": "sha512-I0yXh/QfiDnv8XBhBN3XJx6VYzMhc9/JcdLj2+xShd73xsWt9S+BqsJl8c/gfWmgSq5wzSrFb/QkGbnqQ+iivQ==", + "dev": true, + "requires": { + "@ckeditor/ckeditor5-clipboard": "^17.0.0", + "@ckeditor/ckeditor5-core": "^17.0.0", + "@ckeditor/ckeditor5-engine": "^17.0.0", + "@ckeditor/ckeditor5-ui": "^17.0.0", + "@ckeditor/ckeditor5-upload": "^17.0.0", + "@ckeditor/ckeditor5-utils": "^17.0.0", + "@ckeditor/ckeditor5-widget": "^17.0.0" + } + }, + "@ckeditor/ckeditor5-indent": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-indent/-/ckeditor5-indent-17.0.0.tgz", + "integrity": "sha512-OIkiorLxSPk8M7K6bTE4AKjXomX6B6/ypCYY2lzddZbOI/xc2Vh3UFs7E3G9etiVdAr20bQUadigBdmtD5P22A==", + "dev": true, + "requires": { + "@ckeditor/ckeditor5-core": "^17.0.0", + "@ckeditor/ckeditor5-utils": "^17.0.0" + } + }, + "@ckeditor/ckeditor5-link": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-link/-/ckeditor5-link-17.0.0.tgz", + "integrity": "sha512-UkzddSupmbFNJjis+zTlv5raPqU8vFJwQSYP1sZ+IPf/qMwhart2IWr2EN05UjpfPSRmgw2SVpJ6ebujZGwNFA==", + "dev": true, + "requires": { + "@ckeditor/ckeditor5-core": "^17.0.0", + "@ckeditor/ckeditor5-engine": "^17.0.0", + "@ckeditor/ckeditor5-ui": "^17.0.0", + "lodash-es": "^4.17.10" + } + }, + "@ckeditor/ckeditor5-list": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-list/-/ckeditor5-list-17.0.0.tgz", + "integrity": "sha512-bwcfD8JRdTBev2Du2tk8aSOquodusE0b+KVZi5DIRauPrKDbJ8CzpLhmq5Fnte2YM+8jlwfPDrDLWvNF8MnuSQ==", + "dev": true, + "requires": { + "@ckeditor/ckeditor5-core": "^17.0.0", + "@ckeditor/ckeditor5-engine": "^17.0.0", + "@ckeditor/ckeditor5-paragraph": "^17.0.0", + "@ckeditor/ckeditor5-ui": "^17.0.0", + "@ckeditor/ckeditor5-utils": "^17.0.0" + } + }, + "@ckeditor/ckeditor5-media-embed": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-media-embed/-/ckeditor5-media-embed-17.0.0.tgz", + "integrity": "sha512-/CvmekgEBwTMjglnrrEw+lSb1R0LrgQCZ7dvWjOqxWmNMfbqtBYYN4qWlY/GqyyxtkYGbeP3NmnbCFHuIK4ctA==", + "dev": true, + "requires": { + "@ckeditor/ckeditor5-clipboard": "^17.0.0", + "@ckeditor/ckeditor5-core": "^17.0.0", + "@ckeditor/ckeditor5-engine": "^17.0.0", + "@ckeditor/ckeditor5-image": "^17.0.0", + "@ckeditor/ckeditor5-ui": "^17.0.0", + "@ckeditor/ckeditor5-undo": "^17.0.0", + "@ckeditor/ckeditor5-utils": "^17.0.0", + "@ckeditor/ckeditor5-widget": "^17.0.0" + } + }, + "@ckeditor/ckeditor5-paragraph": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-paragraph/-/ckeditor5-paragraph-17.0.0.tgz", + "integrity": "sha512-8rLM+Ite/5VdKyKih5vgP48aDo2ps6Ltkb9IB6H8bXuazn/Dwfa5sJoNwukQBADPG3ivDrXbrM8XgsTQQ5VDWg==", + "dev": true, + "requires": { + "@ckeditor/ckeditor5-core": "^17.0.0", + "@ckeditor/ckeditor5-ui": "^17.0.0", + "@ckeditor/ckeditor5-utils": "^17.0.0" + } + }, + "@ckeditor/ckeditor5-paste-from-office": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-paste-from-office/-/ckeditor5-paste-from-office-17.0.0.tgz", + "integrity": "sha512-oi1rjElvV6lwQO9gmWXNR25Eq0c29g0ZsNCkwTlt1PrFUruVuZZ7btmCVI/Yi3MHKvZt+uGjbyurhVt/0QdiEA==", + "dev": true, + "requires": { + "@ckeditor/ckeditor5-clipboard": "^17.0.0", + "@ckeditor/ckeditor5-core": "^17.0.0", + "@ckeditor/ckeditor5-engine": "^17.0.0" + } + }, + "@ckeditor/ckeditor5-table": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-table/-/ckeditor5-table-17.0.0.tgz", + "integrity": "sha512-1UlZ8BFF2tbcS18aXsuQC1ul8bv23UNluHMtUidCOodpxboYRfQtTRE+cmcfY2C9RHLKTvwiYenUNIEQNJvr6w==", + "dev": true, + "requires": { + "@ckeditor/ckeditor5-core": "^17.0.0", + "@ckeditor/ckeditor5-ui": "^17.0.0", + "@ckeditor/ckeditor5-widget": "^17.0.0", + "lodash-es": "^4.17.10" + } + }, + "@ckeditor/ckeditor5-theme-lark": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-theme-lark/-/ckeditor5-theme-lark-17.0.0.tgz", + "integrity": "sha512-nRmamxu0ohYcFGvw7zrTEFwlOi59PAaE3CzHZrky05MuupbEsa8+JQWTAHgyavPofY+27Q3P1DfT4AQJojDyXQ==", + "dev": true, + "requires": { + "@ckeditor/ckeditor5-ui": "^17.0.0" + } + }, + "@ckeditor/ckeditor5-typing": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-typing/-/ckeditor5-typing-17.0.0.tgz", + "integrity": "sha512-U/Udd5Xl5VUs96odPDUBzd/fCYbZ2CgwWztaIYLLWU8blAeIEJJmD4EHYYoAh4zajiKVeYQuuWfTEYOPawkwLQ==", + "dev": true, + "requires": { + "@ckeditor/ckeditor5-core": "^17.0.0", + "@ckeditor/ckeditor5-engine": "^17.0.0", + "@ckeditor/ckeditor5-utils": "^17.0.0", + "lodash-es": "^4.17.10" + } + }, + "@ckeditor/ckeditor5-ui": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-ui/-/ckeditor5-ui-17.0.0.tgz", + "integrity": "sha512-ceM0IlBNscyDOeeGyU4n5Xp9YHdc4hdv2dmDgV/hECSaYzePVr5h1HDoF2Juv4SP5azACSLJr6JZs3uXP8iLCg==", + "dev": true, + "requires": { + "@ckeditor/ckeditor5-core": "^17.0.0", + "@ckeditor/ckeditor5-utils": "^17.0.0", + "lodash-es": "^4.17.10" + } + }, + "@ckeditor/ckeditor5-undo": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-undo/-/ckeditor5-undo-17.0.0.tgz", + "integrity": "sha512-dBbgvtJ1K5HtUOq56/6Rs6jJbzLlldm1kjEsAgtH23ttZT65ClWbckamLcStVp0dWL9Ue1DJXy+bkNeVRkCo9g==", + "dev": true, + "requires": { + "@ckeditor/ckeditor5-core": "^17.0.0", + "@ckeditor/ckeditor5-engine": "^17.0.0", + "@ckeditor/ckeditor5-ui": "^17.0.0" + } + }, + "@ckeditor/ckeditor5-upload": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-upload/-/ckeditor5-upload-17.0.0.tgz", + "integrity": "sha512-Kl1srRnm9XvaJ3ivWf4sNMvkMC9ArbRsCWZ5h2m2LFu2O3v6ZEx8F6viUjTmBLD2dkK9D0cN6+DTUQht2KbR4g==", + "dev": true, + "requires": { + "@ckeditor/ckeditor5-core": "^17.0.0", + "@ckeditor/ckeditor5-ui": "^17.0.0", + "@ckeditor/ckeditor5-utils": "^17.0.0" + } + }, + "@ckeditor/ckeditor5-utils": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-utils/-/ckeditor5-utils-17.0.0.tgz", + "integrity": "sha512-La9Au5pvafUi4uN3Zxjb6HLdacZLMkC+KerWQEohPhZYHRmy8OusaGB+X74gYRKb6O+vGfxpbgSA93e3VoE3fQ==", + "dev": true, + "requires": { + "lodash-es": "^4.17.10" + } + }, + "@ckeditor/ckeditor5-watchdog": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-watchdog/-/ckeditor5-watchdog-17.0.0.tgz", + "integrity": "sha512-qwRYWjv6qYuHD3tj4qB7XtuRGQteVtaoVl2Mzg8pNRP85WbTssZxQgDno951pPqR67Mqxe9YwxtrNMiZfQesrw==", + "dev": true, + "requires": { + "lodash-es": "^4.17.10" + } + }, + "@ckeditor/ckeditor5-widget": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-widget/-/ckeditor5-widget-17.0.0.tgz", + "integrity": "sha512-NOPkim9TNq2TPYf8Sa2trEuRVg58n/a+0iGisomXM8HGy8aOxaBQShK3oKdDliwjrlm/MU9mV8rNunwLGtUB/g==", + "dev": true, + "requires": { + "@ckeditor/ckeditor5-core": "^17.0.0", + "@ckeditor/ckeditor5-engine": "^17.0.0", + "@ckeditor/ckeditor5-ui": "^17.0.0", + "@ckeditor/ckeditor5-utils": "^17.0.0", + "lodash-es": "^4.17.10" + } + }, + "@mrmlnc/readdir-enhanced": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", + "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", + "dev": true, + "requires": { + "call-me-maybe": "^1.0.1", + "glob-to-regexp": "^0.3.0" + } + }, + "@ngtools/json-schema": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@ngtools/json-schema/-/json-schema-1.1.0.tgz", + "integrity": "sha1-w6DFRNYjkqzCgTpCyKDcb1j4aSI=", + "dev": true + }, + "@ngtools/webpack": { + "version": "8.3.17", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-8.3.17.tgz", + "integrity": "sha512-p25r68mDut9TGwaBMX98loTlq00gos++LRINgi4wRBAYbYmQQ2GDQw+1hWicx9V+gNEJ21Vm96miUoiQJwxNsg==", + "dev": true, + "requires": { + "@angular-devkit/core": "8.3.17", + "enhanced-resolve": "4.1.0", + "rxjs": "6.4.0", + "tree-kill": "1.2.1", + "webpack-sources": "1.4.3" + }, + "dependencies": { + "@angular-devkit/core": { + "version": "8.3.17", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-8.3.17.tgz", + "integrity": "sha512-cR2H/7OxxqagwGfzxwNWDOYN4QpOZ56Fei9JED/2p/K/5UDAowl20o3qP9mTfia/lEhFeyjMBcM8gsHxhJNYJQ==", + "dev": true, + "requires": { + "ajv": "6.10.2", + "fast-json-stable-stringify": "2.0.0", + "magic-string": "0.25.3", + "rxjs": "6.4.0", + "source-map": "0.7.3" + } + }, + "rxjs": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.4.0.tgz", + "integrity": "sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + } + } + }, + "@nodelib/fs.scandir": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", + "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.3", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", + "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", + "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.3", + "fastq": "^1.6.0" + } + }, + "@octokit/endpoint": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-5.4.1.tgz", + "integrity": "sha512-iwn46orWg3F4iqIzAVRfbzhnROyx7BQ7zJE0B7SEeaMIBvk3qmWtswtRk14QkMNUuNiCHQ6mAM00VJxWqrdM1g==", + "dev": true, + "requires": { + "is-plain-object": "^3.0.0", + "universal-user-agent": "^4.0.0" + }, + "dependencies": { + "is-plain-object": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.0.tgz", + "integrity": "sha512-tZIpofR+P05k8Aocp7UI/2UTa9lTJSebCXpFFoR9aibpokDj/uXBsJ8luUu0tTVYKkMU6URDUuOfJZ7koewXvg==", + "dev": true, + "requires": { + "isobject": "^4.0.0" + } + }, + "isobject": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-4.0.0.tgz", + "integrity": "sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA==", + "dev": true + } } }, "@octokit/request": { @@ -2496,6 +3060,12 @@ } } }, + "@types/color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", + "dev": true + }, "@types/eslint-visitor-keys": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", @@ -3680,6 +4250,16 @@ "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", "dev": true }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dev": true, + "optional": true, + "requires": { + "file-uri-to-path": "1.0.0" + } + }, "blob": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", @@ -3929,9 +4509,9 @@ "dev": true }, "buffer": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", - "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", "dev": true, "requires": { "base64-js": "^1.0.2", @@ -5640,9 +6220,9 @@ "dev": true }, "des.js": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", - "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", + "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", "dev": true, "requires": { "inherits": "^2.0.1", @@ -5655,6 +6235,12 @@ "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", "dev": true }, + "detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", + "dev": true + }, "detect-indent": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", @@ -5854,9 +6440,9 @@ "dev": true }, "elliptic": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.1.tgz", - "integrity": "sha512-xvJINNLbTeWQjrl6X+7eQCrIy/YPv5XCpKW6kB5mKvtnGILoLDcySuwomfdzt0BMdLNVnuRNTuzKNHj0bva1Cg==", + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.2.tgz", + "integrity": "sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw==", "dev": true, "requires": { "bn.js": "^4.4.0", @@ -6366,9 +6952,9 @@ "dev": true }, "events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.0.0.tgz", - "integrity": "sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", + "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==", "dev": true }, "eventsource": { @@ -6461,6 +7047,15 @@ } } }, + "expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, "express": { "version": "4.17.1", "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", @@ -6753,6 +7348,13 @@ } } }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true, + "optional": true + }, "fileset": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/fileset/-/fileset-2.0.3.tgz", @@ -6884,6 +7486,18 @@ "locate-path": "^3.0.0" } }, + "findup-sync": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", + "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", + "dev": true, + "requires": { + "detect-file": "^1.0.0", + "is-glob": "^4.0.0", + "micromatch": "^3.0.4", + "resolve-dir": "^1.0.1" + } + }, "flat-cache": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", @@ -7448,6 +8062,41 @@ "ini": "^1.3.4" } }, + "global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dev": true, + "requires": { + "global-prefix": "^3.0.0" + }, + "dependencies": { + "global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dev": true, + "requires": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + } + } + } + }, + "global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + } + }, "globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", @@ -7716,6 +8365,15 @@ "minimalistic-crypto-utils": "^1.0.1" } }, + "homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "dev": true, + "requires": { + "parse-passwd": "^1.0.0" + } + }, "hosted-git-info": { "version": "2.8.5", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.5.tgz", @@ -9699,6 +10357,12 @@ "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", "dev": true }, + "lodash-es": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.15.tgz", + "integrity": "sha512-rlrc3yU3+JNOpZ9zj5pQtxnx2THmvRykwL4Xlxoa8I9lHBlVbbyPhgyPMioxVZ4NqyxaVVtaJnzsyOidQIhyyQ==", + "dev": true + }, "lodash._reinterpolate": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", @@ -12219,6 +12883,12 @@ "json-parse-better-errors": "^1.0.1" } }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", + "dev": true + }, "parse5": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", @@ -13970,6 +14640,29 @@ "resolve-from": "^3.0.0" } }, + "resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + }, + "dependencies": { + "global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dev": true, + "requires": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + } + } + } + }, "resolve-from": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", @@ -16389,9 +17082,9 @@ } }, "vm-browserify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.0.tgz", - "integrity": "sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", + "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", "dev": true }, "void-elements": { @@ -16498,41 +17191,38 @@ } }, "fsevents": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", - "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.11.tgz", + "integrity": "sha512-+ux3lx6peh0BpvY0JebGyZoiR4D+oYzdPZMKJwkZ+sFkNJzpL7tXc/wehS49gUAxg3tmMHPHZkA8JU2rhhgDHw==", "dev": true, "optional": true, "requires": { + "bindings": "^1.5.0", "nan": "^2.12.1", - "node-pre-gyp": "^0.12.0" + "node-pre-gyp": "*" }, "dependencies": { "abbrev": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "bundled": true, "dev": true, "optional": true }, "ansi-regex": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "bundled": true, "dev": true, "optional": true }, "aproba": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "bundled": true, "dev": true, "optional": true }, "are-we-there-yet": { "version": "1.1.5", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", - "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -16542,15 +17232,13 @@ }, "balanced-match": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "bundled": true, "dev": true, "optional": true }, "brace-expansion": { "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -16559,44 +17247,38 @@ } }, "chownr": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz", - "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==", + "version": "1.1.3", + "bundled": true, "dev": true, "optional": true }, "code-point-at": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "bundled": true, "dev": true, "optional": true }, "concat-map": { "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "bundled": true, "dev": true, "optional": true }, "console-control-strings": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", + "bundled": true, "dev": true, "optional": true }, "core-util-is": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "bundled": true, "dev": true, "optional": true }, "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "3.2.6", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -16605,46 +17287,40 @@ }, "deep-extend": { "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "bundled": true, "dev": true, "optional": true }, "delegates": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "bundled": true, "dev": true, "optional": true }, "detect-libc": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", + "bundled": true, "dev": true, "optional": true }, "fs-minipass": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.5.tgz", - "integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==", + "version": "1.2.7", + "bundled": true, "dev": true, "optional": true, "requires": { - "minipass": "^2.2.1" + "minipass": "^2.6.0" } }, "fs.realpath": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "bundled": true, "dev": true, "optional": true }, "gauge": { "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -16659,9 +17335,8 @@ } }, "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "version": "7.1.6", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -16675,15 +17350,13 @@ }, "has-unicode": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "bundled": true, "dev": true, "optional": true }, "iconv-lite": { "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -16691,9 +17364,8 @@ } }, "ignore-walk": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.1.tgz", - "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==", + "version": "3.0.3", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -16702,8 +17374,7 @@ }, "inflight": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -16712,23 +17383,20 @@ } }, "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "version": "2.0.4", + "bundled": true, "dev": true, "optional": true }, "ini": { "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "bundled": true, "dev": true, "optional": true }, "is-fullwidth-code-point": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -16737,15 +17405,13 @@ }, "isarray": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "bundled": true, "dev": true, "optional": true }, "minimatch": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -16754,15 +17420,13 @@ }, "minimist": { "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "bundled": true, "dev": true, "optional": true }, "minipass": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.5.tgz", - "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==", + "version": "2.9.0", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -16771,19 +17435,17 @@ } }, "minizlib": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.2.1.tgz", - "integrity": "sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA==", + "version": "1.3.3", + "bundled": true, "dev": true, "optional": true, "requires": { - "minipass": "^2.2.1" + "minipass": "^2.9.0" } }, "mkdirp": { "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -16791,28 +17453,25 @@ } }, "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "version": "2.1.2", + "bundled": true, "dev": true, "optional": true }, "needle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/needle/-/needle-2.3.0.tgz", - "integrity": "sha512-QBZu7aAFR0522EyaXZM0FZ9GLpq6lvQ3uq8gteiDUp7wKdy0lSd2hPlgFwVuW1CBkfEs9PfDQsQzZghLs/psdg==", + "version": "2.4.0", + "bundled": true, "dev": true, "optional": true, "requires": { - "debug": "^4.1.0", + "debug": "^3.2.6", "iconv-lite": "^0.4.4", "sax": "^1.2.4" } }, "node-pre-gyp": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.12.0.tgz", - "integrity": "sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A==", + "version": "0.14.0", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -16825,13 +17484,12 @@ "rc": "^1.2.7", "rimraf": "^2.6.1", "semver": "^5.3.0", - "tar": "^4" + "tar": "^4.4.2" } }, "nopt": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", - "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -16840,16 +17498,23 @@ } }, "npm-bundled": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.0.6.tgz", - "integrity": "sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g==", + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npm-normalize-package-bin": { + "version": "1.0.1", + "bundled": true, "dev": true, "optional": true }, "npm-packlist": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.1.tgz", - "integrity": "sha512-+TcdO7HJJ8peiiYhvPxsEDhF3PJFGUGRcFsGve3vxvxdcpO2Z4Z7rkosRM0kWj6LfbK/P0gu3dzk5RU1ffvFcw==", + "version": "1.4.7", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -16859,8 +17524,7 @@ }, "npmlog": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -16872,22 +17536,19 @@ }, "number-is-nan": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "bundled": true, "dev": true, "optional": true }, "object-assign": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "bundled": true, "dev": true, "optional": true }, "once": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -16896,22 +17557,19 @@ }, "os-homedir": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "bundled": true, "dev": true, "optional": true }, "os-tmpdir": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "bundled": true, "dev": true, "optional": true }, "osenv": { "version": "0.1.5", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", - "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -16921,22 +17579,19 @@ }, "path-is-absolute": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "bundled": true, "dev": true, "optional": true }, "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "version": "2.0.1", + "bundled": true, "dev": true, "optional": true }, "rc": { "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -16948,8 +17603,7 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "bundled": true, "dev": true, "optional": true } @@ -16957,8 +17611,7 @@ }, "readable-stream": { "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -16972,9 +17625,8 @@ } }, "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "version": "2.7.1", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -16983,50 +17635,43 @@ }, "safe-buffer": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "bundled": true, "dev": true, "optional": true }, "safer-buffer": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "bundled": true, "dev": true, "optional": true }, "sax": { "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "bundled": true, "dev": true, "optional": true }, "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "version": "5.7.1", + "bundled": true, "dev": true, "optional": true }, "set-blocking": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "bundled": true, "dev": true, "optional": true }, "signal-exit": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "bundled": true, "dev": true, "optional": true }, "string-width": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -17037,8 +17682,7 @@ }, "string_decoder": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -17047,8 +17691,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -17057,38 +17700,34 @@ }, "strip-json-comments": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "bundled": true, "dev": true, "optional": true }, "tar": { - "version": "4.4.8", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.8.tgz", - "integrity": "sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ==", + "version": "4.4.13", + "bundled": true, "dev": true, "optional": true, "requires": { "chownr": "^1.1.1", "fs-minipass": "^1.2.5", - "minipass": "^2.3.4", - "minizlib": "^1.1.1", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", "mkdirp": "^0.5.0", "safe-buffer": "^5.1.2", - "yallist": "^3.0.2" + "yallist": "^3.0.3" } }, "util-deprecate": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "bundled": true, "dev": true, "optional": true }, "wide-align": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -17097,15 +17736,13 @@ }, "wrappy": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "bundled": true, "dev": true, "optional": true }, "yallist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", - "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", + "version": "3.1.1", + "bundled": true, "dev": true, "optional": true } @@ -17181,9 +17818,9 @@ } }, "webpack": { - "version": "4.39.2", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.39.2.tgz", - "integrity": "sha512-AKgTfz3xPSsEibH00JfZ9sHXGUwIQ6eZ9tLN8+VLzachk1Cw2LVmy+4R7ZiwTa9cZZ15tzySjeMui/UnSCAZhA==", + "version": "4.41.6", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.41.6.tgz", + "integrity": "sha512-yxXfV0Zv9WMGRD+QexkZzmGIh54bsvEs+9aRWxnN8erLWEOehAKUTeNBoUbA6HPEZPlRo7KDi2ZcNveoZgK9MA==", "dev": true, "requires": { "@webassemblyjs/ast": "1.8.5", @@ -17206,9 +17843,182 @@ "node-libs-browser": "^2.2.1", "schema-utils": "^1.0.0", "tapable": "^1.1.3", - "terser-webpack-plugin": "^1.4.1", + "terser-webpack-plugin": "^1.4.3", "watchpack": "^1.6.0", "webpack-sources": "^1.4.1" + }, + "dependencies": { + "find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + } + }, + "serialize-javascript": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz", + "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "terser-webpack-plugin": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz", + "integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==", + "dev": true, + "requires": { + "cacache": "^12.0.2", + "find-cache-dir": "^2.1.0", + "is-wsl": "^1.1.0", + "schema-utils": "^1.0.0", + "serialize-javascript": "^2.1.2", + "source-map": "^0.6.1", + "terser": "^4.1.2", + "webpack-sources": "^1.4.0", + "worker-farm": "^1.7.0" + } + } + } + }, + "webpack-cli": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.11.tgz", + "integrity": "sha512-dXlfuml7xvAFwYUPsrtQAA9e4DOe58gnzSxhgrO/ZM/gyXTBowrsYeubyN4mqGhYdpXMFNyQ6emjJS9M7OBd4g==", + "dev": true, + "requires": { + "chalk": "2.4.2", + "cross-spawn": "6.0.5", + "enhanced-resolve": "4.1.0", + "findup-sync": "3.0.0", + "global-modules": "2.0.0", + "import-local": "2.0.0", + "interpret": "1.2.0", + "loader-utils": "1.2.3", + "supports-color": "6.1.0", + "v8-compile-cache": "2.0.3", + "yargs": "13.2.4" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "v8-compile-cache": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz", + "integrity": "sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w==", + "dev": true + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + }, + "yargs": { + "version": "13.2.4", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.4.tgz", + "integrity": "sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "os-locale": "^3.1.0", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.0" + } + }, + "yargs-parser": { + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", + "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } } }, "webpack-core": { diff --git a/package.json b/package.json index d3b4acb..da8e58c 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,8 @@ "changelog": "node ./scripts/changelog.js", "build-package": "node ./scripts/build-package.js", "release": "node ./scripts/release.js", - "postversion": "npm run build-package" + "postversion": "npm run build-package", + "build-ckeditor": "cd ckeditor && webpack --mode production" }, "dependencies": { "@angular/animations": "^8.0.0", @@ -34,9 +35,29 @@ "@angular/cli": "^8.0.0", "@angular/compiler-cli": "^8.0.0", "@angular/language-service": "^8.0.0", - "@ckeditor/ckeditor5-build-classic": "^15.0.0", + "@ckeditor/ckeditor5-adapter-ckfinder": "^17.0.0", + "@ckeditor/ckeditor5-autoformat": "^17.0.0", + "@ckeditor/ckeditor5-basic-styles": "^17.0.0", + "@ckeditor/ckeditor5-block-quote": "^17.0.0", + "@ckeditor/ckeditor5-ckfinder": "^17.0.0", + "@ckeditor/ckeditor5-core": "^17.0.0", "@ckeditor/ckeditor5-dev-env": "^17.0.0", "@ckeditor/ckeditor5-dev-utils": "^12.0.1", + "@ckeditor/ckeditor5-dev-webpack-plugin": "^8.0.0", + "@ckeditor/ckeditor5-easy-image": "^17.0.0", + "@ckeditor/ckeditor5-editor-classic": "^17.0.0", + "@ckeditor/ckeditor5-essentials": "^17.0.0", + "@ckeditor/ckeditor5-heading": "^17.0.0", + "@ckeditor/ckeditor5-image": "^17.0.0", + "@ckeditor/ckeditor5-indent": "^17.0.0", + "@ckeditor/ckeditor5-link": "^17.0.0", + "@ckeditor/ckeditor5-list": "^17.0.0", + "@ckeditor/ckeditor5-media-embed": "^17.0.0", + "@ckeditor/ckeditor5-paragraph": "^17.0.0", + "@ckeditor/ckeditor5-paste-from-office": "^17.0.0", + "@ckeditor/ckeditor5-table": "^17.0.0", + "@ckeditor/ckeditor5-theme-lark": "^17.0.0", + "@ckeditor/ckeditor5-watchdog": "^17.0.0", "@types/jasmine": "^3.3.13", "@types/jasminewd2": "^2.0.6", "@typescript-eslint/eslint-plugin": "^2.5.0", @@ -59,7 +80,9 @@ "protractor": "^5.4.2", "ts-node": "^8.2.0", "tsickle": "^0.37.0", - "typescript": "~3.5.3" + "typescript": "~3.5.3", + "webpack": "^4.41.6", + "webpack-cli": "^3.3.11" }, "engines": { "node": ">=8.0.0", @@ -86,6 +109,7 @@ "eslintIgnore": [ "**/node_modules/**", "**/dist/**", - "src/polyfills.ts" + "src/polyfills.ts", + "ckeditor/**" ] } diff --git a/src/app/app.component.html b/src/app/app.component.html index ca78d6e..60b25a8 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -5,6 +5,8 @@

CKEditor 5 integration with Angular

  • Simple usage
  • Integration with forms (ngModel)
  • Integration with reactive forms (formControlName)
  • +
  • Integration with CKEditor Watchdog
  • +
  • Integration with CKEditor Context
  • diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 32fc169..7828cc7 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -8,12 +8,16 @@ import { CKEditorModule } from '../ckeditor/ckeditor.module'; import { SimpleUsageComponent } from './simple-usage/simple-usage.component'; import { DemoFormComponent } from './demo-form/demo-form.component'; import { DemoReactiveFormComponent } from './demo-reactive-form/demo-reactive-form.component'; +import { ContextDemoComponent } from './context-demo/context-demo'; +import { WatchdogDemoComponent } from './watchdog-demo/watchdog-demo'; const appRoutes: Routes = [ { path: '', redirectTo: '/simple-usage', pathMatch: 'full' }, - { path: 'simple-usage', component: SimpleUsageComponent }, + { path: 'context', component: ContextDemoComponent }, { path: 'forms', component: DemoFormComponent }, { path: 'reactive-forms', component: DemoReactiveFormComponent }, + { path: 'simple-usage', component: SimpleUsageComponent }, + { path: 'watchdog', component: WatchdogDemoComponent }, ]; @NgModule( { @@ -26,9 +30,11 @@ const appRoutes: Routes = [ ], declarations: [ AppComponent, + ContextDemoComponent, DemoFormComponent, DemoReactiveFormComponent, - SimpleUsageComponent + SimpleUsageComponent, + WatchdogDemoComponent, ], providers: [], bootstrap: [ AppComponent ] diff --git a/src/app/context-demo/context-demo.css b/src/app/context-demo/context-demo.css new file mode 100644 index 0000000..dde1df8 --- /dev/null +++ b/src/app/context-demo/context-demo.css @@ -0,0 +1,4 @@ +:host ::ng-deep .ck.ck-editor__editable.ck-read-only { + background: #fafafa; + color: #888; +} diff --git a/src/app/context-demo/context-demo.html b/src/app/context-demo/context-demo.html new file mode 100644 index 0000000..2817e56 --- /dev/null +++ b/src/app/context-demo/context-demo.html @@ -0,0 +1,6 @@ +

    Context demo

    + +
    + + +
    diff --git a/src/app/context-demo/context-demo.ts b/src/app/context-demo/context-demo.ts new file mode 100644 index 0000000..a107690 --- /dev/null +++ b/src/app/context-demo/context-demo.ts @@ -0,0 +1,45 @@ +import { Component, ElementRef, ViewChild } from '@angular/core'; +import { CKEditorComponent } from '../../ckeditor/ckeditor.component'; +import * as CKSource from '../../../ckeditor/build/cksource'; + +const Context = CKSource.Context; + +@Component( { + selector: 'context-demo', + templateUrl: './context-demo.html', + styleUrls: [ './context-demo.css' ] +} ) +export class ContextDemoComponent { + public Editor = CKSource.ClassicEditor; + @ViewChild( CKEditorComponent, { static: false } ) ckeditor?: ElementRef; + + public contextConfig: any; + public context: any; + public config: any; + public ready = false; + + public onReady( editor: any ) { + console.log( editor ); + } + + ngAfterViewInit() { + this.contextConfig = { + // Fill in cloud services data here: + collaboration: { + channelId: 'foobar' + } + }; + + Context.create( this.contextConfig ) + .then( () => { + this.config = { + context: this.context, + collaboration: { + channelId: 'foobar-baz' + } + }; + + this.ready = true; + } ); + } +} diff --git a/src/app/demo-form/demo-form.component.ts b/src/app/demo-form/demo-form.component.ts index c3458ed..c713cd6 100644 --- a/src/app/demo-form/demo-form.component.ts +++ b/src/app/demo-form/demo-form.component.ts @@ -4,8 +4,10 @@ import { AfterViewInit } from '@angular/core'; -import * as ClassicEditorBuild from '@ckeditor/ckeditor5-build-classic'; import { NgForm } from '@angular/forms'; +import * as CKSource from '../../../ckeditor/build/cksource'; + +const ClassicEditor = CKSource.ClassicEditor; @Component( { selector: 'app-demo-form', @@ -15,7 +17,7 @@ import { NgForm } from '@angular/forms'; export class DemoFormComponent implements AfterViewInit { @ViewChild( 'demoForm', { static: true } ) public demoForm?: NgForm; - public Editor = ClassicEditorBuild; + public Editor = ClassicEditor; public model = { name: 'John', surname: 'Doe', diff --git a/src/app/demo-reactive-form/demo-reactive-form.component.ts b/src/app/demo-reactive-form/demo-reactive-form.component.ts index 1cd1d74..6f30810 100644 --- a/src/app/demo-reactive-form/demo-reactive-form.component.ts +++ b/src/app/demo-reactive-form/demo-reactive-form.component.ts @@ -3,8 +3,10 @@ import { AfterViewInit } from '@angular/core'; -import * as ClassicEditorBuild from '@ckeditor/ckeditor5-build-classic'; import { FormGroup, FormControl } from '@angular/forms'; +import * as CKSource from '../../../ckeditor/build/cksource'; + +const ClassicEditor = CKSource.ClassicEditor; @Component( { selector: 'app-demo-reactive-form', @@ -12,7 +14,7 @@ import { FormGroup, FormControl } from '@angular/forms'; styleUrls: [ './demo-reactive-form.component.css' ] } ) export class DemoReactiveFormComponent implements AfterViewInit { - public Editor = ClassicEditorBuild; + public Editor = ClassicEditor; public demoReactiveForm = new FormGroup( { name: new FormControl( 'John' ), diff --git a/src/app/simple-usage/simple-usage.component.html b/src/app/simple-usage/simple-usage.component.html index 0a92b28..ca4db25 100644 --- a/src/app/simple-usage/simple-usage.component.html +++ b/src/app/simple-usage/simple-usage.component.html @@ -17,6 +17,7 @@

    Classic build

    (ready)="onReady()" (change)="onChange()" (focus)="onFocus()" + (error)="onError()" (blur)="onBlur()"> diff --git a/src/app/simple-usage/simple-usage.component.spec.ts b/src/app/simple-usage/simple-usage.component.spec.ts index 587bab7..d0d6906 100644 --- a/src/app/simple-usage/simple-usage.component.spec.ts +++ b/src/app/simple-usage/simple-usage.component.spec.ts @@ -1,4 +1,4 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; import { CKEditorModule } from '../../ckeditor/ckeditor.module'; import { SimpleUsageComponent } from './simple-usage.component'; @@ -12,13 +12,13 @@ describe( 'SimpleUsageComponent', () => { let ckeditorComponent: CKEditorComponent; let debugElement: DebugElement; - beforeEach( async( () => { - TestBed.configureTestingModule( { + beforeEach( () => { + return TestBed.configureTestingModule( { declarations: [ SimpleUsageComponent ], imports: [ CKEditorModule ] } ) .compileComponents(); - } ) ); + } ); beforeEach( () => { fixture = TestBed.createComponent( SimpleUsageComponent ); @@ -96,5 +96,11 @@ describe( 'SimpleUsageComponent', () => { expect( component.componentEvents ).toContain( 'Blurred the editing view.' ); } ); + + it( 'error should be called on ckeditorComponent.error()', () => { + ckeditorComponent.error.emit(); + + expect( component.componentEvents ).toContain( 'The editor crashed.' ); + } ); } ); } ); diff --git a/src/app/simple-usage/simple-usage.component.ts b/src/app/simple-usage/simple-usage.component.ts index 1410de7..f94190c 100644 --- a/src/app/simple-usage/simple-usage.component.ts +++ b/src/app/simple-usage/simple-usage.component.ts @@ -1,6 +1,7 @@ import { Component } from '@angular/core'; +import * as CKSource from '../../../ckeditor/build/cksource'; -import * as ClassicEditorBuild from '@ckeditor/ckeditor5-build-classic'; +const ClassicEditor = CKSource.ClassicEditor; @Component( { selector: 'app-simple-usage', @@ -8,7 +9,7 @@ import * as ClassicEditorBuild from '@ckeditor/ckeditor5-build-classic'; styleUrls: [ './simple-usage.component.css' ] } ) export class SimpleUsageComponent { - public Editor = ClassicEditorBuild; + public Editor = ClassicEditor; public isDisabled = false; public editorData = @@ -37,4 +38,8 @@ You learn to appreciate each and every single one of the differences while you b public onBlur() { this.componentEvents.push( 'Blurred the editing view.' ); } + + public onError() { + this.componentEvents.push( 'The editor crashed.' ); + } } diff --git a/src/app/watchdog-demo/watchdog-demo.css b/src/app/watchdog-demo/watchdog-demo.css new file mode 100644 index 0000000..dde1df8 --- /dev/null +++ b/src/app/watchdog-demo/watchdog-demo.css @@ -0,0 +1,4 @@ +:host ::ng-deep .ck.ck-editor__editable.ck-read-only { + background: #fafafa; + color: #888; +} diff --git a/src/app/watchdog-demo/watchdog-demo.html b/src/app/watchdog-demo/watchdog-demo.html new file mode 100644 index 0000000..c882dc1 --- /dev/null +++ b/src/app/watchdog-demo/watchdog-demo.html @@ -0,0 +1,6 @@ +

    Watchdog demo

    + +
    + + +
    diff --git a/src/app/watchdog-demo/watchdog-demo.ts b/src/app/watchdog-demo/watchdog-demo.ts new file mode 100644 index 0000000..c33e368 --- /dev/null +++ b/src/app/watchdog-demo/watchdog-demo.ts @@ -0,0 +1,41 @@ +import { Component, ElementRef, ViewChild } from '@angular/core'; +import { CKEditorComponent } from '../../ckeditor/ckeditor.component'; +import * as CKSource from '../../../ckeditor/build/cksource'; + +@Component( { + selector: 'watchdog-demo', + templateUrl: './watchdog-demo.html', + styleUrls: [ './watchdog-demo.css' ] +} ) +export class WatchdogDemoComponent { + public Editor = CKSource.ClassicEditor; + @ViewChild( CKEditorComponent, { static: false } ) ckeditor?: ElementRef; + + public context: any; + public config: any; + public watchdog: any; + public ready = false; + + public onReady( editor: any ) { + console.log( editor ); + } + + ngOnInit() { + const contextConfig = { + foo: 'bar' + }; + + this.config = { + collaboration: { + channelId: 'foobar-baz' + }, + }; + + this.watchdog = new CKSource.ContextWatchdog( CKSource.Context ); + + this.watchdog.create( contextConfig ) + .then( () => { + this.ready = true; + } ); + } +} diff --git a/src/ckeditor/ckeditor.component.spec.ts b/src/ckeditor/ckeditor.component.spec.ts index 47cd6dd..0389da1 100644 --- a/src/ckeditor/ckeditor.component.spec.ts +++ b/src/ckeditor/ckeditor.component.spec.ts @@ -5,7 +5,7 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { CKEditorComponent } from './ckeditor.component'; -import * as ClassicEditorBuild from '@ckeditor/ckeditor5-build-classic'; +import * as CKSource from '../../ckeditor/build/cksource'; describe( 'CKEditorComponent', () => { let component: CKEditorComponent; @@ -21,7 +21,7 @@ describe( 'CKEditorComponent', () => { beforeEach( () => { fixture = TestBed.createComponent( CKEditorComponent ); component = fixture.componentInstance; - component.editor = ClassicEditorBuild; + component.editor = CKSource.ClassicEditor; } ); afterEach( () => { @@ -36,7 +36,7 @@ describe( 'CKEditorComponent', () => { it( 'simple usage', () => { fixture.detectChanges(); - return wait().then( () => { + return waitCycle().then( () => { expect( component.disabled ).toBeFalsy(); expect( component.editorInstance!.isReadOnly ).toBeFalsy(); @@ -56,7 +56,7 @@ describe( 'CKEditorComponent', () => { fixture.detectChanges(); component.setDisabledState( true ); - return wait().then( () => { + return waitCycle().then( () => { expect( component.disabled ).toBeTruthy(); expect( component.editorInstance!.isReadOnly ).toBeTruthy(); } ); @@ -64,33 +64,35 @@ describe( 'CKEditorComponent', () => { } ); describe( 'tagName', () => { - it( 'should enable creating component on textarea element', () => { + it( 'should enable creating component on textarea element', async () => { component.tagName = 'textarea'; fixture.detectChanges(); - expect( fixture.nativeElement.lastChild.tagName ).toEqual( 'TEXTAREA' ); + await waitCycle(); + + expect( fixture.nativeElement.querySelector( 'textarea' ) ).toBeDefined(); } ); } ); describe( 'component data', () => { - it( 'initial data should be empty', () => { + it( 'initial data should be empty', async () => { fixture.detectChanges(); - return wait().then( () => { - expect( component.data ).toEqual( '' ); - expect( component.editorInstance!.getData() ).toEqual( '' ); - } ); + await waitCycle(); + + expect( component.data ).toEqual( '' ); + expect( component.editorInstance!.getData() ).toEqual( '' ); } ); - it( 'should be configurable at the start of the component using the `data` property', () => { + it( 'should be configurable at the start of the component using the `data` property', async () => { component.data = 'foo'; fixture.detectChanges(); - return wait().then( () => { - expect( component.data ).toEqual( 'foo' ); - expect( component.editorInstance!.getData() ).toEqual( '

    foo

    ' ); - } ); + await waitCycle(); + + expect( component.data ).toEqual( 'foo' ); + expect( component.editorInstance!.getData() ).toEqual( '

    foo

    ' ); } ); it( 'should be configurable at the start of the component using the `config.initialData` property', () => { @@ -98,43 +100,48 @@ describe( 'CKEditorComponent', () => { fixture.detectChanges(); - return wait().then( () => { + return waitCycle().then( () => { expect( component.config.initialData ).toEqual( 'foo' ); expect( component.editorInstance!.getData() ).toEqual( '

    foo

    ' ); } ); } ); - it( 'should not be provided using both `config.initialData` or `data` properties', () => { + it( 'should not be provided using both `config.initialData` or `data` properties', async () => { component.config = { initialData: 'foo' }; component.data = 'bar'; - expect( () => { + await expect( () => { fixture.detectChanges(); } ).toThrowError( 'Editor data should be provided either using `config.initialData` or `data` properties.' ); } ); - it( 'should be writeable by ControlValueAccessor', () => { + it( 'should be writeable by ControlValueAccessor', async () => { component.writeValue( 'foo' ); fixture.detectChanges(); - return wait().then( () => { - expect( component.editorInstance!.getData() ).toEqual( '

    foo

    ' ); + await waitCycle(); - component.writeValue( 'bar' ); + expect( component.editorInstance!.getData() ).toEqual( '

    foo

    ' ); - expect( component.editorInstance!.getData() ).toEqual( '

    bar

    ' ); - } ); + component.writeValue( 'bar' ); + + expect( component.editorInstance!.getData() ).toEqual( '

    bar

    ' ); } ); it( 'should not be set using `editor.setData()` during the initialization step', () => { class EventEmitter { /* eslint-disable-next-line */ - public on() {} + public on() { } + } + + class ModelDocument extends EventEmitter { + public getRootNames = () => []; + public version = 0; } class EditorMock { public model = { - document: new EventEmitter() + document: new ModelDocument() }; public editing = { @@ -150,7 +157,7 @@ describe( 'CKEditorComponent', () => { } /* eslint-disable-next-line */ - public destroy() {} + public destroy() { } } function createSpy() { @@ -173,7 +180,7 @@ describe( 'CKEditorComponent', () => { component.writeValue( 'foo' ); fixture.detectChanges(); - return wait().then( () => { + return waitCycle().then( () => { const fakeEditorInstance = component.editorInstance as any as EditorMock; expect( fakeEditorInstance.setData.called ).toBe( false ); @@ -190,7 +197,7 @@ describe( 'CKEditorComponent', () => { const spy = jasmine.createSpy(); component.ready.subscribe( spy ); - return wait().then( () => { + return waitCycle().then( () => { expect( spy ).toHaveBeenCalledTimes( 1 ); expect( spy ).toHaveBeenCalledWith( component.editorInstance ); } ); @@ -201,7 +208,7 @@ describe( 'CKEditorComponent', () => { const spy = jasmine.createSpy(); component.change.subscribe( spy ); - return wait().then( () => { + return waitCycle().then( () => { component.editorInstance!.execute( 'input', { text: 'foo' } ); expect( spy ).toHaveBeenCalledTimes( 1 ); @@ -216,7 +223,7 @@ describe( 'CKEditorComponent', () => { const changeSpy = jasmine.createSpy(); component.change.subscribe( changeSpy ); - return wait().then( () => { + return waitCycle().then( () => { spyOn( component.editorInstance!, 'getData' ).and.callThrough(); component.editorInstance!.execute( 'input', { text: 'foo' } ); @@ -233,7 +240,7 @@ describe( 'CKEditorComponent', () => { const spy = jasmine.createSpy(); component.focus.subscribe( spy ); - return wait().then( () => { + return waitCycle().then( () => { component.editorInstance!.editing.view.document.fire( 'focus' ); expect( spy ).toHaveBeenCalledTimes( 1 ); @@ -247,7 +254,7 @@ describe( 'CKEditorComponent', () => { const spy = jasmine.createSpy(); component.blur.subscribe( spy ); - return wait().then( () => { + return waitCycle().then( () => { component.editorInstance!.editing.view.focus(); component.editorInstance!.editing.view.document.fire( 'blur', { target: null } ); @@ -263,7 +270,7 @@ describe( 'CKEditorComponent', () => { it( 'onTouched callback should be called when editor is blurred', () => { fixture.detectChanges(); - return wait().then( () => { + return waitCycle().then( () => { const spy = jasmine.createSpy(); component.registerOnTouched( spy ); @@ -278,7 +285,7 @@ describe( 'CKEditorComponent', () => { it( 'onChange callback should be called when editor model changes with editor data', () => { fixture.detectChanges(); - return wait().then( () => { + return waitCycle().then( () => { const spy = jasmine.createSpy(); component.registerOnChange( spy ); @@ -291,7 +298,7 @@ describe( 'CKEditorComponent', () => { it( 'onChange callback should not be called when the change is coming from outside of the editor', () => { fixture.detectChanges(); - return wait().then( () => { + return waitCycle().then( () => { const spy = jasmine.createSpy(); component.registerOnChange( spy ); @@ -301,46 +308,134 @@ describe( 'CKEditorComponent', () => { } ); } ); } ); -} ); -describe( 'CKEditorComponent', () => { - describe( 'invalid initialization', () => { - let fixture: ComponentFixture; - let component: CKEditorComponent; - - class EditorThatThrowsErrorDuringInitialization { - public static create() { - return Promise.resolve().then( () => { - return Promise.reject( new Error() ); - } ); - } - } - - beforeEach( async( () => { - TestBed.configureTestingModule( { - declarations: [ CKEditorComponent ] - } ) - .compileComponents(); - } ) ); - - beforeEach( () => { - fixture = TestBed.createComponent( CKEditorComponent ); - component = fixture.componentInstance; - component.editor = EditorThatThrowsErrorDuringInitialization; + describe( 'in case of the context watchdog integration', () => { + it( 'should create an editor internally', async () => { + const contextWatchdog = new CKSource.ContextWatchdog( CKSource.Context ); + const spy = jasmine.createSpy(); + + await contextWatchdog.create(); + + component.watchdog = contextWatchdog; + component.ready.subscribe( spy ); + + fixture.detectChanges(); + + await waitCycle(); + + expect( spy ).toHaveBeenCalledTimes( 1 ); + expect( spy ).toHaveBeenCalledWith( component.editorInstance ); } ); - it( 'should result in error logged to the console', () => { - const spy = spyOn( console, 'error' ); + it( 'should fire the `error` event when an error occurs and the `ready` event afterwards #2', async () => { + // Create a second component to test whether the `error` event will be fired only + // on the proper component. + const fixture2 = TestBed.createComponent( CKEditorComponent ); + const component2 = fixture2.componentInstance; + + component2.editor = CKSource.ClassicEditor; + + window.onerror = null; + + const contextWatchdog = new CKSource.ContextWatchdog( CKSource.Context ); + + await contextWatchdog.create(); + + component.watchdog = contextWatchdog; + component2.watchdog = contextWatchdog; + fixture.detectChanges(); + fixture2.detectChanges(); + await waitCycle(); - return wait().then( () => { - expect( spy ).toHaveBeenCalled(); + const errorSpy = jasmine.createSpy( 'errorSpy' ); + const error2Spy = jasmine.createSpy( 'errorSpy' ); + const readySpy = jasmine.createSpy( 'readySpy' ); + + component.error.subscribe( errorSpy ); + component2.error.subscribe( error2Spy ); + component.ready.subscribe( readySpy ); + + await waitCycle(); + + const oldEditor = component.editorInstance; + + setTimeout( () => { + const error: any = new Error( 'foo' ); + error.is = () => true; + error.context = oldEditor; + + throw error; + } ); + + await waitCycle(); + + expect( errorSpy ).toHaveBeenCalledTimes( 1 ); + expect( readySpy ).toHaveBeenCalledTimes( 1 ); + + expect( error2Spy ).toHaveBeenCalledTimes( 0 ); + + fixture2.destroy(); + } ); + } ); + + describe( 'in case of the editor watchdog integration', () => { + it( 'should restart the editor when the editor crashes', async () => { + window.onerror = null; + + fixture.detectChanges(); + await waitCycle(); + + const oldEditor = component.editorInstance; + expect( oldEditor ).toBeTruthy(); + + setTimeout( () => { + const error: any = new Error( 'foo' ); + error.is = () => true; + error.context = oldEditor; + + throw error; } ); + + await waitCycle(); + + expect( oldEditor ).not.toEqual( component.editorInstance ); + expect( component.editorInstance ).toBeTruthy(); + } ); + + it( 'should fire the `error` event when an error occurs and the `ready` event afterwards', async () => { + window.onerror = null; + + fixture.detectChanges(); + await waitCycle(); + + const errorSpy = jasmine.createSpy( 'errorSpy' ); + const readySpy = jasmine.createSpy( 'readySpy' ); + + component.error.subscribe( errorSpy ); + component.ready.subscribe( readySpy ); + + await waitCycle(); + + const oldEditor = component.editorInstance; + + setTimeout( () => { + const error: any = new Error( 'foo' ); + error.is = () => true; + error.context = oldEditor; + + throw error; + } ); + + await waitCycle(); + + expect( errorSpy ).toHaveBeenCalledTimes( 1 ); + expect( readySpy ).toHaveBeenCalledTimes( 1 ); } ); } ); } ); -function wait( time?: number ) { +function waitCycle( time?: number ) { return new Promise( res => { setTimeout( res, time ); } ); diff --git a/src/ckeditor/ckeditor.component.ts b/src/ckeditor/ckeditor.component.ts index f628283..80dc19e 100644 --- a/src/ckeditor/ckeditor.component.ts +++ b/src/ckeditor/ckeditor.component.ts @@ -14,6 +14,10 @@ import { ElementRef } from '@angular/core'; +import EditorWatchdog from '@ckeditor/ckeditor5-watchdog/src/editorwatchdog'; + +import uid from './uid'; + import { ControlValueAccessor, NG_VALUE_ACCESSOR @@ -67,6 +71,11 @@ export class CKEditorComponent implements AfterViewInit, OnDestroy, ControlValue */ @Input() public tagName = 'div'; + /** + * The context watchdog. + */ + @Input() public watchdog?: CKEditor5.ContextWatchdog; + /** * When set `true`, the editor becomes read-only. * See https://ckeditor.com/docs/ckeditor5/latest/api/module_core_editor_editor-Editor.html#member-isReadOnly @@ -112,10 +121,31 @@ export class CKEditorComponent implements AfterViewInit, OnDestroy, ControlValue */ @Output() public focus: EventEmitter = new EventEmitter(); + /** + * Fires when the editor component crashes. + */ + @Output() public error: EventEmitter = new EventEmitter(); + /** * The instance of the editor created by this component. */ - public editorInstance: CKEditor5.Editor | null = null; + public get editorInstance(): CKEditor5.Editor | null { + if ( this.editorWatchdog ) { + return this.editorWatchdog.editor; + } + + if ( this.watchdog ) { + return this.watchdog.getItem( this.id ); + } + + return null; + } + + /** + * The editor watchdog. It is created when the context watchdog is not passed to the component. + * It keeps the editor running. + */ + private editorWatchdog?: CKEditor5.EditorWatchdog; /** * If the component is read–only before the editor instance is created, it remembers that state, @@ -155,6 +185,8 @@ export class CKEditorComponent implements AfterViewInit, OnDestroy, ControlValue */ private isEditorSettingData = false; + private id = uid(); + public constructor( elementRef: ElementRef, ngZone: NgZone ) { this.ngZone = ngZone; this.elementRef = elementRef; @@ -162,16 +194,17 @@ export class CKEditorComponent implements AfterViewInit, OnDestroy, ControlValue // Implementing the AfterViewInit interface. public ngAfterViewInit() { - this.ngZone.runOutsideAngular( () => { - this.createEditor(); - } ); + this.attachToWatchdog(); } // Implementing the OnDestroy interface. - public ngOnDestroy() { - if ( this.editorInstance ) { - this.editorInstance.destroy(); - this.editorInstance = null; + public async ngOnDestroy() { + if ( this.watchdog ) { + await this.watchdog.remove( this.id ); + } else if ( this.editorWatchdog && this.editorWatchdog.editor ) { + await this.editorWatchdog.destroy(); + + this.editorWatchdog = undefined; } } @@ -215,14 +248,13 @@ export class CKEditorComponent implements AfterViewInit, OnDestroy, ControlValue // Implementing the ControlValueAccessor interface (only when binding to ngModel). public setDisabledState( isDisabled: boolean ): void { - // If already initialized + // If already initialized. if ( this.editorInstance ) { this.editorInstance.isReadOnly = isDisabled; } - // If not, wait for it to be ready; store the state. - else { - this.initialIsDisabled = isDisabled; - } + + // Store the state anyway to use it once the editor is created. + this.initialIsDisabled = isDisabled; } /** @@ -230,25 +262,12 @@ export class CKEditorComponent implements AfterViewInit, OnDestroy, ControlValue * the editor with the Angular component. This method does not use the `editor.setData()` * because of the issue in the collaboration mode (#6). */ - private createEditor(): Promise { - const element = document.createElement( this.tagName ); - this.editorElement = element; - - if ( this.data && this.config.initialData ) { - throw new Error( 'Editor data should be provided either using `config.initialData` or `data` properties.' ); - } - - // Merge two possible ways of providing data into the `config.initialData` field. - const config = { - ...this.config, - initialData: this.config.initialData || this.data || '' - }; - - this.elementRef.nativeElement.appendChild( element ); + private attachToWatchdog() { + const creator = async ( element: HTMLElement, config: CKEditor5.Config ) => { + return this.ngZone.runOutsideAngular( async () => { + this.elementRef.nativeElement.appendChild( element ); - return this.editor!.create( element, config ) - .then( editor => { - this.editorInstance = editor; + const editor = await this.editor!.create( element, config ); if ( this.initialIsDisabled ) { editor.isReadOnly = this.initialIsDisabled; @@ -259,10 +278,69 @@ export class CKEditorComponent implements AfterViewInit, OnDestroy, ControlValue } ); this.setUpEditorEvents( editor ); - } ) - .catch( ( err: Error ) => { - console.error( err.stack ); + + return editor; + } ); + }; + + const destructor = async ( editor: CKEditor5.Editor ) => { + await editor.destroy(); + + this.elementRef.nativeElement.removeChild( this.editorElement! ); + }; + + const emitError = () => { + this.ngZone.run( () => { + this.error.emit(); + } ); + }; + + const element = document.createElement( this.tagName ); + const config = this.getConfig(); + + this.editorElement = element; + + // Based on the presence of the watchdog decide how to initialize the editor. + if ( this.watchdog ) { + // When the context watchdog is passed add the new item to it based on the passed configuration. + this.watchdog.add( { + id: this.id, + type: 'editor', + creator, + destructor, + sourceElementOrData: element, + config } ); + + this.watchdog.on( 'itemError', ( _, { itemId } ) => { + if ( itemId === this.id ) { + emitError(); + } + } ); + } else { + // In the other case create the watchdog by hand to keep the editor running. + const editorWatchdog: CKEditor5.EditorWatchdog = new EditorWatchdog( this.editor ); + + editorWatchdog.setCreator( creator ); + editorWatchdog.setDestructor( destructor ); + editorWatchdog.on( 'error', emitError ); + + this.editorWatchdog = editorWatchdog; + + this.editorWatchdog.create( element, config ); + } + } + + private getConfig() { + if ( this.data && this.config.initialData ) { + throw new Error( 'Editor data should be provided either using `config.initialData` or `data` properties.' ); + } + + // Merge two possible ways of providing data into the `config.initialData` field. + return { + ...this.config, + initialData: this.config.initialData || this.data || '' + }; } /** diff --git a/src/ckeditor/ckeditor.ts b/src/ckeditor/ckeditor.ts index 08bf8e0..65c14c6 100644 --- a/src/ckeditor/ckeditor.ts +++ b/src/ckeditor/ckeditor.ts @@ -86,4 +86,24 @@ export namespace CKEditor5 { * E.g. the `ClassicEditor`, `InlineEditor`, etc. */ export interface Editor extends BaseEditor, DataApi {} + + export interface ContextWatchdog extends Watchdog{ + context: any; + add( items: any ): Promise; + remove( items: string | string[] ): Promise; + getItem( itemId: string ): Editor; + addItemWatchdog( itemId: string, itemType: string, watchdog: Watchdog ): Promise; + } + + export interface EditorWatchdog extends Watchdog { + editor: Editor; + } + + export interface Watchdog { + setCreator( creator: ( ...args: any[] ) => Promise ): void; + setDestructor( destructor: ( item: T ) => Promise ): void; + on( event: string, callback: ( ...args: any ) => any ): void; + destroy(): Promise; + create( ...args: any[] ): Promise; + } } diff --git a/src/ckeditor/index.spec.ts b/src/ckeditor/index.spec.ts index 892a814..03f994d 100644 --- a/src/ckeditor/index.spec.ts +++ b/src/ckeditor/index.spec.ts @@ -4,7 +4,7 @@ */ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; -import * as ClassicEditorBuild from '@ckeditor/ckeditor5-build-classic'; +import * as CKSource from '../../ckeditor/build/cksource'; import { CKEditorComponent, @@ -26,7 +26,7 @@ describe( 'index.ts - the entry file', () => { beforeEach( () => { fixture = TestBed.createComponent( CKEditorComponent ); component = fixture.componentInstance; - component.editor = ClassicEditorBuild; + component.editor = CKSource.ClassicEditor; } ); it( 'should expose the CKEditorComponent', () => { diff --git a/src/ckeditor/uid.ts b/src/ckeditor/uid.ts new file mode 100644 index 0000000..09d0011 --- /dev/null +++ b/src/ckeditor/uid.ts @@ -0,0 +1,57 @@ +/** + * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +// A copy of @ckeditor/ckeditor5-utils/src/uid.js + +// A hash table of hex numbers to avoid using toString() in uid() which is costly. +// [ '00', '01', '02', ..., 'fe', 'ff' ] +const HEX_NUMBERS = new Array( 256 ).fill( 0 ) + .map( ( val, index ) => ( '0' + ( index ).toString( 16 ) ).slice( -2 ) ); + +/** + * Returns a unique id. The id starts with an "e" character and a randomly generated string of + * 32 alphanumeric characters. + * + * **Note**: The characters the unique id is built from correspond to the hex number notation + * (from "0" to "9", from "a" to "f"). In other words, each id corresponds to an "e" followed + * by 16 8-bit numbers next to each other. + * + * @returns An unique id string. + */ +export default function uid() { + // Let's create some positive random 32bit integers first. + // + // 1. Math.random() is a float between 0 and 1. + // 2. 0x100000000 is 2^32 = 4294967296. + // 3. >>> 0 enforces integer (in JS all numbers are floating point). + // + // For instance: + // Math.random() * 0x100000000 = 3366450031.853859 + // but + // Math.random() * 0x100000000 >>> 0 = 3366450031. + const r1 = Math.random() * 0x100000000 >>> 0; + const r2 = Math.random() * 0x100000000 >>> 0; + const r3 = Math.random() * 0x100000000 >>> 0; + const r4 = Math.random() * 0x100000000 >>> 0; + + // Make sure that id does not start with number. + return 'e' + + HEX_NUMBERS[ r1 >> 0 & 0xFF ] + + HEX_NUMBERS[ r1 >> 8 & 0xFF ] + + HEX_NUMBERS[ r1 >> 16 & 0xFF ] + + HEX_NUMBERS[ r1 >> 24 & 0xFF ] + + HEX_NUMBERS[ r2 >> 0 & 0xFF ] + + HEX_NUMBERS[ r2 >> 8 & 0xFF ] + + HEX_NUMBERS[ r2 >> 16 & 0xFF ] + + HEX_NUMBERS[ r2 >> 24 & 0xFF ] + + HEX_NUMBERS[ r3 >> 0 & 0xFF ] + + HEX_NUMBERS[ r3 >> 8 & 0xFF ] + + HEX_NUMBERS[ r3 >> 16 & 0xFF ] + + HEX_NUMBERS[ r3 >> 24 & 0xFF ] + + HEX_NUMBERS[ r4 >> 0 & 0xFF ] + + HEX_NUMBERS[ r4 >> 8 & 0xFF ] + + HEX_NUMBERS[ r4 >> 16 & 0xFF ] + + HEX_NUMBERS[ r4 >> 24 & 0xFF ]; +} diff --git a/src/typings.d.ts b/src/typings.d.ts index f297c29..79b6468 100644 --- a/src/typings.d.ts +++ b/src/typings.d.ts @@ -1,7 +1,8 @@ // Typings for the editor used in the sample app to satisfy the TS compiler. -declare module '@ckeditor/ckeditor5-build-classic' { - const ClassicEditorBuild: any; +declare module '@ckeditor/ckeditor5-watchdog/src/editorwatchdog' { + const EditorWatchdog: any; + type EditorWatchdog = any; - export = ClassicEditorBuild; + export default EditorWatchdog; } diff --git a/tsconfig.json b/tsconfig.json index 18c2c7f..48184ea 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -10,7 +10,7 @@ "moduleResolution": "node", "emitDecoratorMetadata": true, "experimentalDecorators": true, - "target": "es2015", + "target": "es2018", "typeRoots": [ "node_modules/@types" ],