diff --git a/README.md b/README.md index c7f492b..dc48fce 100644 --- a/README.md +++ b/README.md @@ -29,27 +29,27 @@ Examples of version specifications that the java-version parameter will accept: - A major Java version e.g. ```6, 7, 8, 9, 10, 11, 12, 13, ...``` - + - A semver Java version specification e.g. ```8.0.232, 7.0.181, 11.0.4``` - + e.g. ```8.0.x, >11.0.3, >=13.0.1, <8.0.212``` - + - An early access (EA) Java version e.g. ```14-ea, 15-ea``` - + e.g. ```14.0.0-ea, 15.0.0-ea``` - + e.g. ```14.0.0-ea.28, 15.0.0-ea.2``` (syntax for specifying an EA build number) - + Note that, per semver rules, EA builds will be matched by explicit EA version specifications. - + - 1.x syntax e.g. ```1.8``` (same as ```8```) - + e.g. ```1.8.0.212``` (same as ```8.0.212```) @@ -113,39 +113,58 @@ jobs: server-id: maven # Value of the distributionManagement/repository/id field of the pom.xml server-username: MAVEN_USERNAME # env variable for username in deploy server-password: MAVEN_CENTRAL_TOKEN # env variable for token in deploy + gpg-private-key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }} # Value of the GPG private key to import + gpg-passphrase: MAVEN_GPG_PASSPHRASE # env variable for GPG private key passphrase - name: Publish to Apache Maven Central - run: mvn deploy + run: mvn deploy env: MAVEN_USERNAME: maven_username123 MAVEN_CENTRAL_TOKEN: ${{ secrets.MAVEN_CENTRAL_TOKEN }} + MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }} ``` The two `settings.xml` files created from the above example look like the following. `settings.xml` file created for the first deploy to GitHub Packages ```xml - + + github ${env.GITHUB_ACTOR} ${env.GITHUB_TOKEN} - + + gpg.passphrase + ${env.GPG_PASSPHRASE} + + + ``` `settings.xml` file created for the second deploy to Apache Maven Central ```xml - + + maven ${env.MAVEN_USERNAME} ${env.MAVEN_CENTRAL_TOKEN} - + + gpg.passphrase + ${env.MAVEN_GPG_PASSPHRASE} + + + ``` -***NOTE: The `settings.xml` file is created in the Actions $HOME directory. If you have an existing `settings.xml` file at that location, it will be overwritten. See below for using the `settings-path` to change your `settings.xml` file location.*** +***NOTE: The `settings.xml` file is created in the Actions $HOME directory. If you have an existing `settings.xml` file at that location, it will be overwritten. See below for using the `settings-path` to change your `settings.xml` file location.*** See the help docs on [Publishing a Package](https://help.github.com/en/github/managing-packages-with-github-packages/configuring-apache-maven-for-use-with-github-packages#publishing-a-package) for more information on the `pom.xml` file. @@ -172,7 +191,7 @@ jobs: PASSWORD: ${{ secrets.GITHUB_TOKEN }} ``` -***NOTE: The `USERNAME` and `PASSWORD` need to correspond to the credentials environment variables used in the publishing section of your `build.gradle`.*** +***NOTE: The `USERNAME` and `PASSWORD` need to correspond to the credentials environment variables used in the publishing section of your `build.gradle`.*** See the help docs on [Publishing a Package with Gradle](https://help.github.com/en/github/managing-packages-with-github-packages/configuring-gradle-for-use-with-github-packages#example-using-gradle-groovy-for-a-single-package-in-a-repository) for more information on the `build.gradle` configuration file. diff --git a/__tests__/auth.test.ts b/__tests__/auth.test.ts index 1350968..b460e93 100644 --- a/__tests__/auth.test.ts +++ b/__tests__/auth.test.ts @@ -53,7 +53,7 @@ describe('auth tests', () => { await io.rmRF(altHome); }, 100000); - it('creates settings.xml with username and password', async () => { + it('creates settings.xml with minimal configuration', async () => { const id = 'packages'; const username = 'UNAME'; const password = 'TOKEN'; @@ -67,6 +67,21 @@ describe('auth tests', () => { ); }, 100000); + it('creates settings.xml with additional configuration', async () => { + const id = 'packages'; + const username = 'UNAME'; + const password = 'TOKEN'; + const gpgPassphrase = 'GPG'; + + await auth.configAuthentication(id, username, password, gpgPassphrase); + + expect(fs.existsSync(m2Dir)).toBe(true); + expect(fs.existsSync(settingsFile)).toBe(true); + expect(fs.readFileSync(settingsFile, 'utf-8')).toEqual( + auth.generate(id, username, password, gpgPassphrase) + ); + }, 100000); + it('overwrites existing settings.xml files', async () => { const id = 'packages'; const username = 'USERNAME'; @@ -86,59 +101,50 @@ describe('auth tests', () => { ); }, 100000); - it('does not create settings.xml without required parameters', async () => { - await auth.configAuthentication('FOO'); - - expect(fs.existsSync(m2Dir)).toBe(true); - expect(fs.existsSync(settingsFile)).toBe(true); - expect(fs.readFileSync(settingsFile, 'utf-8')).toEqual( - auth.generate('FOO', auth.DEFAULT_USERNAME, auth.DEFAULT_PASSWORD) - ); - - await auth.configAuthentication(undefined, 'BAR', undefined); - - expect(fs.existsSync(m2Dir)).toBe(true); - expect(fs.existsSync(settingsFile)).toBe(true); - expect(fs.readFileSync(settingsFile, 'utf-8')).toEqual( - auth.generate(auth.DEFAULT_ID, 'BAR', auth.DEFAULT_PASSWORD) - ); - - await auth.configAuthentication(undefined, undefined, 'BAZ'); - - expect(fs.existsSync(m2Dir)).toBe(true); - expect(fs.existsSync(settingsFile)).toBe(true); - expect(fs.readFileSync(settingsFile, 'utf-8')).toEqual( - auth.generate(auth.DEFAULT_ID, auth.DEFAULT_USERNAME, 'BAZ') - ); - - await auth.configAuthentication(); - - expect(fs.existsSync(m2Dir)).toBe(true); - expect(fs.existsSync(settingsFile)).toBe(true); - expect(fs.readFileSync(settingsFile, 'utf-8')).toEqual( - auth.generate( - auth.DEFAULT_ID, - auth.DEFAULT_USERNAME, - auth.DEFAULT_PASSWORD - ) - ); - }, 100000); - - it('escapes invalid XML inputs', () => { + it('generates valid settings.xml with minimal configuration', () => { const id = 'packages'; const username = 'USER'; const password = '&<>"\'\'"><&'; - expect(auth.generate(id, username, password)).toEqual(` - - - - ${id} - \${env.${username}} - \${env.&<>"''"><&} - - - - `); + const expectedSettings = ` + + + ${id} + \${env.${username}} + \${env.&<>"''"><&} + + +`; + + expect(auth.generate(id, username, password)).toEqual(expectedSettings); + }); + + it('generates valid settings.xml with additional configuration', () => { + const id = 'packages'; + const username = 'USER'; + const password = '&<>"\'\'"><&'; + const gpgPassphrase = 'PASSPHRASE'; + + const expectedSettings = ` + + + ${id} + \${env.${username}} + \${env.&<>"''"><&} + + + gpg.passphrase + \${env.${gpgPassphrase}} + + +`; + + expect(auth.generate(id, username, password, gpgPassphrase)).toEqual( + expectedSettings + ); }); }); diff --git a/__tests__/gpg.test.ts b/__tests__/gpg.test.ts new file mode 100644 index 0000000..2248b04 --- /dev/null +++ b/__tests__/gpg.test.ts @@ -0,0 +1,56 @@ +import path = require('path'); +import io = require('@actions/io'); +import exec = require('@actions/exec'); + +jest.mock('@actions/exec', () => { + return { + exec: jest.fn() + }; +}); + +const tempDir = path.join(__dirname, 'runner', 'temp'); +process.env['RUNNER_TEMP'] = tempDir; + +import gpg = require('../src/gpg'); + +describe('gpg tests', () => { + beforeEach(async () => { + await io.mkdirP(tempDir); + }, 300000); + + afterAll(async () => { + try { + await io.rmRF(tempDir); + } catch { + console.log('Failed to remove test directories'); + } + }, 100000); + + describe('importKey', () => { + it('attempts to import private key and returns null key id on failure', async () => { + const privateKey = 'KEY CONTENTS'; + const keyId = await gpg.importKey(privateKey); + + expect(keyId).toBeNull(); + + expect(exec.exec).toHaveBeenCalledWith( + 'gpg', + expect.anything(), + expect.anything() + ); + }); + }); + + describe('deleteKey', () => { + it('deletes private key', async () => { + const keyId = 'asdfhjkl'; + await gpg.deleteKey(keyId); + + expect(exec.exec).toHaveBeenCalledWith( + 'gpg', + expect.anything(), + expect.anything() + ); + }); + }); +}); diff --git a/__tests__/util.test.ts b/__tests__/util.test.ts new file mode 100644 index 0000000..4ef37cf --- /dev/null +++ b/__tests__/util.test.ts @@ -0,0 +1,61 @@ +import path = require('path'); + +const env = process.env; + +describe('util tests', () => { + beforeEach(() => { + const tempEnv = Object.assign({}, env); + delete tempEnv.RUNNER_TEMP; + delete tempEnv.USERPROFILE; + process.env = tempEnv; + Object.defineProperty(process, 'platform', {value: 'linux'}); + }); + + describe('getTempDir', () => { + it('gets temp dir using env', () => { + process.env['RUNNER_TEMP'] = 'defaulttmp'; + const util = require('../src/util'); + + const tempDir = util.getTempDir(); + + expect(tempDir).toEqual(process.env['RUNNER_TEMP']); + }); + + it('gets temp dir for windows using userprofile', () => { + Object.defineProperty(process, 'platform', {value: 'win32'}); + process.env['USERPROFILE'] = 'winusertmp'; + const util = require('../src/util'); + + const tempDir = util.getTempDir(); + + expect(tempDir).toEqual( + path.join(process.env['USERPROFILE'], 'actions', 'temp') + ); + }); + + it('gets temp dir for windows using c drive', () => { + Object.defineProperty(process, 'platform', {value: 'win32'}); + const util = require('../src/util'); + + const tempDir = util.getTempDir(); + + expect(tempDir).toEqual(path.join('C:\\', 'actions', 'temp')); + }); + + it('gets temp dir for mac', () => { + Object.defineProperty(process, 'platform', {value: 'darwin'}); + const util = require('../src/util'); + + const tempDir = util.getTempDir(); + + expect(tempDir).toEqual(path.join('/Users', 'actions', 'temp')); + }); + + it('gets temp dir for linux', () => { + const util = require('../src/util'); + const tempDir = util.getTempDir(); + + expect(tempDir).toEqual(path.join('/home', 'actions', 'temp')); + }); + }); +}); diff --git a/action.yml b/action.yml index de7711f..e3f4430 100644 --- a/action.yml +++ b/action.yml @@ -36,6 +36,14 @@ inputs: settings-path: description: 'Path to where the settings.xml file will be written. Default is ~/.m2.' required: false + gpg-private-key: + description: 'GPG private key to import. Default is empty string.' + required: false + gpg-passphrase: + description: 'Environment variable name for the GPG private key passphrase. Default is + $GPG_PASSPHRASE.' + required: false runs: using: 'node12' - main: 'dist/index.js' + main: 'dist/setup/index.js' + post: 'dist/cleanup/index.js' diff --git a/dist/cleanup/index.js b/dist/cleanup/index.js new file mode 100644 index 0000000..aa1ed2d --- /dev/null +++ b/dist/cleanup/index.js @@ -0,0 +1,1682 @@ +module.exports = +/******/ (function(modules, runtime) { // webpackBootstrap +/******/ "use strict"; +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ __webpack_require__.ab = __dirname + "/"; +/******/ +/******/ // the startup function +/******/ function startup() { +/******/ // Load entry module and return exports +/******/ return __webpack_require__(219); +/******/ }; +/******/ +/******/ // run startup +/******/ return startup(); +/******/ }) +/************************************************************************/ +/******/ ({ + +/***/ 1: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const childProcess = __webpack_require__(129); +const path = __webpack_require__(622); +const util_1 = __webpack_require__(669); +const ioUtil = __webpack_require__(672); +const exec = util_1.promisify(childProcess.exec); +/** + * Copies a file or folder. + * Based off of shelljs - https://github.com/shelljs/shelljs/blob/9237f66c52e5daa40458f94f9565e18e8132f5a6/src/cp.js + * + * @param source source path + * @param dest destination path + * @param options optional. See CopyOptions. + */ +function cp(source, dest, options = {}) { + return __awaiter(this, void 0, void 0, function* () { + const { force, recursive } = readCopyOptions(options); + const destStat = (yield ioUtil.exists(dest)) ? yield ioUtil.stat(dest) : null; + // Dest is an existing file, but not forcing + if (destStat && destStat.isFile() && !force) { + return; + } + // If dest is an existing directory, should copy inside. + const newDest = destStat && destStat.isDirectory() + ? path.join(dest, path.basename(source)) + : dest; + if (!(yield ioUtil.exists(source))) { + throw new Error(`no such file or directory: ${source}`); + } + const sourceStat = yield ioUtil.stat(source); + if (sourceStat.isDirectory()) { + if (!recursive) { + throw new Error(`Failed to copy. ${source} is a directory, but tried to copy without recursive flag.`); + } + else { + yield cpDirRecursive(source, newDest, 0, force); + } + } + else { + if (path.relative(source, newDest) === '') { + // a file cannot be copied to itself + throw new Error(`'${newDest}' and '${source}' are the same file`); + } + yield copyFile(source, newDest, force); + } + }); +} +exports.cp = cp; +/** + * Moves a path. + * + * @param source source path + * @param dest destination path + * @param options optional. See MoveOptions. + */ +function mv(source, dest, options = {}) { + return __awaiter(this, void 0, void 0, function* () { + if (yield ioUtil.exists(dest)) { + let destExists = true; + if (yield ioUtil.isDirectory(dest)) { + // If dest is directory copy src into dest + dest = path.join(dest, path.basename(source)); + destExists = yield ioUtil.exists(dest); + } + if (destExists) { + if (options.force == null || options.force) { + yield rmRF(dest); + } + else { + throw new Error('Destination already exists'); + } + } + } + yield mkdirP(path.dirname(dest)); + yield ioUtil.rename(source, dest); + }); +} +exports.mv = mv; +/** + * Remove a path recursively with force + * + * @param inputPath path to remove + */ +function rmRF(inputPath) { + return __awaiter(this, void 0, void 0, function* () { + if (ioUtil.IS_WINDOWS) { + // Node doesn't provide a delete operation, only an unlink function. This means that if the file is being used by another + // program (e.g. antivirus), it won't be deleted. To address this, we shell out the work to rd/del. + try { + if (yield ioUtil.isDirectory(inputPath, true)) { + yield exec(`rd /s /q "${inputPath}"`); + } + else { + yield exec(`del /f /a "${inputPath}"`); + } + } + catch (err) { + // if you try to delete a file that doesn't exist, desired result is achieved + // other errors are valid + if (err.code !== 'ENOENT') + throw err; + } + // Shelling out fails to remove a symlink folder with missing source, this unlink catches that + try { + yield ioUtil.unlink(inputPath); + } + catch (err) { + // if you try to delete a file that doesn't exist, desired result is achieved + // other errors are valid + if (err.code !== 'ENOENT') + throw err; + } + } + else { + let isDir = false; + try { + isDir = yield ioUtil.isDirectory(inputPath); + } + catch (err) { + // if you try to delete a file that doesn't exist, desired result is achieved + // other errors are valid + if (err.code !== 'ENOENT') + throw err; + return; + } + if (isDir) { + yield exec(`rm -rf "${inputPath}"`); + } + else { + yield ioUtil.unlink(inputPath); + } + } + }); +} +exports.rmRF = rmRF; +/** + * Make a directory. Creates the full path with folders in between + * Will throw if it fails + * + * @param fsPath path to create + * @returns Promise + */ +function mkdirP(fsPath) { + return __awaiter(this, void 0, void 0, function* () { + yield ioUtil.mkdirP(fsPath); + }); +} +exports.mkdirP = mkdirP; +/** + * Returns path of a tool had the tool actually been invoked. Resolves via paths. + * If you check and the tool does not exist, it will throw. + * + * @param tool name of the tool + * @param check whether to check if tool exists + * @returns Promise path to tool + */ +function which(tool, check) { + return __awaiter(this, void 0, void 0, function* () { + if (!tool) { + throw new Error("parameter 'tool' is required"); + } + // recursive when check=true + if (check) { + const result = yield which(tool, false); + if (!result) { + if (ioUtil.IS_WINDOWS) { + throw new Error(`Unable to locate executable file: ${tool}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also verify the file has a valid extension for an executable file.`); + } + else { + throw new Error(`Unable to locate executable file: ${tool}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also check the file mode to verify the file is executable.`); + } + } + } + try { + // build the list of extensions to try + const extensions = []; + if (ioUtil.IS_WINDOWS && process.env.PATHEXT) { + for (const extension of process.env.PATHEXT.split(path.delimiter)) { + if (extension) { + extensions.push(extension); + } + } + } + // if it's rooted, return it if exists. otherwise return empty. + if (ioUtil.isRooted(tool)) { + const filePath = yield ioUtil.tryGetExecutablePath(tool, extensions); + if (filePath) { + return filePath; + } + return ''; + } + // if any path separators, return empty + if (tool.includes('/') || (ioUtil.IS_WINDOWS && tool.includes('\\'))) { + return ''; + } + // build the list of directories + // + // Note, technically "where" checks the current directory on Windows. From a toolkit perspective, + // it feels like we should not do this. Checking the current directory seems like more of a use + // case of a shell, and the which() function exposed by the toolkit should strive for consistency + // across platforms. + const directories = []; + if (process.env.PATH) { + for (const p of process.env.PATH.split(path.delimiter)) { + if (p) { + directories.push(p); + } + } + } + // return the first match + for (const directory of directories) { + const filePath = yield ioUtil.tryGetExecutablePath(directory + path.sep + tool, extensions); + if (filePath) { + return filePath; + } + } + return ''; + } + catch (err) { + throw new Error(`which failed with message ${err.message}`); + } + }); +} +exports.which = which; +function readCopyOptions(options) { + const force = options.force == null ? true : options.force; + const recursive = Boolean(options.recursive); + return { force, recursive }; +} +function cpDirRecursive(sourceDir, destDir, currentDepth, force) { + return __awaiter(this, void 0, void 0, function* () { + // Ensure there is not a run away recursive copy + if (currentDepth >= 255) + return; + currentDepth++; + yield mkdirP(destDir); + const files = yield ioUtil.readdir(sourceDir); + for (const fileName of files) { + const srcFile = `${sourceDir}/${fileName}`; + const destFile = `${destDir}/${fileName}`; + const srcFileStat = yield ioUtil.lstat(srcFile); + if (srcFileStat.isDirectory()) { + // Recurse + yield cpDirRecursive(srcFile, destFile, currentDepth, force); + } + else { + yield copyFile(srcFile, destFile, force); + } + } + // Change the mode for the newly created directory + yield ioUtil.chmod(destDir, (yield ioUtil.stat(sourceDir)).mode); + }); +} +// Buffered file copy +function copyFile(srcFile, destFile, force) { + return __awaiter(this, void 0, void 0, function* () { + if ((yield ioUtil.lstat(srcFile)).isSymbolicLink()) { + // unlink/re-link it + try { + yield ioUtil.lstat(destFile); + yield ioUtil.unlink(destFile); + } + catch (e) { + // Try to override file permission + if (e.code === 'EPERM') { + yield ioUtil.chmod(destFile, '0666'); + yield ioUtil.unlink(destFile); + } + // other errors = it doesn't exist, no work to do + } + // Copy over symlink + const symlinkFull = yield ioUtil.readlink(srcFile); + yield ioUtil.symlink(symlinkFull, destFile, ioUtil.IS_WINDOWS ? 'junction' : null); + } + else if (!(yield ioUtil.exists(destFile)) || force) { + yield ioUtil.copyFile(srcFile, destFile); + } + }); +} +//# sourceMappingURL=io.js.map + +/***/ }), + +/***/ 9: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const os = __webpack_require__(87); +const events = __webpack_require__(614); +const child = __webpack_require__(129); +const path = __webpack_require__(622); +const io = __webpack_require__(1); +const ioUtil = __webpack_require__(672); +/* eslint-disable @typescript-eslint/unbound-method */ +const IS_WINDOWS = process.platform === 'win32'; +/* + * Class for running command line tools. Handles quoting and arg parsing in a platform agnostic way. + */ +class ToolRunner extends events.EventEmitter { + constructor(toolPath, args, options) { + super(); + if (!toolPath) { + throw new Error("Parameter 'toolPath' cannot be null or empty."); + } + this.toolPath = toolPath; + this.args = args || []; + this.options = options || {}; + } + _debug(message) { + if (this.options.listeners && this.options.listeners.debug) { + this.options.listeners.debug(message); + } + } + _getCommandString(options, noPrefix) { + const toolPath = this._getSpawnFileName(); + const args = this._getSpawnArgs(options); + let cmd = noPrefix ? '' : '[command]'; // omit prefix when piped to a second tool + if (IS_WINDOWS) { + // Windows + cmd file + if (this._isCmdFile()) { + cmd += toolPath; + for (const a of args) { + cmd += ` ${a}`; + } + } + // Windows + verbatim + else if (options.windowsVerbatimArguments) { + cmd += `"${toolPath}"`; + for (const a of args) { + cmd += ` ${a}`; + } + } + // Windows (regular) + else { + cmd += this._windowsQuoteCmdArg(toolPath); + for (const a of args) { + cmd += ` ${this._windowsQuoteCmdArg(a)}`; + } + } + } + else { + // OSX/Linux - this can likely be improved with some form of quoting. + // creating processes on Unix is fundamentally different than Windows. + // on Unix, execvp() takes an arg array. + cmd += toolPath; + for (const a of args) { + cmd += ` ${a}`; + } + } + return cmd; + } + _processLineBuffer(data, strBuffer, onLine) { + try { + let s = strBuffer + data.toString(); + let n = s.indexOf(os.EOL); + while (n > -1) { + const line = s.substring(0, n); + onLine(line); + // the rest of the string ... + s = s.substring(n + os.EOL.length); + n = s.indexOf(os.EOL); + } + strBuffer = s; + } + catch (err) { + // streaming lines to console is best effort. Don't fail a build. + this._debug(`error processing line. Failed with error ${err}`); + } + } + _getSpawnFileName() { + if (IS_WINDOWS) { + if (this._isCmdFile()) { + return process.env['COMSPEC'] || 'cmd.exe'; + } + } + return this.toolPath; + } + _getSpawnArgs(options) { + if (IS_WINDOWS) { + if (this._isCmdFile()) { + let argline = `/D /S /C "${this._windowsQuoteCmdArg(this.toolPath)}`; + for (const a of this.args) { + argline += ' '; + argline += options.windowsVerbatimArguments + ? a + : this._windowsQuoteCmdArg(a); + } + argline += '"'; + return [argline]; + } + } + return this.args; + } + _endsWith(str, end) { + return str.endsWith(end); + } + _isCmdFile() { + const upperToolPath = this.toolPath.toUpperCase(); + return (this._endsWith(upperToolPath, '.CMD') || + this._endsWith(upperToolPath, '.BAT')); + } + _windowsQuoteCmdArg(arg) { + // for .exe, apply the normal quoting rules that libuv applies + if (!this._isCmdFile()) { + return this._uvQuoteCmdArg(arg); + } + // otherwise apply quoting rules specific to the cmd.exe command line parser. + // the libuv rules are generic and are not designed specifically for cmd.exe + // command line parser. + // + // for a detailed description of the cmd.exe command line parser, refer to + // http://stackoverflow.com/questions/4094699/how-does-the-windows-command-interpreter-cmd-exe-parse-scripts/7970912#7970912 + // need quotes for empty arg + if (!arg) { + return '""'; + } + // determine whether the arg needs to be quoted + const cmdSpecialChars = [ + ' ', + '\t', + '&', + '(', + ')', + '[', + ']', + '{', + '}', + '^', + '=', + ';', + '!', + "'", + '+', + ',', + '`', + '~', + '|', + '<', + '>', + '"' + ]; + let needsQuotes = false; + for (const char of arg) { + if (cmdSpecialChars.some(x => x === char)) { + needsQuotes = true; + break; + } + } + // short-circuit if quotes not needed + if (!needsQuotes) { + return arg; + } + // the following quoting rules are very similar to the rules that by libuv applies. + // + // 1) wrap the string in quotes + // + // 2) double-up quotes - i.e. " => "" + // + // this is different from the libuv quoting rules. libuv replaces " with \", which unfortunately + // doesn't work well with a cmd.exe command line. + // + // note, replacing " with "" also works well if the arg is passed to a downstream .NET console app. + // for example, the command line: + // foo.exe "myarg:""my val""" + // is parsed by a .NET console app into an arg array: + // [ "myarg:\"my val\"" ] + // which is the same end result when applying libuv quoting rules. although the actual + // command line from libuv quoting rules would look like: + // foo.exe "myarg:\"my val\"" + // + // 3) double-up slashes that precede a quote, + // e.g. hello \world => "hello \world" + // hello\"world => "hello\\""world" + // hello\\"world => "hello\\\\""world" + // hello world\ => "hello world\\" + // + // technically this is not required for a cmd.exe command line, or the batch argument parser. + // the reasons for including this as a .cmd quoting rule are: + // + // a) this is optimized for the scenario where the argument is passed from the .cmd file to an + // external program. many programs (e.g. .NET console apps) rely on the slash-doubling rule. + // + // b) it's what we've been doing previously (by deferring to node default behavior) and we + // haven't heard any complaints about that aspect. + // + // note, a weakness of the quoting rules chosen here, is that % is not escaped. in fact, % cannot be + // escaped when used on the command line directly - even though within a .cmd file % can be escaped + // by using %%. + // + // the saving grace is, on the command line, %var% is left as-is if var is not defined. this contrasts + // the line parsing rules within a .cmd file, where if var is not defined it is replaced with nothing. + // + // one option that was explored was replacing % with ^% - i.e. %var% => ^%var^%. this hack would + // often work, since it is unlikely that var^ would exist, and the ^ character is removed when the + // variable is used. the problem, however, is that ^ is not removed when %* is used to pass the args + // to an external program. + // + // an unexplored potential solution for the % escaping problem, is to create a wrapper .cmd file. + // % can be escaped within a .cmd file. + let reverse = '"'; + let quoteHit = true; + for (let i = arg.length; i > 0; i--) { + // walk the string in reverse + reverse += arg[i - 1]; + if (quoteHit && arg[i - 1] === '\\') { + reverse += '\\'; // double the slash + } + else if (arg[i - 1] === '"') { + quoteHit = true; + reverse += '"'; // double the quote + } + else { + quoteHit = false; + } + } + reverse += '"'; + return reverse + .split('') + .reverse() + .join(''); + } + _uvQuoteCmdArg(arg) { + // Tool runner wraps child_process.spawn() and needs to apply the same quoting as + // Node in certain cases where the undocumented spawn option windowsVerbatimArguments + // is used. + // + // Since this function is a port of quote_cmd_arg from Node 4.x (technically, lib UV, + // see https://github.com/nodejs/node/blob/v4.x/deps/uv/src/win/process.c for details), + // pasting copyright notice from Node within this function: + // + // Copyright Joyent, Inc. and other Node contributors. All rights reserved. + // + // Permission is hereby granted, free of charge, to any person obtaining a copy + // of this software and associated documentation files (the "Software"), to + // deal in the Software without restriction, including without limitation the + // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + // sell copies of the Software, and to permit persons to whom the Software is + // furnished to do so, subject to the following conditions: + // + // The above copyright notice and this permission notice shall be included in + // all copies or substantial portions of the Software. + // + // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + // IN THE SOFTWARE. + if (!arg) { + // Need double quotation for empty argument + return '""'; + } + if (!arg.includes(' ') && !arg.includes('\t') && !arg.includes('"')) { + // No quotation needed + return arg; + } + if (!arg.includes('"') && !arg.includes('\\')) { + // No embedded double quotes or backslashes, so I can just wrap + // quote marks around the whole thing. + return `"${arg}"`; + } + // Expected input/output: + // input : hello"world + // output: "hello\"world" + // input : hello""world + // output: "hello\"\"world" + // input : hello\world + // output: hello\world + // input : hello\\world + // output: hello\\world + // input : hello\"world + // output: "hello\\\"world" + // input : hello\\"world + // output: "hello\\\\\"world" + // input : hello world\ + // output: "hello world\\" - note the comment in libuv actually reads "hello world\" + // but it appears the comment is wrong, it should be "hello world\\" + let reverse = '"'; + let quoteHit = true; + for (let i = arg.length; i > 0; i--) { + // walk the string in reverse + reverse += arg[i - 1]; + if (quoteHit && arg[i - 1] === '\\') { + reverse += '\\'; + } + else if (arg[i - 1] === '"') { + quoteHit = true; + reverse += '\\'; + } + else { + quoteHit = false; + } + } + reverse += '"'; + return reverse + .split('') + .reverse() + .join(''); + } + _cloneExecOptions(options) { + options = options || {}; + const result = { + cwd: options.cwd || process.cwd(), + env: options.env || process.env, + silent: options.silent || false, + windowsVerbatimArguments: options.windowsVerbatimArguments || false, + failOnStdErr: options.failOnStdErr || false, + ignoreReturnCode: options.ignoreReturnCode || false, + delay: options.delay || 10000 + }; + result.outStream = options.outStream || process.stdout; + result.errStream = options.errStream || process.stderr; + return result; + } + _getSpawnOptions(options, toolPath) { + options = options || {}; + const result = {}; + result.cwd = options.cwd; + result.env = options.env; + result['windowsVerbatimArguments'] = + options.windowsVerbatimArguments || this._isCmdFile(); + if (options.windowsVerbatimArguments) { + result.argv0 = `"${toolPath}"`; + } + return result; + } + /** + * Exec a tool. + * Output will be streamed to the live console. + * Returns promise with return code + * + * @param tool path to tool to exec + * @param options optional exec options. See ExecOptions + * @returns number + */ + exec() { + return __awaiter(this, void 0, void 0, function* () { + // root the tool path if it is unrooted and contains relative pathing + if (!ioUtil.isRooted(this.toolPath) && + (this.toolPath.includes('/') || + (IS_WINDOWS && this.toolPath.includes('\\')))) { + // prefer options.cwd if it is specified, however options.cwd may also need to be rooted + this.toolPath = path.resolve(process.cwd(), this.options.cwd || process.cwd(), this.toolPath); + } + // if the tool is only a file name, then resolve it from the PATH + // otherwise verify it exists (add extension on Windows if necessary) + this.toolPath = yield io.which(this.toolPath, true); + return new Promise((resolve, reject) => { + this._debug(`exec tool: ${this.toolPath}`); + this._debug('arguments:'); + for (const arg of this.args) { + this._debug(` ${arg}`); + } + const optionsNonNull = this._cloneExecOptions(this.options); + if (!optionsNonNull.silent && optionsNonNull.outStream) { + optionsNonNull.outStream.write(this._getCommandString(optionsNonNull) + os.EOL); + } + const state = new ExecState(optionsNonNull, this.toolPath); + state.on('debug', (message) => { + this._debug(message); + }); + const fileName = this._getSpawnFileName(); + const cp = child.spawn(fileName, this._getSpawnArgs(optionsNonNull), this._getSpawnOptions(this.options, fileName)); + const stdbuffer = ''; + if (cp.stdout) { + cp.stdout.on('data', (data) => { + if (this.options.listeners && this.options.listeners.stdout) { + this.options.listeners.stdout(data); + } + if (!optionsNonNull.silent && optionsNonNull.outStream) { + optionsNonNull.outStream.write(data); + } + this._processLineBuffer(data, stdbuffer, (line) => { + if (this.options.listeners && this.options.listeners.stdline) { + this.options.listeners.stdline(line); + } + }); + }); + } + const errbuffer = ''; + if (cp.stderr) { + cp.stderr.on('data', (data) => { + state.processStderr = true; + if (this.options.listeners && this.options.listeners.stderr) { + this.options.listeners.stderr(data); + } + if (!optionsNonNull.silent && + optionsNonNull.errStream && + optionsNonNull.outStream) { + const s = optionsNonNull.failOnStdErr + ? optionsNonNull.errStream + : optionsNonNull.outStream; + s.write(data); + } + this._processLineBuffer(data, errbuffer, (line) => { + if (this.options.listeners && this.options.listeners.errline) { + this.options.listeners.errline(line); + } + }); + }); + } + cp.on('error', (err) => { + state.processError = err.message; + state.processExited = true; + state.processClosed = true; + state.CheckComplete(); + }); + cp.on('exit', (code) => { + state.processExitCode = code; + state.processExited = true; + this._debug(`Exit code ${code} received from tool '${this.toolPath}'`); + state.CheckComplete(); + }); + cp.on('close', (code) => { + state.processExitCode = code; + state.processExited = true; + state.processClosed = true; + this._debug(`STDIO streams have closed for tool '${this.toolPath}'`); + state.CheckComplete(); + }); + state.on('done', (error, exitCode) => { + if (stdbuffer.length > 0) { + this.emit('stdline', stdbuffer); + } + if (errbuffer.length > 0) { + this.emit('errline', errbuffer); + } + cp.removeAllListeners(); + if (error) { + reject(error); + } + else { + resolve(exitCode); + } + }); + }); + }); + } +} +exports.ToolRunner = ToolRunner; +/** + * Convert an arg string to an array of args. Handles escaping + * + * @param argString string of arguments + * @returns string[] array of arguments + */ +function argStringToArray(argString) { + const args = []; + let inQuotes = false; + let escaped = false; + let arg = ''; + function append(c) { + // we only escape double quotes. + if (escaped && c !== '"') { + arg += '\\'; + } + arg += c; + escaped = false; + } + for (let i = 0; i < argString.length; i++) { + const c = argString.charAt(i); + if (c === '"') { + if (!escaped) { + inQuotes = !inQuotes; + } + else { + append(c); + } + continue; + } + if (c === '\\' && escaped) { + append(c); + continue; + } + if (c === '\\' && inQuotes) { + escaped = true; + continue; + } + if (c === ' ' && !inQuotes) { + if (arg.length > 0) { + args.push(arg); + arg = ''; + } + continue; + } + append(c); + } + if (arg.length > 0) { + args.push(arg.trim()); + } + return args; +} +exports.argStringToArray = argStringToArray; +class ExecState extends events.EventEmitter { + constructor(options, toolPath) { + super(); + this.processClosed = false; // tracks whether the process has exited and stdio is closed + this.processError = ''; + this.processExitCode = 0; + this.processExited = false; // tracks whether the process has exited + this.processStderr = false; // tracks whether stderr was written to + this.delay = 10000; // 10 seconds + this.done = false; + this.timeout = null; + if (!toolPath) { + throw new Error('toolPath must not be empty'); + } + this.options = options; + this.toolPath = toolPath; + if (options.delay) { + this.delay = options.delay; + } + } + CheckComplete() { + if (this.done) { + return; + } + if (this.processClosed) { + this._setResult(); + } + else if (this.processExited) { + this.timeout = setTimeout(ExecState.HandleTimeout, this.delay, this); + } + } + _debug(message) { + this.emit('debug', message); + } + _setResult() { + // determine whether there is an error + let error; + if (this.processExited) { + if (this.processError) { + error = new Error(`There was an error when attempting to execute the process '${this.toolPath}'. This may indicate the process failed to start. Error: ${this.processError}`); + } + else if (this.processExitCode !== 0 && !this.options.ignoreReturnCode) { + error = new Error(`The process '${this.toolPath}' failed with exit code ${this.processExitCode}`); + } + else if (this.processStderr && this.options.failOnStdErr) { + error = new Error(`The process '${this.toolPath}' failed because one or more lines were written to the STDERR stream`); + } + } + // clear the timeout + if (this.timeout) { + clearTimeout(this.timeout); + this.timeout = null; + } + this.done = true; + this.emit('done', error, this.processExitCode); + } + static HandleTimeout(state) { + if (state.done) { + return; + } + if (!state.processClosed && state.processExited) { + const message = `The STDIO streams did not close within ${state.delay / + 1000} seconds of the exit event from process '${state.toolPath}'. This may indicate a child process inherited the STDIO streams and has not yet exited.`; + state._debug(message); + } + state._setResult(); + } +} +//# sourceMappingURL=toolrunner.js.map + +/***/ }), + +/***/ 87: +/***/ (function(module) { + +module.exports = require("os"); + +/***/ }), + +/***/ 129: +/***/ (function(module) { + +module.exports = require("child_process"); + +/***/ }), + +/***/ 219: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result["default"] = mod; + return result; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const core = __importStar(__webpack_require__(470)); +const gpg = __importStar(__webpack_require__(884)); +function run() { + return __awaiter(this, void 0, void 0, function* () { + if (core.getInput('gpg-private-key', { required: false })) { + console.log('removing private key from keychain'); + try { + const keyFingerprint = core.getState('gpg-private-key-fingerprint'); + yield gpg.deleteKey(keyFingerprint); + } + catch (error) { + core.setFailed(error.message); + } + } + }); +} +run(); + + +/***/ }), + +/***/ 322: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result["default"] = mod; + return result; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const path = __importStar(__webpack_require__(622)); +function getTempDir() { + let tempDirectory = process.env.RUNNER_TEMP; + if (tempDirectory === undefined) { + let baseLocation; + if (isWindows()) { + // On windows use the USERPROFILE env variable + baseLocation = process.env['USERPROFILE'] + ? process.env['USERPROFILE'] + : 'C:\\'; + } + else { + if (process.platform === 'darwin') { + baseLocation = '/Users'; + } + else { + baseLocation = '/home'; + } + } + tempDirectory = path.join(baseLocation, 'actions', 'temp'); + } + return tempDirectory; +} +exports.getTempDir = getTempDir; +function isWindows() { + return process.platform === 'win32'; +} +exports.isWindows = isWindows; + + +/***/ }), + +/***/ 357: +/***/ (function(module) { + +module.exports = require("assert"); + +/***/ }), + +/***/ 431: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result["default"] = mod; + return result; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const os = __importStar(__webpack_require__(87)); +/** + * Commands + * + * Command Format: + * ::name key=value,key=value::message + * + * Examples: + * ::warning::This is the message + * ::set-env name=MY_VAR::some value + */ +function issueCommand(command, properties, message) { + const cmd = new Command(command, properties, message); + process.stdout.write(cmd.toString() + os.EOL); +} +exports.issueCommand = issueCommand; +function issue(name, message = '') { + issueCommand(name, {}, message); +} +exports.issue = issue; +const CMD_STRING = '::'; +class Command { + constructor(command, properties, message) { + if (!command) { + command = 'missing.command'; + } + this.command = command; + this.properties = properties; + this.message = message; + } + toString() { + let cmdStr = CMD_STRING + this.command; + if (this.properties && Object.keys(this.properties).length > 0) { + cmdStr += ' '; + let first = true; + for (const key in this.properties) { + if (this.properties.hasOwnProperty(key)) { + const val = this.properties[key]; + if (val) { + if (first) { + first = false; + } + else { + cmdStr += ','; + } + cmdStr += `${key}=${escapeProperty(val)}`; + } + } + } + } + cmdStr += `${CMD_STRING}${escapeData(this.message)}`; + return cmdStr; + } +} +function escapeData(s) { + return (s || '') + .replace(/%/g, '%25') + .replace(/\r/g, '%0D') + .replace(/\n/g, '%0A'); +} +function escapeProperty(s) { + return (s || '') + .replace(/%/g, '%25') + .replace(/\r/g, '%0D') + .replace(/\n/g, '%0A') + .replace(/:/g, '%3A') + .replace(/,/g, '%2C'); +} +//# sourceMappingURL=command.js.map + +/***/ }), + +/***/ 470: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result["default"] = mod; + return result; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const command_1 = __webpack_require__(431); +const os = __importStar(__webpack_require__(87)); +const path = __importStar(__webpack_require__(622)); +/** + * The code to exit an action + */ +var ExitCode; +(function (ExitCode) { + /** + * A code indicating that the action was successful + */ + ExitCode[ExitCode["Success"] = 0] = "Success"; + /** + * A code indicating that the action was a failure + */ + ExitCode[ExitCode["Failure"] = 1] = "Failure"; +})(ExitCode = exports.ExitCode || (exports.ExitCode = {})); +//----------------------------------------------------------------------- +// Variables +//----------------------------------------------------------------------- +/** + * Sets env variable for this action and future actions in the job + * @param name the name of the variable to set + * @param val the value of the variable + */ +function exportVariable(name, val) { + process.env[name] = val; + command_1.issueCommand('set-env', { name }, val); +} +exports.exportVariable = exportVariable; +/** + * Registers a secret which will get masked from logs + * @param secret value of the secret + */ +function setSecret(secret) { + command_1.issueCommand('add-mask', {}, secret); +} +exports.setSecret = setSecret; +/** + * Prepends inputPath to the PATH (for this action and future actions) + * @param inputPath + */ +function addPath(inputPath) { + command_1.issueCommand('add-path', {}, inputPath); + process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`; +} +exports.addPath = addPath; +/** + * Gets the value of an input. The value is also trimmed. + * + * @param name name of the input to get + * @param options optional. See InputOptions. + * @returns string + */ +function getInput(name, options) { + const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || ''; + if (options && options.required && !val) { + throw new Error(`Input required and not supplied: ${name}`); + } + return val.trim(); +} +exports.getInput = getInput; +/** + * Sets the value of an output. + * + * @param name name of the output to set + * @param value value to store + */ +function setOutput(name, value) { + command_1.issueCommand('set-output', { name }, value); +} +exports.setOutput = setOutput; +//----------------------------------------------------------------------- +// Results +//----------------------------------------------------------------------- +/** + * Sets the action status to failed. + * When the action exits it will be with an exit code of 1 + * @param message add error issue message + */ +function setFailed(message) { + process.exitCode = ExitCode.Failure; + error(message); +} +exports.setFailed = setFailed; +//----------------------------------------------------------------------- +// Logging Commands +//----------------------------------------------------------------------- +/** + * Writes debug message to user log + * @param message debug message + */ +function debug(message) { + command_1.issueCommand('debug', {}, message); +} +exports.debug = debug; +/** + * Adds an error issue + * @param message error issue message + */ +function error(message) { + command_1.issue('error', message); +} +exports.error = error; +/** + * Adds an warning issue + * @param message warning issue message + */ +function warning(message) { + command_1.issue('warning', message); +} +exports.warning = warning; +/** + * Writes info to log with console.log. + * @param message info message + */ +function info(message) { + process.stdout.write(message + os.EOL); +} +exports.info = info; +/** + * Begin an output group. + * + * Output until the next `groupEnd` will be foldable in this group + * + * @param name The name of the output group + */ +function startGroup(name) { + command_1.issue('group', name); +} +exports.startGroup = startGroup; +/** + * End an output group. + */ +function endGroup() { + command_1.issue('endgroup'); +} +exports.endGroup = endGroup; +/** + * Wrap an asynchronous function call in a group. + * + * Returns the same type as the function itself. + * + * @param name The name of the group + * @param fn The function to wrap in the group + */ +function group(name, fn) { + return __awaiter(this, void 0, void 0, function* () { + startGroup(name); + let result; + try { + result = yield fn(); + } + finally { + endGroup(); + } + return result; + }); +} +exports.group = group; +//----------------------------------------------------------------------- +// Wrapper action state +//----------------------------------------------------------------------- +/** + * Saves state for current action, the state can only be retrieved by this action's post job execution. + * + * @param name name of the state to store + * @param value value to store + */ +function saveState(name, value) { + command_1.issueCommand('save-state', { name }, value); +} +exports.saveState = saveState; +/** + * Gets the value of an state set by this action's main execution. + * + * @param name name of the state to get + * @returns string + */ +function getState(name) { + return process.env[`STATE_${name}`] || ''; +} +exports.getState = getState; +//# sourceMappingURL=core.js.map + +/***/ }), + +/***/ 614: +/***/ (function(module) { + +module.exports = require("events"); + +/***/ }), + +/***/ 622: +/***/ (function(module) { + +module.exports = require("path"); + +/***/ }), + +/***/ 669: +/***/ (function(module) { + +module.exports = require("util"); + +/***/ }), + +/***/ 672: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var _a; +Object.defineProperty(exports, "__esModule", { value: true }); +const assert_1 = __webpack_require__(357); +const fs = __webpack_require__(747); +const path = __webpack_require__(622); +_a = fs.promises, exports.chmod = _a.chmod, exports.copyFile = _a.copyFile, exports.lstat = _a.lstat, exports.mkdir = _a.mkdir, exports.readdir = _a.readdir, exports.readlink = _a.readlink, exports.rename = _a.rename, exports.rmdir = _a.rmdir, exports.stat = _a.stat, exports.symlink = _a.symlink, exports.unlink = _a.unlink; +exports.IS_WINDOWS = process.platform === 'win32'; +function exists(fsPath) { + return __awaiter(this, void 0, void 0, function* () { + try { + yield exports.stat(fsPath); + } + catch (err) { + if (err.code === 'ENOENT') { + return false; + } + throw err; + } + return true; + }); +} +exports.exists = exists; +function isDirectory(fsPath, useStat = false) { + return __awaiter(this, void 0, void 0, function* () { + const stats = useStat ? yield exports.stat(fsPath) : yield exports.lstat(fsPath); + return stats.isDirectory(); + }); +} +exports.isDirectory = isDirectory; +/** + * On OSX/Linux, true if path starts with '/'. On Windows, true for paths like: + * \, \hello, \\hello\share, C:, and C:\hello (and corresponding alternate separator cases). + */ +function isRooted(p) { + p = normalizeSeparators(p); + if (!p) { + throw new Error('isRooted() parameter "p" cannot be empty'); + } + if (exports.IS_WINDOWS) { + return (p.startsWith('\\') || /^[A-Z]:/i.test(p) // e.g. \ or \hello or \\hello + ); // e.g. C: or C:\hello + } + return p.startsWith('/'); +} +exports.isRooted = isRooted; +/** + * Recursively create a directory at `fsPath`. + * + * This implementation is optimistic, meaning it attempts to create the full + * path first, and backs up the path stack from there. + * + * @param fsPath The path to create + * @param maxDepth The maximum recursion depth + * @param depth The current recursion depth + */ +function mkdirP(fsPath, maxDepth = 1000, depth = 1) { + return __awaiter(this, void 0, void 0, function* () { + assert_1.ok(fsPath, 'a path argument must be provided'); + fsPath = path.resolve(fsPath); + if (depth >= maxDepth) + return exports.mkdir(fsPath); + try { + yield exports.mkdir(fsPath); + return; + } + catch (err) { + switch (err.code) { + case 'ENOENT': { + yield mkdirP(path.dirname(fsPath), maxDepth, depth + 1); + yield exports.mkdir(fsPath); + return; + } + default: { + let stats; + try { + stats = yield exports.stat(fsPath); + } + catch (err2) { + throw err; + } + if (!stats.isDirectory()) + throw err; + } + } + } + }); +} +exports.mkdirP = mkdirP; +/** + * Best effort attempt to determine whether a file exists and is executable. + * @param filePath file path to check + * @param extensions additional file extensions to try + * @return if file exists and is executable, returns the file path. otherwise empty string. + */ +function tryGetExecutablePath(filePath, extensions) { + return __awaiter(this, void 0, void 0, function* () { + let stats = undefined; + try { + // test file exists + stats = yield exports.stat(filePath); + } + catch (err) { + if (err.code !== 'ENOENT') { + // eslint-disable-next-line no-console + console.log(`Unexpected error attempting to determine if executable file exists '${filePath}': ${err}`); + } + } + if (stats && stats.isFile()) { + if (exports.IS_WINDOWS) { + // on Windows, test for valid extension + const upperExt = path.extname(filePath).toUpperCase(); + if (extensions.some(validExt => validExt.toUpperCase() === upperExt)) { + return filePath; + } + } + else { + if (isUnixExecutable(stats)) { + return filePath; + } + } + } + // try each extension + const originalFilePath = filePath; + for (const extension of extensions) { + filePath = originalFilePath + extension; + stats = undefined; + try { + stats = yield exports.stat(filePath); + } + catch (err) { + if (err.code !== 'ENOENT') { + // eslint-disable-next-line no-console + console.log(`Unexpected error attempting to determine if executable file exists '${filePath}': ${err}`); + } + } + if (stats && stats.isFile()) { + if (exports.IS_WINDOWS) { + // preserve the case of the actual file (since an extension was appended) + try { + const directory = path.dirname(filePath); + const upperName = path.basename(filePath).toUpperCase(); + for (const actualName of yield exports.readdir(directory)) { + if (upperName === actualName.toUpperCase()) { + filePath = path.join(directory, actualName); + break; + } + } + } + catch (err) { + // eslint-disable-next-line no-console + console.log(`Unexpected error attempting to determine the actual case of the file '${filePath}': ${err}`); + } + return filePath; + } + else { + if (isUnixExecutable(stats)) { + return filePath; + } + } + } + } + return ''; + }); +} +exports.tryGetExecutablePath = tryGetExecutablePath; +function normalizeSeparators(p) { + p = p || ''; + if (exports.IS_WINDOWS) { + // convert slashes on Windows + p = p.replace(/\//g, '\\'); + // remove redundant slashes + return p.replace(/\\\\+/g, '\\'); + } + // remove redundant slashes + return p.replace(/\/\/+/g, '/'); +} +// on Mac/Linux, test the execute bit +// R W X R W X R W X +// 256 128 64 32 16 8 4 2 1 +function isUnixExecutable(stats) { + return ((stats.mode & 1) > 0 || + ((stats.mode & 8) > 0 && stats.gid === process.getgid()) || + ((stats.mode & 64) > 0 && stats.uid === process.getuid())); +} +//# sourceMappingURL=io-util.js.map + +/***/ }), + +/***/ 747: +/***/ (function(module) { + +module.exports = require("fs"); + +/***/ }), + +/***/ 884: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result["default"] = mod; + return result; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const fs = __importStar(__webpack_require__(747)); +const path = __importStar(__webpack_require__(622)); +const io = __importStar(__webpack_require__(1)); +const exec = __importStar(__webpack_require__(986)); +const util = __importStar(__webpack_require__(322)); +exports.PRIVATE_KEY_FILE = path.join(util.getTempDir(), 'private-key.asc'); +const PRIVATE_KEY_FINGERPRINT_REGEX = /\w{40}/; +function importKey(privateKey) { + return __awaiter(this, void 0, void 0, function* () { + fs.writeFileSync(exports.PRIVATE_KEY_FILE, privateKey, { + encoding: 'utf-8', + flag: 'w' + }); + let output = ''; + const options = { + silent: true, + listeners: { + stdout: (data) => { + output += data.toString(); + } + } + }; + yield exec.exec('gpg', [ + '--batch', + '--import-options', + 'import-show', + '--import', + exports.PRIVATE_KEY_FILE + ], options); + yield io.rmRF(exports.PRIVATE_KEY_FILE); + const match = output.match(PRIVATE_KEY_FINGERPRINT_REGEX); + return match && match[0]; + }); +} +exports.importKey = importKey; +function deleteKey(keyFingerprint) { + return __awaiter(this, void 0, void 0, function* () { + yield exec.exec('gpg', ['--batch', '--yes', '--delete-secret-keys', keyFingerprint], { silent: true }); + yield exec.exec('gpg', ['--batch', '--yes', '--delete-keys', keyFingerprint], { silent: true }); + }); +} +exports.deleteKey = deleteKey; + + +/***/ }), + +/***/ 986: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const tr = __webpack_require__(9); +/** + * Exec a command. + * Output will be streamed to the live console. + * Returns promise with return code + * + * @param commandLine command to execute (can include additional args). Must be correctly escaped. + * @param args optional arguments for tool. Escaping is handled by the lib. + * @param options optional exec options. See ExecOptions + * @returns Promise exit code + */ +function exec(commandLine, args, options) { + return __awaiter(this, void 0, void 0, function* () { + const commandArgs = tr.argStringToArray(commandLine); + if (commandArgs.length === 0) { + throw new Error(`Parameter 'commandLine' cannot be null or empty.`); + } + // Path to tool to execute should be first arg + const toolPath = commandArgs[0]; + args = commandArgs.slice(1).concat(args || []); + const runner = new tr.ToolRunner(toolPath, args, options); + return runner.exec(); + }); +} +exports.exec = exec; +//# sourceMappingURL=exec.js.map + +/***/ }) + +/******/ }); \ No newline at end of file diff --git a/dist/index.js b/dist/index.js deleted file mode 100644 index 9663265..0000000 Binary files a/dist/index.js and /dev/null differ diff --git a/dist/setup/index.js b/dist/setup/index.js new file mode 100644 index 0000000..cdddbdb --- /dev/null +++ b/dist/setup/index.js @@ -0,0 +1,35284 @@ +module.exports = +/******/ (function(modules, runtime) { // webpackBootstrap +/******/ "use strict"; +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ __webpack_require__.ab = __dirname + "/"; +/******/ +/******/ // the startup function +/******/ function startup() { +/******/ // Load entry module and return exports +/******/ return __webpack_require__(811); +/******/ }; +/******/ +/******/ // run startup +/******/ return startup(); +/******/ }) +/************************************************************************/ +/******/ ({ + +/***/ 1: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const childProcess = __webpack_require__(129); +const path = __webpack_require__(622); +const util_1 = __webpack_require__(669); +const ioUtil = __webpack_require__(672); +const exec = util_1.promisify(childProcess.exec); +/** + * Copies a file or folder. + * Based off of shelljs - https://github.com/shelljs/shelljs/blob/9237f66c52e5daa40458f94f9565e18e8132f5a6/src/cp.js + * + * @param source source path + * @param dest destination path + * @param options optional. See CopyOptions. + */ +function cp(source, dest, options = {}) { + return __awaiter(this, void 0, void 0, function* () { + const { force, recursive } = readCopyOptions(options); + const destStat = (yield ioUtil.exists(dest)) ? yield ioUtil.stat(dest) : null; + // Dest is an existing file, but not forcing + if (destStat && destStat.isFile() && !force) { + return; + } + // If dest is an existing directory, should copy inside. + const newDest = destStat && destStat.isDirectory() + ? path.join(dest, path.basename(source)) + : dest; + if (!(yield ioUtil.exists(source))) { + throw new Error(`no such file or directory: ${source}`); + } + const sourceStat = yield ioUtil.stat(source); + if (sourceStat.isDirectory()) { + if (!recursive) { + throw new Error(`Failed to copy. ${source} is a directory, but tried to copy without recursive flag.`); + } + else { + yield cpDirRecursive(source, newDest, 0, force); + } + } + else { + if (path.relative(source, newDest) === '') { + // a file cannot be copied to itself + throw new Error(`'${newDest}' and '${source}' are the same file`); + } + yield copyFile(source, newDest, force); + } + }); +} +exports.cp = cp; +/** + * Moves a path. + * + * @param source source path + * @param dest destination path + * @param options optional. See MoveOptions. + */ +function mv(source, dest, options = {}) { + return __awaiter(this, void 0, void 0, function* () { + if (yield ioUtil.exists(dest)) { + let destExists = true; + if (yield ioUtil.isDirectory(dest)) { + // If dest is directory copy src into dest + dest = path.join(dest, path.basename(source)); + destExists = yield ioUtil.exists(dest); + } + if (destExists) { + if (options.force == null || options.force) { + yield rmRF(dest); + } + else { + throw new Error('Destination already exists'); + } + } + } + yield mkdirP(path.dirname(dest)); + yield ioUtil.rename(source, dest); + }); +} +exports.mv = mv; +/** + * Remove a path recursively with force + * + * @param inputPath path to remove + */ +function rmRF(inputPath) { + return __awaiter(this, void 0, void 0, function* () { + if (ioUtil.IS_WINDOWS) { + // Node doesn't provide a delete operation, only an unlink function. This means that if the file is being used by another + // program (e.g. antivirus), it won't be deleted. To address this, we shell out the work to rd/del. + try { + if (yield ioUtil.isDirectory(inputPath, true)) { + yield exec(`rd /s /q "${inputPath}"`); + } + else { + yield exec(`del /f /a "${inputPath}"`); + } + } + catch (err) { + // if you try to delete a file that doesn't exist, desired result is achieved + // other errors are valid + if (err.code !== 'ENOENT') + throw err; + } + // Shelling out fails to remove a symlink folder with missing source, this unlink catches that + try { + yield ioUtil.unlink(inputPath); + } + catch (err) { + // if you try to delete a file that doesn't exist, desired result is achieved + // other errors are valid + if (err.code !== 'ENOENT') + throw err; + } + } + else { + let isDir = false; + try { + isDir = yield ioUtil.isDirectory(inputPath); + } + catch (err) { + // if you try to delete a file that doesn't exist, desired result is achieved + // other errors are valid + if (err.code !== 'ENOENT') + throw err; + return; + } + if (isDir) { + yield exec(`rm -rf "${inputPath}"`); + } + else { + yield ioUtil.unlink(inputPath); + } + } + }); +} +exports.rmRF = rmRF; +/** + * Make a directory. Creates the full path with folders in between + * Will throw if it fails + * + * @param fsPath path to create + * @returns Promise + */ +function mkdirP(fsPath) { + return __awaiter(this, void 0, void 0, function* () { + yield ioUtil.mkdirP(fsPath); + }); +} +exports.mkdirP = mkdirP; +/** + * Returns path of a tool had the tool actually been invoked. Resolves via paths. + * If you check and the tool does not exist, it will throw. + * + * @param tool name of the tool + * @param check whether to check if tool exists + * @returns Promise path to tool + */ +function which(tool, check) { + return __awaiter(this, void 0, void 0, function* () { + if (!tool) { + throw new Error("parameter 'tool' is required"); + } + // recursive when check=true + if (check) { + const result = yield which(tool, false); + if (!result) { + if (ioUtil.IS_WINDOWS) { + throw new Error(`Unable to locate executable file: ${tool}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also verify the file has a valid extension for an executable file.`); + } + else { + throw new Error(`Unable to locate executable file: ${tool}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also check the file mode to verify the file is executable.`); + } + } + } + try { + // build the list of extensions to try + const extensions = []; + if (ioUtil.IS_WINDOWS && process.env.PATHEXT) { + for (const extension of process.env.PATHEXT.split(path.delimiter)) { + if (extension) { + extensions.push(extension); + } + } + } + // if it's rooted, return it if exists. otherwise return empty. + if (ioUtil.isRooted(tool)) { + const filePath = yield ioUtil.tryGetExecutablePath(tool, extensions); + if (filePath) { + return filePath; + } + return ''; + } + // if any path separators, return empty + if (tool.includes('/') || (ioUtil.IS_WINDOWS && tool.includes('\\'))) { + return ''; + } + // build the list of directories + // + // Note, technically "where" checks the current directory on Windows. From a toolkit perspective, + // it feels like we should not do this. Checking the current directory seems like more of a use + // case of a shell, and the which() function exposed by the toolkit should strive for consistency + // across platforms. + const directories = []; + if (process.env.PATH) { + for (const p of process.env.PATH.split(path.delimiter)) { + if (p) { + directories.push(p); + } + } + } + // return the first match + for (const directory of directories) { + const filePath = yield ioUtil.tryGetExecutablePath(directory + path.sep + tool, extensions); + if (filePath) { + return filePath; + } + } + return ''; + } + catch (err) { + throw new Error(`which failed with message ${err.message}`); + } + }); +} +exports.which = which; +function readCopyOptions(options) { + const force = options.force == null ? true : options.force; + const recursive = Boolean(options.recursive); + return { force, recursive }; +} +function cpDirRecursive(sourceDir, destDir, currentDepth, force) { + return __awaiter(this, void 0, void 0, function* () { + // Ensure there is not a run away recursive copy + if (currentDepth >= 255) + return; + currentDepth++; + yield mkdirP(destDir); + const files = yield ioUtil.readdir(sourceDir); + for (const fileName of files) { + const srcFile = `${sourceDir}/${fileName}`; + const destFile = `${destDir}/${fileName}`; + const srcFileStat = yield ioUtil.lstat(srcFile); + if (srcFileStat.isDirectory()) { + // Recurse + yield cpDirRecursive(srcFile, destFile, currentDepth, force); + } + else { + yield copyFile(srcFile, destFile, force); + } + } + // Change the mode for the newly created directory + yield ioUtil.chmod(destDir, (yield ioUtil.stat(sourceDir)).mode); + }); +} +// Buffered file copy +function copyFile(srcFile, destFile, force) { + return __awaiter(this, void 0, void 0, function* () { + if ((yield ioUtil.lstat(srcFile)).isSymbolicLink()) { + // unlink/re-link it + try { + yield ioUtil.lstat(destFile); + yield ioUtil.unlink(destFile); + } + catch (e) { + // Try to override file permission + if (e.code === 'EPERM') { + yield ioUtil.chmod(destFile, '0666'); + yield ioUtil.unlink(destFile); + } + // other errors = it doesn't exist, no work to do + } + // Copy over symlink + const symlinkFull = yield ioUtil.readlink(srcFile); + yield ioUtil.symlink(symlinkFull, destFile, ioUtil.IS_WINDOWS ? 'junction' : null); + } + else if (!(yield ioUtil.exists(destFile)) || force) { + yield ioUtil.copyFile(srcFile, destFile); + } + }); +} +//# sourceMappingURL=io.js.map + +/***/ }), + +/***/ 9: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const os = __webpack_require__(87); +const events = __webpack_require__(614); +const child = __webpack_require__(129); +const path = __webpack_require__(622); +const io = __webpack_require__(1); +const ioUtil = __webpack_require__(672); +/* eslint-disable @typescript-eslint/unbound-method */ +const IS_WINDOWS = process.platform === 'win32'; +/* + * Class for running command line tools. Handles quoting and arg parsing in a platform agnostic way. + */ +class ToolRunner extends events.EventEmitter { + constructor(toolPath, args, options) { + super(); + if (!toolPath) { + throw new Error("Parameter 'toolPath' cannot be null or empty."); + } + this.toolPath = toolPath; + this.args = args || []; + this.options = options || {}; + } + _debug(message) { + if (this.options.listeners && this.options.listeners.debug) { + this.options.listeners.debug(message); + } + } + _getCommandString(options, noPrefix) { + const toolPath = this._getSpawnFileName(); + const args = this._getSpawnArgs(options); + let cmd = noPrefix ? '' : '[command]'; // omit prefix when piped to a second tool + if (IS_WINDOWS) { + // Windows + cmd file + if (this._isCmdFile()) { + cmd += toolPath; + for (const a of args) { + cmd += ` ${a}`; + } + } + // Windows + verbatim + else if (options.windowsVerbatimArguments) { + cmd += `"${toolPath}"`; + for (const a of args) { + cmd += ` ${a}`; + } + } + // Windows (regular) + else { + cmd += this._windowsQuoteCmdArg(toolPath); + for (const a of args) { + cmd += ` ${this._windowsQuoteCmdArg(a)}`; + } + } + } + else { + // OSX/Linux - this can likely be improved with some form of quoting. + // creating processes on Unix is fundamentally different than Windows. + // on Unix, execvp() takes an arg array. + cmd += toolPath; + for (const a of args) { + cmd += ` ${a}`; + } + } + return cmd; + } + _processLineBuffer(data, strBuffer, onLine) { + try { + let s = strBuffer + data.toString(); + let n = s.indexOf(os.EOL); + while (n > -1) { + const line = s.substring(0, n); + onLine(line); + // the rest of the string ... + s = s.substring(n + os.EOL.length); + n = s.indexOf(os.EOL); + } + strBuffer = s; + } + catch (err) { + // streaming lines to console is best effort. Don't fail a build. + this._debug(`error processing line. Failed with error ${err}`); + } + } + _getSpawnFileName() { + if (IS_WINDOWS) { + if (this._isCmdFile()) { + return process.env['COMSPEC'] || 'cmd.exe'; + } + } + return this.toolPath; + } + _getSpawnArgs(options) { + if (IS_WINDOWS) { + if (this._isCmdFile()) { + let argline = `/D /S /C "${this._windowsQuoteCmdArg(this.toolPath)}`; + for (const a of this.args) { + argline += ' '; + argline += options.windowsVerbatimArguments + ? a + : this._windowsQuoteCmdArg(a); + } + argline += '"'; + return [argline]; + } + } + return this.args; + } + _endsWith(str, end) { + return str.endsWith(end); + } + _isCmdFile() { + const upperToolPath = this.toolPath.toUpperCase(); + return (this._endsWith(upperToolPath, '.CMD') || + this._endsWith(upperToolPath, '.BAT')); + } + _windowsQuoteCmdArg(arg) { + // for .exe, apply the normal quoting rules that libuv applies + if (!this._isCmdFile()) { + return this._uvQuoteCmdArg(arg); + } + // otherwise apply quoting rules specific to the cmd.exe command line parser. + // the libuv rules are generic and are not designed specifically for cmd.exe + // command line parser. + // + // for a detailed description of the cmd.exe command line parser, refer to + // http://stackoverflow.com/questions/4094699/how-does-the-windows-command-interpreter-cmd-exe-parse-scripts/7970912#7970912 + // need quotes for empty arg + if (!arg) { + return '""'; + } + // determine whether the arg needs to be quoted + const cmdSpecialChars = [ + ' ', + '\t', + '&', + '(', + ')', + '[', + ']', + '{', + '}', + '^', + '=', + ';', + '!', + "'", + '+', + ',', + '`', + '~', + '|', + '<', + '>', + '"' + ]; + let needsQuotes = false; + for (const char of arg) { + if (cmdSpecialChars.some(x => x === char)) { + needsQuotes = true; + break; + } + } + // short-circuit if quotes not needed + if (!needsQuotes) { + return arg; + } + // the following quoting rules are very similar to the rules that by libuv applies. + // + // 1) wrap the string in quotes + // + // 2) double-up quotes - i.e. " => "" + // + // this is different from the libuv quoting rules. libuv replaces " with \", which unfortunately + // doesn't work well with a cmd.exe command line. + // + // note, replacing " with "" also works well if the arg is passed to a downstream .NET console app. + // for example, the command line: + // foo.exe "myarg:""my val""" + // is parsed by a .NET console app into an arg array: + // [ "myarg:\"my val\"" ] + // which is the same end result when applying libuv quoting rules. although the actual + // command line from libuv quoting rules would look like: + // foo.exe "myarg:\"my val\"" + // + // 3) double-up slashes that precede a quote, + // e.g. hello \world => "hello \world" + // hello\"world => "hello\\""world" + // hello\\"world => "hello\\\\""world" + // hello world\ => "hello world\\" + // + // technically this is not required for a cmd.exe command line, or the batch argument parser. + // the reasons for including this as a .cmd quoting rule are: + // + // a) this is optimized for the scenario where the argument is passed from the .cmd file to an + // external program. many programs (e.g. .NET console apps) rely on the slash-doubling rule. + // + // b) it's what we've been doing previously (by deferring to node default behavior) and we + // haven't heard any complaints about that aspect. + // + // note, a weakness of the quoting rules chosen here, is that % is not escaped. in fact, % cannot be + // escaped when used on the command line directly - even though within a .cmd file % can be escaped + // by using %%. + // + // the saving grace is, on the command line, %var% is left as-is if var is not defined. this contrasts + // the line parsing rules within a .cmd file, where if var is not defined it is replaced with nothing. + // + // one option that was explored was replacing % with ^% - i.e. %var% => ^%var^%. this hack would + // often work, since it is unlikely that var^ would exist, and the ^ character is removed when the + // variable is used. the problem, however, is that ^ is not removed when %* is used to pass the args + // to an external program. + // + // an unexplored potential solution for the % escaping problem, is to create a wrapper .cmd file. + // % can be escaped within a .cmd file. + let reverse = '"'; + let quoteHit = true; + for (let i = arg.length; i > 0; i--) { + // walk the string in reverse + reverse += arg[i - 1]; + if (quoteHit && arg[i - 1] === '\\') { + reverse += '\\'; // double the slash + } + else if (arg[i - 1] === '"') { + quoteHit = true; + reverse += '"'; // double the quote + } + else { + quoteHit = false; + } + } + reverse += '"'; + return reverse + .split('') + .reverse() + .join(''); + } + _uvQuoteCmdArg(arg) { + // Tool runner wraps child_process.spawn() and needs to apply the same quoting as + // Node in certain cases where the undocumented spawn option windowsVerbatimArguments + // is used. + // + // Since this function is a port of quote_cmd_arg from Node 4.x (technically, lib UV, + // see https://github.com/nodejs/node/blob/v4.x/deps/uv/src/win/process.c for details), + // pasting copyright notice from Node within this function: + // + // Copyright Joyent, Inc. and other Node contributors. All rights reserved. + // + // Permission is hereby granted, free of charge, to any person obtaining a copy + // of this software and associated documentation files (the "Software"), to + // deal in the Software without restriction, including without limitation the + // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + // sell copies of the Software, and to permit persons to whom the Software is + // furnished to do so, subject to the following conditions: + // + // The above copyright notice and this permission notice shall be included in + // all copies or substantial portions of the Software. + // + // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + // IN THE SOFTWARE. + if (!arg) { + // Need double quotation for empty argument + return '""'; + } + if (!arg.includes(' ') && !arg.includes('\t') && !arg.includes('"')) { + // No quotation needed + return arg; + } + if (!arg.includes('"') && !arg.includes('\\')) { + // No embedded double quotes or backslashes, so I can just wrap + // quote marks around the whole thing. + return `"${arg}"`; + } + // Expected input/output: + // input : hello"world + // output: "hello\"world" + // input : hello""world + // output: "hello\"\"world" + // input : hello\world + // output: hello\world + // input : hello\\world + // output: hello\\world + // input : hello\"world + // output: "hello\\\"world" + // input : hello\\"world + // output: "hello\\\\\"world" + // input : hello world\ + // output: "hello world\\" - note the comment in libuv actually reads "hello world\" + // but it appears the comment is wrong, it should be "hello world\\" + let reverse = '"'; + let quoteHit = true; + for (let i = arg.length; i > 0; i--) { + // walk the string in reverse + reverse += arg[i - 1]; + if (quoteHit && arg[i - 1] === '\\') { + reverse += '\\'; + } + else if (arg[i - 1] === '"') { + quoteHit = true; + reverse += '\\'; + } + else { + quoteHit = false; + } + } + reverse += '"'; + return reverse + .split('') + .reverse() + .join(''); + } + _cloneExecOptions(options) { + options = options || {}; + const result = { + cwd: options.cwd || process.cwd(), + env: options.env || process.env, + silent: options.silent || false, + windowsVerbatimArguments: options.windowsVerbatimArguments || false, + failOnStdErr: options.failOnStdErr || false, + ignoreReturnCode: options.ignoreReturnCode || false, + delay: options.delay || 10000 + }; + result.outStream = options.outStream || process.stdout; + result.errStream = options.errStream || process.stderr; + return result; + } + _getSpawnOptions(options, toolPath) { + options = options || {}; + const result = {}; + result.cwd = options.cwd; + result.env = options.env; + result['windowsVerbatimArguments'] = + options.windowsVerbatimArguments || this._isCmdFile(); + if (options.windowsVerbatimArguments) { + result.argv0 = `"${toolPath}"`; + } + return result; + } + /** + * Exec a tool. + * Output will be streamed to the live console. + * Returns promise with return code + * + * @param tool path to tool to exec + * @param options optional exec options. See ExecOptions + * @returns number + */ + exec() { + return __awaiter(this, void 0, void 0, function* () { + // root the tool path if it is unrooted and contains relative pathing + if (!ioUtil.isRooted(this.toolPath) && + (this.toolPath.includes('/') || + (IS_WINDOWS && this.toolPath.includes('\\')))) { + // prefer options.cwd if it is specified, however options.cwd may also need to be rooted + this.toolPath = path.resolve(process.cwd(), this.options.cwd || process.cwd(), this.toolPath); + } + // if the tool is only a file name, then resolve it from the PATH + // otherwise verify it exists (add extension on Windows if necessary) + this.toolPath = yield io.which(this.toolPath, true); + return new Promise((resolve, reject) => { + this._debug(`exec tool: ${this.toolPath}`); + this._debug('arguments:'); + for (const arg of this.args) { + this._debug(` ${arg}`); + } + const optionsNonNull = this._cloneExecOptions(this.options); + if (!optionsNonNull.silent && optionsNonNull.outStream) { + optionsNonNull.outStream.write(this._getCommandString(optionsNonNull) + os.EOL); + } + const state = new ExecState(optionsNonNull, this.toolPath); + state.on('debug', (message) => { + this._debug(message); + }); + const fileName = this._getSpawnFileName(); + const cp = child.spawn(fileName, this._getSpawnArgs(optionsNonNull), this._getSpawnOptions(this.options, fileName)); + const stdbuffer = ''; + if (cp.stdout) { + cp.stdout.on('data', (data) => { + if (this.options.listeners && this.options.listeners.stdout) { + this.options.listeners.stdout(data); + } + if (!optionsNonNull.silent && optionsNonNull.outStream) { + optionsNonNull.outStream.write(data); + } + this._processLineBuffer(data, stdbuffer, (line) => { + if (this.options.listeners && this.options.listeners.stdline) { + this.options.listeners.stdline(line); + } + }); + }); + } + const errbuffer = ''; + if (cp.stderr) { + cp.stderr.on('data', (data) => { + state.processStderr = true; + if (this.options.listeners && this.options.listeners.stderr) { + this.options.listeners.stderr(data); + } + if (!optionsNonNull.silent && + optionsNonNull.errStream && + optionsNonNull.outStream) { + const s = optionsNonNull.failOnStdErr + ? optionsNonNull.errStream + : optionsNonNull.outStream; + s.write(data); + } + this._processLineBuffer(data, errbuffer, (line) => { + if (this.options.listeners && this.options.listeners.errline) { + this.options.listeners.errline(line); + } + }); + }); + } + cp.on('error', (err) => { + state.processError = err.message; + state.processExited = true; + state.processClosed = true; + state.CheckComplete(); + }); + cp.on('exit', (code) => { + state.processExitCode = code; + state.processExited = true; + this._debug(`Exit code ${code} received from tool '${this.toolPath}'`); + state.CheckComplete(); + }); + cp.on('close', (code) => { + state.processExitCode = code; + state.processExited = true; + state.processClosed = true; + this._debug(`STDIO streams have closed for tool '${this.toolPath}'`); + state.CheckComplete(); + }); + state.on('done', (error, exitCode) => { + if (stdbuffer.length > 0) { + this.emit('stdline', stdbuffer); + } + if (errbuffer.length > 0) { + this.emit('errline', errbuffer); + } + cp.removeAllListeners(); + if (error) { + reject(error); + } + else { + resolve(exitCode); + } + }); + }); + }); + } +} +exports.ToolRunner = ToolRunner; +/** + * Convert an arg string to an array of args. Handles escaping + * + * @param argString string of arguments + * @returns string[] array of arguments + */ +function argStringToArray(argString) { + const args = []; + let inQuotes = false; + let escaped = false; + let arg = ''; + function append(c) { + // we only escape double quotes. + if (escaped && c !== '"') { + arg += '\\'; + } + arg += c; + escaped = false; + } + for (let i = 0; i < argString.length; i++) { + const c = argString.charAt(i); + if (c === '"') { + if (!escaped) { + inQuotes = !inQuotes; + } + else { + append(c); + } + continue; + } + if (c === '\\' && escaped) { + append(c); + continue; + } + if (c === '\\' && inQuotes) { + escaped = true; + continue; + } + if (c === ' ' && !inQuotes) { + if (arg.length > 0) { + args.push(arg); + arg = ''; + } + continue; + } + append(c); + } + if (arg.length > 0) { + args.push(arg.trim()); + } + return args; +} +exports.argStringToArray = argStringToArray; +class ExecState extends events.EventEmitter { + constructor(options, toolPath) { + super(); + this.processClosed = false; // tracks whether the process has exited and stdio is closed + this.processError = ''; + this.processExitCode = 0; + this.processExited = false; // tracks whether the process has exited + this.processStderr = false; // tracks whether stderr was written to + this.delay = 10000; // 10 seconds + this.done = false; + this.timeout = null; + if (!toolPath) { + throw new Error('toolPath must not be empty'); + } + this.options = options; + this.toolPath = toolPath; + if (options.delay) { + this.delay = options.delay; + } + } + CheckComplete() { + if (this.done) { + return; + } + if (this.processClosed) { + this._setResult(); + } + else if (this.processExited) { + this.timeout = setTimeout(ExecState.HandleTimeout, this.delay, this); + } + } + _debug(message) { + this.emit('debug', message); + } + _setResult() { + // determine whether there is an error + let error; + if (this.processExited) { + if (this.processError) { + error = new Error(`There was an error when attempting to execute the process '${this.toolPath}'. This may indicate the process failed to start. Error: ${this.processError}`); + } + else if (this.processExitCode !== 0 && !this.options.ignoreReturnCode) { + error = new Error(`The process '${this.toolPath}' failed with exit code ${this.processExitCode}`); + } + else if (this.processStderr && this.options.failOnStdErr) { + error = new Error(`The process '${this.toolPath}' failed because one or more lines were written to the STDERR stream`); + } + } + // clear the timeout + if (this.timeout) { + clearTimeout(this.timeout); + this.timeout = null; + } + this.done = true; + this.emit('done', error, this.processExitCode); + } + static HandleTimeout(state) { + if (state.done) { + return; + } + if (!state.processClosed && state.processExited) { + const message = `The STDIO streams did not close within ${state.delay / + 1000} seconds of the exit event from process '${state.toolPath}'. This may indicate a child process inherited the STDIO streams and has not yet exited.`; + state._debug(message); + } + state._setResult(); + } +} +//# sourceMappingURL=toolrunner.js.map + +/***/ }), + +/***/ 11: +/***/ (function(__unusedmodule, exports) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * A surrogate is a code point that is in the range U+D800 to U+DFFF, inclusive. + */ +exports.Surrogate = /[\uD800-\uDFFF]/; +/** + * A scalar value is a code point that is not a surrogate. + */ +exports.ScalarValue = /[\uD800-\uDFFF]/; +/** + * A noncharacter is a code point that is in the range U+FDD0 to U+FDEF, + * inclusive, or U+FFFE, U+FFFF, U+1FFFE, U+1FFFF, U+2FFFE, U+2FFFF, U+3FFFE, + * U+3FFFF, U+4FFFE, U+4FFFF, U+5FFFE, U+5FFFF, U+6FFFE, U+6FFFF, U+7FFFE, + * U+7FFFF, U+8FFFE, U+8FFFF, U+9FFFE, U+9FFFF, U+AFFFE, U+AFFFF, U+BFFFE, + * U+BFFFF, U+CFFFE, U+CFFFF, U+DFFFE, U+DFFFF, U+EFFFE, U+EFFFF, U+FFFFE, + * U+FFFFF, U+10FFFE, or U+10FFFF. + */ +exports.NonCharacter = /[\uFDD0-\uFDEF\uFFFE\uFFFF]|[\uD83F\uD87F\uD8BF\uD8FF\uD93F\uD97F\uD9BF\uD9FF\uDA3F\uDA7F\uDABF\uDAFF\uDB3F\uDB7F\uDBBF\uDBFF][\uDFFE\uDFFF]/; +/** + * An ASCII code point is a code point in the range U+0000 NULL to U+007F + * DELETE, inclusive. + */ +exports.ASCIICodePoint = /[\u0000-\u007F]/; +/** + * An ASCII tab or newline is U+0009 TAB, U+000A LF, or U+000D CR. + */ +exports.ASCIITabOrNewLine = /[\t\n\r]/; +/** + * ASCII whitespace is U+0009 TAB, U+000A LF, U+000C FF, U+000D CR, or + * U+0020 SPACE. + */ +exports.ASCIIWhiteSpace = /[\t\n\f\r ]/; +/** + * A C0 control is a code point in the range U+0000 NULL to U+001F + * INFORMATION SEPARATOR ONE, inclusive. + */ +exports.C0Control = /[\u0000-\u001F]/; +/** + * A C0 control or space is a C0 control or U+0020 SPACE. + */ +exports.C0ControlOrSpace = /[\u0000-\u001F ]/; +/** + * A control is a C0 control or a code point in the range U+007F DELETE to + * U+009F APPLICATION PROGRAM COMMAND, inclusive. + */ +exports.Control = /[\u0000-\u001F\u007F-\u009F]/; +/** + * An ASCII digit is a code point in the range U+0030 (0) to U+0039 (9), + * inclusive. + */ +exports.ASCIIDigit = /[0-9]/; +/** + * An ASCII upper hex digit is an ASCII digit or a code point in the range + * U+0041 (A) to U+0046 (F), inclusive. + */ +exports.ASCIIUpperHexDigit = /[0-9A-F]/; +/** + * An ASCII lower hex digit is an ASCII digit or a code point in the range + * U+0061 (a) to U+0066 (f), inclusive. + */ +exports.ASCIILowerHexDigit = /[0-9a-f]/; +/** + * An ASCII hex digit is an ASCII upper hex digit or ASCII lower hex digit. + */ +exports.ASCIIHexDigit = /[0-9A-Fa-f]/; +/** + * An ASCII upper alpha is a code point in the range U+0041 (A) to U+005A (Z), + * inclusive. + */ +exports.ASCIIUpperAlpha = /[A-Z]/; +/** + * An ASCII lower alpha is a code point in the range U+0061 (a) to U+007A (z), + * inclusive. + */ +exports.ASCIILowerAlpha = /[a-z]/; +/** + * An ASCII alpha is an ASCII upper alpha or ASCII lower alpha. + */ +exports.ASCIIAlpha = /[A-Za-z]/; +/** + * An ASCII alphanumeric is an ASCII digit or ASCII alpha. + */ +exports.ASCIIAlphanumeric = /[0-9A-Za-z]/; +//# sourceMappingURL=CodePoints.js.map + +/***/ }), + +/***/ 15: +/***/ (function(__unusedmodule, exports) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * Determines if the given number is an ASCII byte. + * + * @param byte - a byte + */ +function isASCIIByte(byte) { + /** + * An ASCII byte is a byte in the range 0x00 (NUL) to 0x7F (DEL), inclusive. + */ + return byte >= 0x00 && byte <= 0x7F; +} +exports.isASCIIByte = isASCIIByte; +//# sourceMappingURL=Byte.js.map + +/***/ }), + +/***/ 16: +/***/ (function(module) { + +module.exports = require("tls"); + +/***/ }), + +/***/ 18: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const util_1 = __webpack_require__(918); +/** + * Represents a mixin that extends child nodes that can have siblings + * other than doctypes. This mixin is implemented by {@link Element} and + * {@link CharacterData}. + */ +class NonDocumentTypeChildNodeImpl { + /** @inheritdoc */ + get previousElementSibling() { + /** + * The previousElementSibling attribute’s getter must return the first + * preceding sibling that is an element, and null otherwise. + */ + let node = util_1.Cast.asNode(this)._previousSibling; + while (node) { + if (util_1.Guard.isElementNode(node)) + return node; + else + node = node._previousSibling; + } + return null; + } + /** @inheritdoc */ + get nextElementSibling() { + /** + * The nextElementSibling attribute’s getter must return the first + * following sibling that is an element, and null otherwise. + */ + let node = util_1.Cast.asNode(this)._nextSibling; + while (node) { + if (util_1.Guard.isElementNode(node)) + return node; + else + node = node._nextSibling; + } + return null; + } +} +exports.NonDocumentTypeChildNodeImpl = NonDocumentTypeChildNodeImpl; +//# sourceMappingURL=NonDocumentTypeChildNodeImpl.js.map + +/***/ }), + +/***/ 22: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const interfaces_1 = __webpack_require__(970); +const DOMException_1 = __webpack_require__(35); +const util_1 = __webpack_require__(918); +const CreateAlgorithm_1 = __webpack_require__(86); +const TreeAlgorithm_1 = __webpack_require__(873); +const BoundaryPointAlgorithm_1 = __webpack_require__(350); +const CharacterDataAlgorithm_1 = __webpack_require__(27); +const NodeAlgorithm_1 = __webpack_require__(541); +const MutationAlgorithm_1 = __webpack_require__(479); +const TextAlgorithm_1 = __webpack_require__(154); +/** + * Determines if the node's start boundary point is at its end boundary + * point. + * + * @param range - a range + */ +function range_collapsed(range) { + /** + * A range is collapsed if its start node is its end node and its start offset is its end offset. + */ + return (range._startNode === range._endNode && range._startOffset === range._endOffset); +} +exports.range_collapsed = range_collapsed; +/** + * Gets the root node of a range. + * + * @param range - a range + */ +function range_root(range) { + /** + * The root of a live range is the root of its start node. + */ + return TreeAlgorithm_1.tree_rootNode(range._startNode); +} +exports.range_root = range_root; +/** + * Determines if a node is fully contained in a range. + * + * @param node - a node + * @param range - a range + */ +function range_isContained(node, range) { + /** + * A node node is contained in a live range range if node’s root is range’s + * root, and (node, 0) is after range’s start, and (node, node’s length) is + * before range’s end. + */ + return (TreeAlgorithm_1.tree_rootNode(node) === range_root(range) && + BoundaryPointAlgorithm_1.boundaryPoint_position([node, 0], range._start) === interfaces_1.BoundaryPosition.After && + BoundaryPointAlgorithm_1.boundaryPoint_position([node, TreeAlgorithm_1.tree_nodeLength(node)], range._end) === interfaces_1.BoundaryPosition.Before); +} +exports.range_isContained = range_isContained; +/** + * Determines if a node is partially contained in a range. + * + * @param node - a node + * @param range - a range + */ +function range_isPartiallyContained(node, range) { + /** + * A node is partially contained in a live range if it’s an inclusive + * ancestor of the live range’s start node but not its end node, + * or vice versa. + */ + const startCheck = TreeAlgorithm_1.tree_isAncestorOf(range._startNode, node, true); + const endCheck = TreeAlgorithm_1.tree_isAncestorOf(range._endNode, node, true); + return (startCheck && !endCheck) || (!startCheck && endCheck); +} +exports.range_isPartiallyContained = range_isPartiallyContained; +/** + * Sets the start boundary point of a range. + * + * @param range - a range + * @param node - a node + * @param offset - an offset into node + */ +function range_setTheStart(range, node, offset) { + /** + * 1. If node is a doctype, then throw an "InvalidNodeTypeError" DOMException. + * 2. If offset is greater than node’s length, then throw an "IndexSizeError" + * DOMException. + * 3. Let bp be the boundary point (node, offset). + * 4. If these steps were invoked as "set the start" + * 4.1. If bp is after the range’s end, or if range’s root is not equal to + * node’s root, set range’s end to bp. + * 4.2. Set range’s start to bp. + */ + if (util_1.Guard.isDocumentTypeNode(node)) { + throw new DOMException_1.InvalidNodeTypeError(); + } + if (offset > TreeAlgorithm_1.tree_nodeLength(node)) { + throw new DOMException_1.IndexSizeError(); + } + const bp = [node, offset]; + if (range_root(range) !== TreeAlgorithm_1.tree_rootNode(node) || + BoundaryPointAlgorithm_1.boundaryPoint_position(bp, range._end) === interfaces_1.BoundaryPosition.After) { + range._end = bp; + } + range._start = bp; +} +exports.range_setTheStart = range_setTheStart; +/** + * Sets the end boundary point of a range. + * + * @param range - a range + * @param node - a node + * @param offset - an offset into node + */ +function range_setTheEnd(range, node, offset) { + /** + * 1. If node is a doctype, then throw an "InvalidNodeTypeError" DOMException. + * 2. If offset is greater than node’s length, then throw an "IndexSizeError" + * DOMException. + * 3. Let bp be the boundary point (node, offset). + * 4. If these steps were invoked as "set the end" + * 4.1. If bp is before the range’s start, or if range’s root is not equal + * to node’s root, set range’s start to bp. + * 4.2. Set range’s end to bp. + */ + if (util_1.Guard.isDocumentTypeNode(node)) { + throw new DOMException_1.InvalidNodeTypeError(); + } + if (offset > TreeAlgorithm_1.tree_nodeLength(node)) { + throw new DOMException_1.IndexSizeError(); + } + const bp = [node, offset]; + if (range_root(range) !== TreeAlgorithm_1.tree_rootNode(node) || + BoundaryPointAlgorithm_1.boundaryPoint_position(bp, range._start) === interfaces_1.BoundaryPosition.Before) { + range._start = bp; + } + range._end = bp; +} +exports.range_setTheEnd = range_setTheEnd; +/** + * Selects a node. + * + * @param range - a range + * @param node - a node + */ +function range_select(node, range) { + /** + * 1. Let parent be node’s parent. + * 2. If parent is null, then throw an "InvalidNodeTypeError" DOMException. + */ + const parent = node._parent; + if (parent === null) + throw new DOMException_1.InvalidNodeTypeError(); + /** + * 3. Let index be node’s index. + * 4. Set range’s start to boundary point (parent, index). + * 5. Set range’s end to boundary point (parent, index plus 1). + */ + const index = TreeAlgorithm_1.tree_index(node); + range._start = [parent, index]; + range._end = [parent, index + 1]; +} +exports.range_select = range_select; +/** + * EXtracts the contents of range as a document fragment. + * + * @param range - a range + */ +function range_extract(range) { + /** + * 1. Let fragment be a new DocumentFragment node whose node document is + * range’s start node’s node document. + * 2. If range is collapsed, then return fragment. + */ + const fragment = CreateAlgorithm_1.create_documentFragment(range._startNode._nodeDocument); + if (range_collapsed(range)) + return fragment; + /** + * 3. Let original start node, original start offset, original end node, + * and original end offset be range’s start node, start offset, end node, + * and end offset, respectively. + */ + const originalStartNode = range._startNode; + const originalStartOffset = range._startOffset; + const originalEndNode = range._endNode; + const originalEndOffset = range._endOffset; + /** + * 4. If original start node is original end node, and they are a Text, + * ProcessingInstruction, or Comment node: + * 4.1. Let clone be a clone of original start node. + * 4.2. Set the data of clone to the result of substringing data with node + * original start node, offset original start offset, and count original end + * offset minus original start offset. + * 4.3. Append clone to fragment. + * 4.4. Replace data with node original start node, offset original start + * offset, count original end offset minus original start offset, and data + * the empty string. + * 4.5. Return fragment. + */ + if (originalStartNode === originalEndNode && + util_1.Guard.isCharacterDataNode(originalStartNode)) { + const clone = NodeAlgorithm_1.node_clone(originalStartNode); + clone._data = CharacterDataAlgorithm_1.characterData_substringData(originalStartNode, originalStartOffset, originalEndOffset - originalStartOffset); + MutationAlgorithm_1.mutation_append(clone, fragment); + CharacterDataAlgorithm_1.characterData_replaceData(originalStartNode, originalStartOffset, originalEndOffset - originalStartOffset, ''); + return fragment; + } + /** + * 5. Let common ancestor be original start node. + * 6. While common ancestor is not an inclusive ancestor of original end + * node, set common ancestor to its own parent. + */ + let commonAncestor = originalStartNode; + while (!TreeAlgorithm_1.tree_isAncestorOf(originalEndNode, commonAncestor, true)) { + if (commonAncestor._parent === null) { + throw new Error("Parent node is null."); + } + commonAncestor = commonAncestor._parent; + } + /** + * 7. Let first partially contained child be null. + * 8. If original start node is not an inclusive ancestor of original end + * node, set first partially contained child to the first child of common + * ancestor that is partially contained in range. + */ + let firstPartiallyContainedChild = null; + if (!TreeAlgorithm_1.tree_isAncestorOf(originalEndNode, originalStartNode, true)) { + for (const node of commonAncestor._children) { + if (range_isPartiallyContained(node, range)) { + firstPartiallyContainedChild = node; + break; + } + } + } + /** + * 9. Let last partially contained child be null. + * 10. If original end node is not an inclusive ancestor of original start + * node, set last partially contained child to the last child of common + * ancestor that is partially contained in range. + */ + let lastPartiallyContainedChild = null; + if (!TreeAlgorithm_1.tree_isAncestorOf(originalStartNode, originalEndNode, true)) { + const children = [...commonAncestor._children]; + for (let i = children.length - 1; i > 0; i--) { + const node = children[i]; + if (range_isPartiallyContained(node, range)) { + lastPartiallyContainedChild = node; + break; + } + } + } + /** + * 11. Let contained children be a list of all children of common ancestor + * that are contained in range, in tree order. + * 12. If any member of contained children is a doctype, then throw a + * "HierarchyRequestError" DOMException. + */ + const containedChildren = []; + for (const child of commonAncestor._children) { + if (range_isContained(child, range)) { + if (util_1.Guard.isDocumentTypeNode(child)) { + throw new DOMException_1.HierarchyRequestError(); + } + containedChildren.push(child); + } + } + let newNode; + let newOffset; + if (TreeAlgorithm_1.tree_isAncestorOf(originalEndNode, originalStartNode, true)) { + /** + * 13. If original start node is an inclusive ancestor of original end node, + * set new node to original start node and new offset to original start + * offset. + */ + newNode = originalStartNode; + newOffset = originalStartOffset; + } + else { + /** + * 14. Otherwise: + * 14.1. Let reference node equal original start node. + * 14.2. While reference node’s parent is not null and is not an inclusive + * ancestor of original end node, set reference node to its parent. + * 14.3. Set new node to the parent of reference node, and new offset to + * one plus reference node’s index. + */ + let referenceNode = originalStartNode; + while (referenceNode._parent !== null && + !TreeAlgorithm_1.tree_isAncestorOf(originalEndNode, referenceNode._parent)) { + referenceNode = referenceNode._parent; + } + /* istanbul ignore next */ + if (referenceNode._parent === null) { + /** + * If reference node’s parent is null, it would be the root of range, + * so would be an inclusive ancestor of original end node, and we could + * not reach this point. + */ + throw new Error("Parent node is null."); + } + newNode = referenceNode._parent; + newOffset = 1 + TreeAlgorithm_1.tree_index(referenceNode); + } + if (util_1.Guard.isCharacterDataNode(firstPartiallyContainedChild)) { + /** + * 15. If first partially contained child is a Text, ProcessingInstruction, + * or Comment node: + * 15.1. Let clone be a clone of original start node. + * 15.2. Set the data of clone to the result of substringing data with + * node original start node, offset original start offset, and count + * original start node’s length minus original start offset. + * 15.3. Append clone to fragment. + * 15.4. Replace data with node original start node, offset original + * start offset, count original start node’s length minus original start + * offset, and data the empty string. + */ + const clone = NodeAlgorithm_1.node_clone(originalStartNode); + clone._data = CharacterDataAlgorithm_1.characterData_substringData(originalStartNode, originalStartOffset, TreeAlgorithm_1.tree_nodeLength(originalStartNode) - originalStartOffset); + MutationAlgorithm_1.mutation_append(clone, fragment); + CharacterDataAlgorithm_1.characterData_replaceData(originalStartNode, originalStartOffset, TreeAlgorithm_1.tree_nodeLength(originalStartNode) - originalStartOffset, ''); + } + else if (firstPartiallyContainedChild !== null) { + /** + * 16. Otherwise, if first partially contained child is not null: + * 16.1. Let clone be a clone of first partially contained child. + * 16.2. Append clone to fragment. + * 16.3. Let subrange be a new live range whose start is (original start + * node, original start offset) and whose end is (first partially + * contained child, first partially contained child’s length). + * 16.4. Let subfragment be the result of extracting subrange. + * 16.5. Append subfragment to clone. + */ + const clone = NodeAlgorithm_1.node_clone(firstPartiallyContainedChild); + MutationAlgorithm_1.mutation_append(clone, fragment); + const subrange = CreateAlgorithm_1.create_range([originalStartNode, originalStartOffset], [firstPartiallyContainedChild, TreeAlgorithm_1.tree_nodeLength(firstPartiallyContainedChild)]); + const subfragment = range_extract(subrange); + MutationAlgorithm_1.mutation_append(subfragment, clone); + } + /** + * 17. For each contained child in contained children, append contained + * child to fragment. + */ + for (const child of containedChildren) { + MutationAlgorithm_1.mutation_append(child, fragment); + } + if (util_1.Guard.isCharacterDataNode(lastPartiallyContainedChild)) { + /** + * 18. If last partially contained child is a Text, ProcessingInstruction, + * or Comment node: + * 18.1. Let clone be a clone of original end node. + * 18.2. Set the data of clone to the result of substringing data with + * node original end node, offset 0, and count original end offset. + * 18.3. Append clone to fragment. + * 18.4. Replace data with node original end node, offset 0, count + * original end offset, and data the empty string. + */ + const clone = NodeAlgorithm_1.node_clone(originalEndNode); + clone._data = CharacterDataAlgorithm_1.characterData_substringData(originalEndNode, 0, originalEndOffset); + MutationAlgorithm_1.mutation_append(clone, fragment); + CharacterDataAlgorithm_1.characterData_replaceData(originalEndNode, 0, originalEndOffset, ''); + } + else if (lastPartiallyContainedChild !== null) { + /** + * 19. Otherwise, if last partially contained child is not null: + * 19.1. Let clone be a clone of last partially contained child. + * 19.2. Append clone to fragment. + * 19.3. Let subrange be a new live range whose start is (last partially + * contained child, 0) and whose end is (original end node, original + * end offset). + * 19.4. Let subfragment be the result of extracting subrange. + * 19.5. Append subfragment to clone. + */ + const clone = NodeAlgorithm_1.node_clone(lastPartiallyContainedChild); + MutationAlgorithm_1.mutation_append(clone, fragment); + const subrange = CreateAlgorithm_1.create_range([lastPartiallyContainedChild, 0], [originalEndNode, originalEndOffset]); + const subfragment = range_extract(subrange); + MutationAlgorithm_1.mutation_append(subfragment, clone); + } + /** + * 20. Set range’s start and end to (new node, new offset). + */ + range._start = [newNode, newOffset]; + range._end = [newNode, newOffset]; + /** + * 21. Return fragment. + */ + return fragment; +} +exports.range_extract = range_extract; +/** + * Clones the contents of range as a document fragment. + * + * @param range - a range + */ +function range_cloneTheContents(range) { + /** + * 1. Let fragment be a new DocumentFragment node whose node document + * is range’s start node’s node document. + * 2. If range is collapsed, then return fragment. + */ + const fragment = CreateAlgorithm_1.create_documentFragment(range._startNode._nodeDocument); + if (range_collapsed(range)) + return fragment; + /** + * 3. Let original start node, original start offset, original end node, + * and original end offset be range’s start node, start offset, end node, + * and end offset, respectively. + * 4. If original start node is original end node, and they are a Text, + * ProcessingInstruction, or Comment node: + * 4.1. Let clone be a clone of original start node. + * 4.2. Set the data of clone to the result of substringing data with node + * original start node, offset original start offset, and count original end + * offset minus original start offset. + * 4.3. Append clone to fragment. + * 4.5. Return fragment. + */ + const originalStartNode = range._startNode; + const originalStartOffset = range._startOffset; + const originalEndNode = range._endNode; + const originalEndOffset = range._endOffset; + if (originalStartNode === originalEndNode && + util_1.Guard.isCharacterDataNode(originalStartNode)) { + const clone = NodeAlgorithm_1.node_clone(originalStartNode); + clone._data = CharacterDataAlgorithm_1.characterData_substringData(originalStartNode, originalStartOffset, originalEndOffset - originalStartOffset); + MutationAlgorithm_1.mutation_append(clone, fragment); + } + /** + * 5. Let common ancestor be original start node. + * 6. While common ancestor is not an inclusive ancestor of original end + * node, set common ancestor to its own parent. + */ + let commonAncestor = originalStartNode; + while (!TreeAlgorithm_1.tree_isAncestorOf(originalEndNode, commonAncestor, true)) { + if (commonAncestor._parent === null) { + throw new Error("Parent node is null."); + } + commonAncestor = commonAncestor._parent; + } + /** + * 7. Let first partially contained child be null. + * 8. If original start node is not an inclusive ancestor of original end + * node, set first partially contained child to the first child of common + * ancestor that is partially contained in range. + */ + let firstPartiallyContainedChild = null; + if (!TreeAlgorithm_1.tree_isAncestorOf(originalEndNode, originalStartNode, true)) { + for (const node of commonAncestor._children) { + if (range_isPartiallyContained(node, range)) { + firstPartiallyContainedChild = node; + break; + } + } + } + /** + * 9. Let last partially contained child be null. + * 10. If original end node is not an inclusive ancestor of original start + * node, set last partially contained child to the last child of common + * ancestor that is partially contained in range. + */ + let lastPartiallyContainedChild = null; + if (!TreeAlgorithm_1.tree_isAncestorOf(originalStartNode, originalEndNode, true)) { + const children = [...commonAncestor._children]; + for (let i = children.length - 1; i > 0; i--) { + const node = children[i]; + if (range_isPartiallyContained(node, range)) { + lastPartiallyContainedChild = node; + break; + } + } + } + /** + * 11. Let contained children be a list of all children of common ancestor + * that are contained in range, in tree order. + * 12. If any member of contained children is a doctype, then throw a + * "HierarchyRequestError" DOMException. + */ + const containedChildren = []; + for (const child of commonAncestor._children) { + if (range_isContained(child, range)) { + if (util_1.Guard.isDocumentTypeNode(child)) { + throw new DOMException_1.HierarchyRequestError(); + } + containedChildren.push(child); + } + } + if (util_1.Guard.isCharacterDataNode(firstPartiallyContainedChild)) { + /** + * 13. If first partially contained child is a Text, ProcessingInstruction, + * or Comment node: + * 13.1. Let clone be a clone of original start node. + * 13.2. Set the data of clone to the result of substringing data with + * node original start node, offset original start offset, and count + * original start node’s length minus original start offset. + * 13.3. Append clone to fragment. + */ + const clone = NodeAlgorithm_1.node_clone(originalStartNode); + clone._data = CharacterDataAlgorithm_1.characterData_substringData(originalStartNode, originalStartOffset, TreeAlgorithm_1.tree_nodeLength(originalStartNode) - originalStartOffset); + MutationAlgorithm_1.mutation_append(clone, fragment); + } + else if (firstPartiallyContainedChild !== null) { + /** + * 14. Otherwise, if first partially contained child is not null: + * 14.1. Let clone be a clone of first partially contained child. + * 14.2. Append clone to fragment. + * 14.3. Let subrange be a new live range whose start is (original start + * node, original start offset) and whose end is (first partially + * contained child, first partially contained child’s length). + * 14.4. Let subfragment be the result of cloning the contents of + * subrange. + * 14.5. Append subfragment to clone. + */ + const clone = NodeAlgorithm_1.node_clone(firstPartiallyContainedChild); + MutationAlgorithm_1.mutation_append(clone, fragment); + const subrange = CreateAlgorithm_1.create_range([originalStartNode, originalStartOffset], [firstPartiallyContainedChild, TreeAlgorithm_1.tree_nodeLength(firstPartiallyContainedChild)]); + const subfragment = range_cloneTheContents(subrange); + MutationAlgorithm_1.mutation_append(subfragment, clone); + } + /** + * 15. For each contained child in contained children, append contained + * child to fragment. + * 15.1. Let clone be a clone of contained child with the clone children + * flag set. + * 15.2. Append clone to fragment. + */ + for (const child of containedChildren) { + const clone = NodeAlgorithm_1.node_clone(child); + MutationAlgorithm_1.mutation_append(clone, fragment); + } + if (util_1.Guard.isCharacterDataNode(lastPartiallyContainedChild)) { + /** + * 16. If last partially contained child is a Text, ProcessingInstruction, + * or Comment node: + * 16.1. Let clone be a clone of original end node. + * 16.2. Set the data of clone to the result of substringing data with + * node original end node, offset 0, and count original end offset. + * 16.3. Append clone to fragment. + */ + const clone = NodeAlgorithm_1.node_clone(originalEndNode); + clone._data = CharacterDataAlgorithm_1.characterData_substringData(originalEndNode, 0, originalEndOffset); + MutationAlgorithm_1.mutation_append(clone, fragment); + } + else if (lastPartiallyContainedChild !== null) { + /** + * 17. Otherwise, if last partially contained child is not null: + * 17.1. Let clone be a clone of last partially contained child. + * 17.2. Append clone to fragment. + * 17.3. Let subrange be a new live range whose start is (last partially + * contained child, 0) and whose end is (original end node, original + * end offset). + * 17.4. Let subfragment be the result of cloning the contents of subrange. + * 17.5. Append subfragment to clone. + */ + const clone = NodeAlgorithm_1.node_clone(lastPartiallyContainedChild); + fragment.append(clone); + const subrange = CreateAlgorithm_1.create_range([lastPartiallyContainedChild, 0], [originalEndNode, originalEndOffset]); + const subfragment = range_extract(subrange); + MutationAlgorithm_1.mutation_append(subfragment, clone); + } + /** + * 18. Return fragment. + */ + return fragment; +} +exports.range_cloneTheContents = range_cloneTheContents; +/** + * Inserts a node into a range at the start boundary point. + * + * @param node - node to insert + * @param range - a range + */ +function range_insert(node, range) { + /** + * 1. If range’s start node is a ProcessingInstruction or Comment node, is a + * Text node whose parent is null, or is node, then throw a + * "HierarchyRequestError" DOMException. + */ + if (util_1.Guard.isProcessingInstructionNode(range._startNode) || + util_1.Guard.isCommentNode(range._startNode) || + (util_1.Guard.isTextNode(range._startNode) && range._startNode._parent === null) || + range._startNode === node) { + throw new DOMException_1.HierarchyRequestError(); + } + /** + * 2. Let referenceNode be null. + * 3. If range’s start node is a Text node, set referenceNode to that Text + * node. + * 4. Otherwise, set referenceNode to the child of start node whose index is + * start offset, and null if there is no such child. + */ + let referenceNode = null; + if (util_1.Guard.isTextNode(range._startNode)) { + referenceNode = range._startNode; + } + else { + let index = 0; + for (const child of range._startNode._children) { + if (index === range._startOffset) { + referenceNode = child; + break; + } + index++; + } + } + /** + * 5. Let parent be range’s start node if referenceNode is null, and + * referenceNode’s parent otherwise. + */ + let parent; + if (referenceNode === null) { + parent = range._startNode; + } + else { + if (referenceNode._parent === null) { + throw new Error("Parent node is null."); + } + parent = referenceNode._parent; + } + /** + * 6. Ensure pre-insertion validity of node into parent before referenceNode. + */ + MutationAlgorithm_1.mutation_ensurePreInsertionValidity(node, parent, referenceNode); + /** + * 7. If range’s start node is a Text node, set referenceNode to the result + * of splitting it with offset range’s start offset. + */ + if (util_1.Guard.isTextNode(range._startNode)) { + referenceNode = TextAlgorithm_1.text_split(range._startNode, range._startOffset); + } + /** + * 8. If node is referenceNode, set referenceNode to its next sibling. + */ + if (node === referenceNode) { + referenceNode = node._nextSibling; + } + /** + * 9. If node’s parent is not null, remove node from its parent. + */ + if (node._parent !== null) { + MutationAlgorithm_1.mutation_remove(node, node._parent); + } + /** + * 10. Let newOffset be parent’s length if referenceNode is null, and + * referenceNode’s index otherwise. + */ + let newOffset = (referenceNode === null ? + TreeAlgorithm_1.tree_nodeLength(parent) : TreeAlgorithm_1.tree_index(referenceNode)); + /** + * 11. Increase newOffset by node’s length if node is a DocumentFragment + * node, and one otherwise. + */ + if (util_1.Guard.isDocumentFragmentNode(node)) { + newOffset += TreeAlgorithm_1.tree_nodeLength(node); + } + else { + newOffset++; + } + /** + * 12. Pre-insert node into parent before referenceNode. + */ + MutationAlgorithm_1.mutation_preInsert(node, parent, referenceNode); + /** + * 13. If range is collapsed, then set range’s end to (parent, newOffset). + */ + if (range_collapsed(range)) { + range._end = [parent, newOffset]; + } +} +exports.range_insert = range_insert; +/** + * Traverses through all contained nodes of a range. + * + * @param range - a range + */ +function range_getContainedNodes(range) { + return { + [Symbol.iterator]: () => { + const container = range.commonAncestorContainer; + let currentNode = TreeAlgorithm_1.tree_getFirstDescendantNode(container); + return { + next: () => { + while (currentNode && !range_isContained(currentNode, range)) { + currentNode = TreeAlgorithm_1.tree_getNextDescendantNode(container, currentNode); + } + if (currentNode === null) { + return { done: true, value: null }; + } + else { + const result = { done: false, value: currentNode }; + currentNode = TreeAlgorithm_1.tree_getNextDescendantNode(container, currentNode); + return result; + } + } + }; + } + }; +} +exports.range_getContainedNodes = range_getContainedNodes; +/** + * Traverses through all partially contained nodes of a range. + * + * @param range - a range + */ +function range_getPartiallyContainedNodes(range) { + return { + [Symbol.iterator]: () => { + const container = range.commonAncestorContainer; + let currentNode = TreeAlgorithm_1.tree_getFirstDescendantNode(container); + return { + next: () => { + while (currentNode && !range_isPartiallyContained(currentNode, range)) { + currentNode = TreeAlgorithm_1.tree_getNextDescendantNode(container, currentNode); + } + if (currentNode === null) { + return { done: true, value: null }; + } + else { + const result = { done: false, value: currentNode }; + currentNode = TreeAlgorithm_1.tree_getNextDescendantNode(container, currentNode); + return result; + } + } + }; + } + }; +} +exports.range_getPartiallyContainedNodes = range_getPartiallyContainedNodes; +//# sourceMappingURL=RangeAlgorithm.js.map + +/***/ }), + +/***/ 23: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result["default"] = mod; + return result; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const base64 = __importStar(__webpack_require__(763)); +exports.base64 = base64; +const byte = __importStar(__webpack_require__(782)); +exports.byte = byte; +const byteSequence = __importStar(__webpack_require__(263)); +exports.byteSequence = byteSequence; +const codePoint = __importStar(__webpack_require__(11)); +exports.codePoint = codePoint; +const json = __importStar(__webpack_require__(522)); +exports.json = json; +const list = __importStar(__webpack_require__(657)); +exports.list = list; +const map = __importStar(__webpack_require__(279)); +exports.map = map; +const namespace = __importStar(__webpack_require__(916)); +exports.namespace = namespace; +const queue = __importStar(__webpack_require__(501)); +exports.queue = queue; +const set = __importStar(__webpack_require__(496)); +exports.set = set; +const stack = __importStar(__webpack_require__(134)); +exports.stack = stack; +const string = __importStar(__webpack_require__(97)); +exports.string = string; +//# sourceMappingURL=index.js.map + +/***/ }), + +/***/ 27: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const dom_1 = __webpack_require__(113); +const util_1 = __webpack_require__(918); +const DOMException_1 = __webpack_require__(35); +const TreeAlgorithm_1 = __webpack_require__(873); +const MutationObserverAlgorithm_1 = __webpack_require__(151); +const DOMAlgorithm_1 = __webpack_require__(304); +/** + * Replaces character data. + * + * @param node - a character data node + * @param offset - start offset + * @param count - count of characters to replace + * @param data - new data + */ +function characterData_replaceData(node, offset, count, data) { + /** + * 1. Let length be node’s length. + * 2. If offset is greater than length, then throw an "IndexSizeError" + * DOMException. + * 3. If offset plus count is greater than length, then set count to length + * minus offset. + */ + const length = TreeAlgorithm_1.tree_nodeLength(node); + if (offset > length) { + throw new DOMException_1.IndexSizeError(`Offset exceeds character data length. Offset: ${offset}, Length: ${length}, Node is ${node.nodeName}.`); + } + if (offset + count > length) { + count = length - offset; + } + /** + * 4. Queue a mutation record of "characterData" for node with null, null, + * node’s data, « », « », null, and null. + */ + if (dom_1.dom.features.mutationObservers) { + MutationObserverAlgorithm_1.observer_queueMutationRecord("characterData", node, null, null, node._data, [], [], null, null); + } + /** + * 5. Insert data into node’s data after offset code units. + * 6. Let delete offset be offset + data’s length. + * 7. Starting from delete offset code units, remove count code units from + * node’s data. + */ + const newData = node._data.substring(0, offset) + data + + node._data.substring(offset + count); + node._data = newData; + /** + * 8. For each live range whose start node is node and start offset is + * greater than offset but less than or equal to offset plus count, set its + * start offset to offset. + * 9. For each live range whose end node is node and end offset is greater + * than offset but less than or equal to offset plus count, set its end + * offset to offset. + * 10. For each live range whose start node is node and start offset is + * greater than offset plus count, increase its start offset by data’s + * length and decrease it by count. + * 11. For each live range whose end node is node and end offset is greater + * than offset plus count, increase its end offset by data’s length and + * decrease it by count. + */ + for (const range of dom_1.dom.rangeList) { + if (range._start[0] === node && range._start[1] > offset && range._start[1] <= offset + count) { + range._start[1] = offset; + } + if (range._end[0] === node && range._end[1] > offset && range._end[1] <= offset + count) { + range._end[1] = offset; + } + if (range._start[0] === node && range._start[1] > offset + count) { + range._start[1] += data.length - count; + } + if (range._end[0] === node && range._end[1] > offset + count) { + range._end[1] += data.length - count; + } + } + /** + * 12. If node is a Text node and its parent is not null, run the child + * text content change steps for node’s parent. + */ + if (dom_1.dom.features.steps) { + if (util_1.Guard.isTextNode(node) && node._parent !== null) { + DOMAlgorithm_1.dom_runChildTextContentChangeSteps(node._parent); + } + } +} +exports.characterData_replaceData = characterData_replaceData; +/** + * Returns `count` number of characters from `node`'s data starting at + * the given `offset`. + * + * @param node - a character data node + * @param offset - start offset + * @param count - count of characters to return + */ +function characterData_substringData(node, offset, count) { + /** + * 1. Let length be node’s length. + * 2. If offset is greater than length, then throw an "IndexSizeError" + * DOMException. + * 3. If offset plus count is greater than length, return a string whose + * value is the code units from the offsetth code unit to the end of node’s + * data, and then return. + * 4. Return a string whose value is the code units from the offsetth code + * unit to the offset+countth code unit in node’s data. + */ + const length = TreeAlgorithm_1.tree_nodeLength(node); + if (offset > length) { + throw new DOMException_1.IndexSizeError(`Offset exceeds character data length. Offset: ${offset}, Length: ${length}, Node is ${node.nodeName}.`); + } + if (offset + count > length) { + return node._data.substr(offset); + } + else { + return node._data.substr(offset, count); + } +} +exports.characterData_substringData = characterData_substringData; +//# sourceMappingURL=CharacterDataAlgorithm.js.map + +/***/ }), + +/***/ 33: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const dom_1 = __webpack_require__(113); +const infra_1 = __webpack_require__(23); +const util_1 = __webpack_require__(918); +const DOMException_1 = __webpack_require__(35); +const CreateAlgorithm_1 = __webpack_require__(86); +const CustomElementAlgorithm_1 = __webpack_require__(344); +const MutationObserverAlgorithm_1 = __webpack_require__(151); +const DOMAlgorithm_1 = __webpack_require__(304); +const MutationAlgorithm_1 = __webpack_require__(479); +const DocumentAlgorithm_1 = __webpack_require__(493); +/** + * Determines whether the element's attribute list contains the given + * attribute. + * + * @param attribute - an attribute node + * @param element - an element node + */ +function element_has(attribute, element) { + /** + * An element has an attribute A if its attribute list contains A. + */ + return element._attributeList._asArray().indexOf(attribute) !== -1; +} +exports.element_has = element_has; +/** + * Changes the value of an attribute node. + * + * @param attribute - an attribute node + * @param element - an element node + * @param value - attribute value + */ +function element_change(attribute, element, value) { + /** + * 1. Queue an attribute mutation record for element with attribute’s + * local name, attribute’s namespace, and attribute’s value. + */ + if (dom_1.dom.features.mutationObservers) { + MutationObserverAlgorithm_1.observer_queueAttributeMutationRecord(element, attribute._localName, attribute._namespace, attribute._value); + } + /** + * 2. If element is custom, then enqueue a custom element callback reaction + * with element, callback name "attributeChangedCallback", and an argument + * list containing attribute’s local name, attribute’s value, value, and + * attribute’s namespace. + */ + if (dom_1.dom.features.customElements) { + if (util_1.Guard.isCustomElementNode(element)) { + CustomElementAlgorithm_1.customElement_enqueueACustomElementCallbackReaction(element, "attributeChangedCallback", [attribute._localName, attribute._value, value, attribute._namespace]); + } + } + /** + * 3. Run the attribute change steps with element, attribute’s local name, + * attribute’s value, value, and attribute’s namespace. + * 4. Set attribute’s value to value. + */ + if (dom_1.dom.features.steps) { + DOMAlgorithm_1.dom_runAttributeChangeSteps(element, attribute._localName, attribute._value, value, attribute._namespace); + } + attribute._value = value; +} +exports.element_change = element_change; +/** + * Appends an attribute to an element node. + * + * @param attribute - an attribute + * @param element - an element to receive the attribute + */ +function element_append(attribute, element) { + /** + * 1. Queue an attribute mutation record for element with attribute’s + * local name, attribute’s namespace, and null. + */ + if (dom_1.dom.features.mutationObservers) { + MutationObserverAlgorithm_1.observer_queueAttributeMutationRecord(element, attribute._localName, attribute._namespace, null); + } + /** + * 2. If element is custom, then enqueue a custom element callback reaction + * with element, callback name "attributeChangedCallback", and an argument + * list containing attribute’s local name, null, attribute’s value, and + * attribute’s namespace. + */ + if (dom_1.dom.features.customElements) { + if (util_1.Guard.isCustomElementNode(element)) { + CustomElementAlgorithm_1.customElement_enqueueACustomElementCallbackReaction(element, "attributeChangedCallback", [attribute._localName, null, attribute._value, attribute._namespace]); + } + } + /** + * 3. Run the attribute change steps with element, attribute’s local name, + * null, attribute’s value, and attribute’s namespace. + */ + if (dom_1.dom.features.steps) { + DOMAlgorithm_1.dom_runAttributeChangeSteps(element, attribute._localName, null, attribute._value, attribute._namespace); + } + /** + * 4. Append attribute to element’s attribute list. + * 5. Set attribute’s element to element. + */ + element._attributeList._asArray().push(attribute); + attribute._element = element; + // mark that the document has namespaces + if (!element._nodeDocument._hasNamespaces && (attribute._namespace !== null || + attribute._namespacePrefix !== null || attribute._localName === "xmlns")) { + element._nodeDocument._hasNamespaces = true; + } +} +exports.element_append = element_append; +/** + * Removes an attribute from an element node. + * + * @param attribute - an attribute + * @param element - an element to receive the attribute + */ +function element_remove(attribute, element) { + /** + * 1. Queue an attribute mutation record for element with attribute’s + * local name, attribute’s namespace, and attribute’s value. + */ + if (dom_1.dom.features.mutationObservers) { + MutationObserverAlgorithm_1.observer_queueAttributeMutationRecord(element, attribute._localName, attribute._namespace, attribute._value); + } + /** + * 2. If element is custom, then enqueue a custom element callback reaction + * with element, callback name "attributeChangedCallback", and an argument + * list containing attribute’s local name, attribute’s value, null, + * and attribute’s namespace. + */ + if (dom_1.dom.features.customElements) { + if (util_1.Guard.isCustomElementNode(element)) { + CustomElementAlgorithm_1.customElement_enqueueACustomElementCallbackReaction(element, "attributeChangedCallback", [attribute._localName, attribute._value, null, attribute._namespace]); + } + } + /** + * 3. Run the attribute change steps with element, attribute’s local name, + * attribute’s value, null, and attribute’s namespace. + */ + if (dom_1.dom.features.steps) { + DOMAlgorithm_1.dom_runAttributeChangeSteps(element, attribute._localName, attribute._value, null, attribute._namespace); + } + /** + * 3. Remove attribute from element’s attribute list. + * 5. Set attribute’s element to null. + */ + const index = element._attributeList._asArray().indexOf(attribute); + element._attributeList._asArray().splice(index, 1); + attribute._element = null; +} +exports.element_remove = element_remove; +/** + * Replaces an attribute with another of an element node. + * + * @param oldAttr - old attribute + * @param newAttr - new attribute + * @param element - an element to receive the attribute + */ +function element_replace(oldAttr, newAttr, element) { + /** + * 1. Queue an attribute mutation record for element with oldAttr’s + * local name, oldAttr’s namespace, and oldAttr’s value. + */ + if (dom_1.dom.features.mutationObservers) { + MutationObserverAlgorithm_1.observer_queueAttributeMutationRecord(element, oldAttr._localName, oldAttr._namespace, oldAttr._value); + } + /** + * 2. If element is custom, then enqueue a custom element callback reaction + * with element, callback name "attributeChangedCallback", and an argument + * list containing oldAttr’s local name, oldAttr’s value, newAttr’s value, + * and oldAttr’s namespace. + */ + if (dom_1.dom.features.customElements) { + if (util_1.Guard.isCustomElementNode(element)) { + CustomElementAlgorithm_1.customElement_enqueueACustomElementCallbackReaction(element, "attributeChangedCallback", [oldAttr._localName, oldAttr._value, newAttr._value, oldAttr._namespace]); + } + } + /** + * 3. Run the attribute change steps with element, oldAttr’s local name, + * oldAttr’s value, newAttr’s value, and oldAttr’s namespace. + */ + if (dom_1.dom.features.steps) { + DOMAlgorithm_1.dom_runAttributeChangeSteps(element, oldAttr._localName, oldAttr._value, newAttr._value, oldAttr._namespace); + } + /** + * 4. Replace oldAttr by newAttr in element’s attribute list. + * 5. Set oldAttr’s element to null. + * 6. Set newAttr’s element to element. + */ + const index = element._attributeList._asArray().indexOf(oldAttr); + if (index !== -1) { + element._attributeList._asArray()[index] = newAttr; + } + oldAttr._element = null; + newAttr._element = element; + // mark that the document has namespaces + if (!element._nodeDocument._hasNamespaces && (newAttr._namespace !== null || + newAttr._namespacePrefix !== null || newAttr._localName === "xmlns")) { + element._nodeDocument._hasNamespaces = true; + } +} +exports.element_replace = element_replace; +/** + * Retrieves an attribute with the given name from an element node. + * + * @param qualifiedName - an attribute name + * @param element - an element to receive the attribute + */ +function element_getAnAttributeByName(qualifiedName, element) { + /** + * 1. If element is in the HTML namespace and its node document is an HTML + * document, then set qualifiedName to qualifiedName in ASCII lowercase. + * 2. Return the first attribute in element’s attribute list whose qualified + * name is qualifiedName, and null otherwise. + */ + if (element._namespace === infra_1.namespace.HTML && element._nodeDocument._type === "html") { + qualifiedName = qualifiedName.toLowerCase(); + } + return element._attributeList._asArray().find(attr => attr._qualifiedName === qualifiedName) || null; +} +exports.element_getAnAttributeByName = element_getAnAttributeByName; +/** + * Retrieves an attribute with the given namespace and local name from an + * element node. + * + * @param namespace - an attribute namespace + * @param localName - an attribute local name + * @param element - an element to receive the attribute + */ +function element_getAnAttributeByNamespaceAndLocalName(namespace, localName, element) { + /** + * 1. If namespace is the empty string, set it to null. + * 2. Return the attribute in element’s attribute list whose namespace is + * namespace and local name is localName, if any, and null otherwise. + */ + const ns = namespace || null; + return element._attributeList._asArray().find(attr => attr._namespace === ns && attr._localName === localName) || null; +} +exports.element_getAnAttributeByNamespaceAndLocalName = element_getAnAttributeByNamespaceAndLocalName; +/** + * Retrieves an attribute's value with the given name namespace and local + * name from an element node. + * + * @param element - an element to receive the attribute + * @param localName - an attribute local name + * @param namespace - an attribute namespace + */ +function element_getAnAttributeValue(element, localName, namespace = '') { + /** + * 1. Let attr be the result of getting an attribute given namespace, + * localName, and element. + * 2. If attr is null, then return the empty string. + * 3. Return attr’s value. + */ + const attr = element_getAnAttributeByNamespaceAndLocalName(namespace, localName, element); + if (attr === null) + return ''; + else + return attr._value; +} +exports.element_getAnAttributeValue = element_getAnAttributeValue; +/** + * Sets an attribute of an element node. + * + * @param attr - an attribute + * @param element - an element to receive the attribute + */ +function element_setAnAttribute(attr, element) { + /** + * 1. If attr’s element is neither null nor element, throw an + * "InUseAttributeError" DOMException. + * 2. Let oldAttr be the result of getting an attribute given attr’s + * namespace, attr’s local name, and element. + * 3. If oldAttr is attr, return attr. + * 4. If oldAttr is non-null, replace it by attr in element. + * 5. Otherwise, append attr to element. + * 6. Return oldAttr. + */ + if (attr._element !== null && attr._element !== element) + throw new DOMException_1.InUseAttributeError(`This attribute already exists in the document: ${attr._qualifiedName} as a child of ${attr._element._qualifiedName}.`); + const oldAttr = element_getAnAttributeByNamespaceAndLocalName(attr._namespace || '', attr._localName, element); + if (oldAttr === attr) + return attr; + if (oldAttr !== null) { + element_replace(oldAttr, attr, element); + } + else { + element_append(attr, element); + } + return oldAttr; +} +exports.element_setAnAttribute = element_setAnAttribute; +/** + * Sets an attribute's value of an element node. + * + * @param element - an element to receive the attribute + * @param localName - an attribute local name + * @param value - an attribute value + * @param prefix - an attribute prefix + * @param namespace - an attribute namespace + */ +function element_setAnAttributeValue(element, localName, value, prefix = null, namespace = null) { + /** + * 1. If prefix is not given, set it to null. + * 2. If namespace is not given, set it to null. + * 3. Let attribute be the result of getting an attribute given namespace, + * localName, and element. + * 4. If attribute is null, create an attribute whose namespace is + * namespace, namespace prefix is prefix, local name is localName, value + * is value, and node document is element’s node document, then append this + * attribute to element, and then return. + * 5. Change attribute from element to value. + */ + const attribute = element_getAnAttributeByNamespaceAndLocalName(namespace || '', localName, element); + if (attribute === null) { + const newAttr = CreateAlgorithm_1.create_attr(element._nodeDocument, localName); + newAttr._namespace = namespace; + newAttr._namespacePrefix = prefix; + newAttr._value = value; + element_append(newAttr, element); + return; + } + element_change(attribute, element, value); +} +exports.element_setAnAttributeValue = element_setAnAttributeValue; +/** + * Removes an attribute with the given name from an element node. + * + * @param qualifiedName - an attribute name + * @param element - an element to receive the attribute + */ +function element_removeAnAttributeByName(qualifiedName, element) { + /** + * 1. Let attr be the result of getting an attribute given qualifiedName + * and element. + * 2. If attr is non-null, remove it from element. + * 3. Return attr. + */ + const attr = element_getAnAttributeByName(qualifiedName, element); + if (attr !== null) { + element_remove(attr, element); + } + return attr; +} +exports.element_removeAnAttributeByName = element_removeAnAttributeByName; +/** + * Removes an attribute with the given namespace and local name from an + * element node. + * + * @param namespace - an attribute namespace + * @param localName - an attribute local name + * @param element - an element to receive the attribute + */ +function element_removeAnAttributeByNamespaceAndLocalName(namespace, localName, element) { + /** + * 1. Let attr be the result of getting an attribute given namespace, localName, and element. + * 2. If attr is non-null, remove it from element. + * 3. Return attr. + */ + const attr = element_getAnAttributeByNamespaceAndLocalName(namespace, localName, element); + if (attr !== null) { + element_remove(attr, element); + } + return attr; +} +exports.element_removeAnAttributeByNamespaceAndLocalName = element_removeAnAttributeByNamespaceAndLocalName; +/** + * Creates an element node. + * See: https://dom.spec.whatwg.org/#concept-create-element. + * + * @param document - the document owning the element + * @param localName - local name + * @param namespace - element namespace + * @param prefix - namespace prefix + * @param is - the "is" value + * @param synchronousCustomElementsFlag - synchronous custom elements flag + */ +function element_createAnElement(document, localName, namespace, prefix = null, is = null, synchronousCustomElementsFlag = false) { + /** + * 1. If prefix was not given, let prefix be null. + * 2. If is was not given, let is be null. + * 3. Let result be null. + */ + let result = null; + if (!dom_1.dom.features.customElements) { + result = CreateAlgorithm_1.create_element(document, localName, namespace, prefix); + result._customElementState = "uncustomized"; + result._customElementDefinition = null; + result._is = is; + return result; + } + /** + * 4. Let definition be the result of looking up a custom element definition + * given document, namespace, localName, and is. + */ + const definition = CustomElementAlgorithm_1.customElement_lookUpACustomElementDefinition(document, namespace, localName, is); + if (definition !== null && definition.name !== definition.localName) { + /** + * 5. If definition is non-null, and definition’s name is not equal to + * its local name (i.e., definition represents a customized built-in + * element), then: + * 5.1. Let interface be the element interface for localName and the HTML + * namespace. + * 5.2. Set result to a new element that implements interface, with no + * attributes, namespace set to the HTML namespace, namespace prefix + * set to prefix, local name set to localName, custom element state set + * to "undefined", custom element definition set to null, is value set + * to is, and node document set to document. + * 5.3. If the synchronous custom elements flag is set, upgrade element + * using definition. + * 5.4. Otherwise, enqueue a custom element upgrade reaction given result + * and definition. + */ + const elemenInterface = DocumentAlgorithm_1.document_elementInterface(localName, infra_1.namespace.HTML); + result = new elemenInterface(); + result._localName = localName; + result._namespace = infra_1.namespace.HTML; + result._namespacePrefix = prefix; + result._customElementState = "undefined"; + result._customElementDefinition = null; + result._is = is; + result._nodeDocument = document; + if (synchronousCustomElementsFlag) { + CustomElementAlgorithm_1.customElement_upgrade(definition, result); + } + else { + CustomElementAlgorithm_1.customElement_enqueueACustomElementUpgradeReaction(result, definition); + } + } + else if (definition !== null) { + /** + * 6. Otherwise, if definition is non-null, then: + */ + if (synchronousCustomElementsFlag) { + /** + * 6.1. If the synchronous custom elements flag is set, then run these + * steps while catching any exceptions: + */ + try { + /** + * 6.1.1. Let C be definition’s constructor. + * 6.1.2. Set result to the result of constructing C, with no arguments. + * 6.1.3. Assert: result’s custom element state and custom element definition + * are initialized. + * 6.1.4. Assert: result’s namespace is the HTML namespace. + * _Note:_ IDL enforces that result is an HTMLElement object, which all + * use the HTML namespace. + */ + const C = definition.constructor; + const result = new C(); + console.assert(result._customElementState !== undefined); + console.assert(result._customElementDefinition !== undefined); + console.assert(result._namespace === infra_1.namespace.HTML); + /** + * 6.1.5. If result’s attribute list is not empty, then throw a + * "NotSupportedError" DOMException. + * 6.1.6. If result has children, then throw a "NotSupportedError" + * DOMException. + * 6.1.7. If result’s parent is not null, then throw a + * "NotSupportedError" DOMException. + * 6.1.8. If result’s node document is not document, then throw a + * "NotSupportedError" DOMException. + * 6.1.9. If result’s local name is not equal to localName, then throw + * a "NotSupportedError" DOMException. + */ + if (result._attributeList.length !== 0) + throw new DOMException_1.NotSupportedError("Custom element already has attributes."); + if (result._children.size !== 0) + throw new DOMException_1.NotSupportedError("Custom element already has child nodes."); + if (result._parent !== null) + throw new DOMException_1.NotSupportedError("Custom element already has a parent node."); + if (result._nodeDocument !== document) + throw new DOMException_1.NotSupportedError("Custom element is already in a document."); + if (result._localName !== localName) + throw new DOMException_1.NotSupportedError("Custom element has a different local name."); + /** + * 6.1.10. Set result’s namespace prefix to prefix. + * 6.1.11. Set result’s is value to null. + */ + result._namespacePrefix = prefix; + result._is = null; + } + catch (e) { + /** + * If any of these steps threw an exception, then: + * - Report the exception. + * - Set result to a new element that implements the HTMLUnknownElement + * interface, with no attributes, namespace set to the HTML namespace, + * namespace prefix set to prefix, local name set to localName, custom + * element state set to "failed", custom element definition set to null, + * is value set to null, and node document set to document. + */ + // TODO: Report the exception + result = CreateAlgorithm_1.create_htmlUnknownElement(document, localName, infra_1.namespace.HTML, prefix); + result._customElementState = "failed"; + result._customElementDefinition = null; + result._is = null; + } + } + else { + /** + * 6.2. Otherwise: + * 6.2.1. Set result to a new element that implements the HTMLElement + * interface, with no attributes, namespace set to the HTML namespace, + * namespace prefix set to prefix, local name set to localName, custom + * element state set to "undefined", custom element definition set to + * null, is value set to null, and node document set to document. + * 6.2.2. Enqueue a custom element upgrade reaction given result and + * definition. + */ + result = CreateAlgorithm_1.create_htmlElement(document, localName, infra_1.namespace.HTML, prefix); + result._customElementState = "undefined"; + result._customElementDefinition = null; + result._is = null; + CustomElementAlgorithm_1.customElement_enqueueACustomElementUpgradeReaction(result, definition); + } + } + else { + /** + * 7. Otherwise: + * 7.1. Let interface be the element interface for localName and + * namespace. + * 7.2. Set result to a new element that implements interface, with no + * attributes, namespace set to namespace, namespace prefix set to prefix, + * local name set to localName, custom element state set to + * "uncustomized", custom element definition set to null, is value set to + * is, and node document set to document. + */ + const elementInterface = DocumentAlgorithm_1.document_elementInterface(localName, namespace); + result = new elementInterface(); + result._localName = localName; + result._namespace = namespace; + result._namespacePrefix = prefix; + result._customElementState = "uncustomized"; + result._customElementDefinition = null; + result._is = is; + result._nodeDocument = document; + /** + * 7.3. If namespace is the HTML namespace, and either localName is a + * valid custom element name or is is non-null, then set result’s + * custom element state to "undefined". + */ + if (namespace === infra_1.namespace.HTML && (is !== null || + CustomElementAlgorithm_1.customElement_isValidCustomElementName(localName))) { + result._customElementState = "undefined"; + } + } + /* istanbul ignore next */ + if (result === null) { + throw new Error("Unable to create element."); + } + /** + * 8. Returns result + */ + return result; +} +exports.element_createAnElement = element_createAnElement; +/** + * Inserts a new node adjacent to this element. + * + * @param element - a reference element + * @param where - a string defining where to insert the element node. + * - `beforebegin` before this element itself. + * - `afterbegin` before the first child. + * - `beforeend` after the last child. + * - `afterend` after this element itself. + * @param node - node to insert + */ +function element_insertAdjacent(element, where, node) { + /** + * - "beforebegin" + * If element’s parent is null, return null. + * Return the result of pre-inserting node into element’s parent before + * element. + * - "afterbegin" + * Return the result of pre-inserting node into element before element’s + * first child. + * - "beforeend" + * Return the result of pre-inserting node into element before null. + * - "afterend" + * If element’s parent is null, return null. + * Return the result of pre-inserting node into element’s parent before element’s next sibling. + * - Otherwise + * Throw a "SyntaxError" DOMException. + */ + switch (where.toLowerCase()) { + case 'beforebegin': + if (element._parent === null) + return null; + return MutationAlgorithm_1.mutation_preInsert(node, element._parent, element); + case 'afterbegin': + return MutationAlgorithm_1.mutation_preInsert(node, element, element._firstChild); + case 'beforeend': + return MutationAlgorithm_1.mutation_preInsert(node, element, null); + case 'afterend': + if (element._parent === null) + return null; + return MutationAlgorithm_1.mutation_preInsert(node, element._parent, element._nextSibling); + default: + throw new DOMException_1.SyntaxError(`Invalid 'where' argument. "beforebegin", "afterbegin", "beforeend" or "afterend" expected`); + } +} +exports.element_insertAdjacent = element_insertAdjacent; +//# sourceMappingURL=ElementAlgorithm.js.map + +/***/ }), + +/***/ 35: +/***/ (function(__unusedmodule, exports) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * Represents the base class of `Error` objects used by this module. + */ +class DOMException extends Error { + /** + * + * @param name - message name + * @param message - error message + */ + constructor(name, message = "") { + super(message); + this.name = name; + } +} +exports.DOMException = DOMException; +class DOMStringSizeError extends DOMException { + /** + * @param message - error message + */ + constructor(message = "") { + super("DOMStringSizeError", message); + } +} +exports.DOMStringSizeError = DOMStringSizeError; +class WrongDocumentError extends DOMException { + /** + * @param message - error message + */ + constructor(message = "") { + super("WrongDocumentError", "The object is in the wrong document. " + message); + } +} +exports.WrongDocumentError = WrongDocumentError; +class NoDataAllowedError extends DOMException { + /** + * @param message - error message + */ + constructor(message = "") { + super("NoDataAllowedError", message); + } +} +exports.NoDataAllowedError = NoDataAllowedError; +class NoModificationAllowedError extends DOMException { + /** + * @param message - error message + */ + constructor(message = "") { + super("NoModificationAllowedError", "The object can not be modified. " + message); + } +} +exports.NoModificationAllowedError = NoModificationAllowedError; +class NotSupportedError extends DOMException { + /** + * @param message - error message + */ + constructor(message = "") { + super("NotSupportedError", "The operation is not supported. " + message); + } +} +exports.NotSupportedError = NotSupportedError; +class InUseAttributeError extends DOMException { + /** + * @param message - error message + */ + constructor(message = "") { + super("InUseAttributeError", message); + } +} +exports.InUseAttributeError = InUseAttributeError; +class InvalidStateError extends DOMException { + /** + * @param message - error message + */ + constructor(message = "") { + super("InvalidStateError", "The object is in an invalid state. " + message); + } +} +exports.InvalidStateError = InvalidStateError; +class InvalidModificationError extends DOMException { + /** + * @param message - error message + */ + constructor(message = "") { + super("InvalidModificationError", "The object can not be modified in this way. " + message); + } +} +exports.InvalidModificationError = InvalidModificationError; +class NamespaceError extends DOMException { + /** + * @param message - error message + */ + constructor(message = "") { + super("NamespaceError", "The operation is not allowed by Namespaces in XML. [XMLNS] " + message); + } +} +exports.NamespaceError = NamespaceError; +class InvalidAccessError extends DOMException { + /** + * @param message - error message + */ + constructor(message = "") { + super("InvalidAccessError", "The object does not support the operation or argument. " + message); + } +} +exports.InvalidAccessError = InvalidAccessError; +class ValidationError extends DOMException { + /** + * @param message - error message + */ + constructor(message = "") { + super("ValidationError", message); + } +} +exports.ValidationError = ValidationError; +class TypeMismatchError extends DOMException { + /** + * @param message - error message + */ + constructor(message = "") { + super("TypeMismatchError", message); + } +} +exports.TypeMismatchError = TypeMismatchError; +class SecurityError extends DOMException { + /** + * @param message - error message + */ + constructor(message = "") { + super("SecurityError", "The operation is insecure. " + message); + } +} +exports.SecurityError = SecurityError; +class NetworkError extends DOMException { + /** + * @param message - error message + */ + constructor(message = "") { + super("NetworkError", "A network error occurred. " + message); + } +} +exports.NetworkError = NetworkError; +class AbortError extends DOMException { + /** + * @param message - error message + */ + constructor(message = "") { + super("AbortError", "The operation was aborted. " + message); + } +} +exports.AbortError = AbortError; +class URLMismatchError extends DOMException { + /** + * @param message - error message + */ + constructor(message = "") { + super("URLMismatchError", "The given URL does not match another URL. " + message); + } +} +exports.URLMismatchError = URLMismatchError; +class QuotaExceededError extends DOMException { + /** + * @param message - error message + */ + constructor(message = "") { + super("QuotaExceededError", "The quota has been exceeded. " + message); + } +} +exports.QuotaExceededError = QuotaExceededError; +class TimeoutError extends DOMException { + /** + * @param message - error message + */ + constructor(message = "") { + super("TimeoutError", "The operation timed out. " + message); + } +} +exports.TimeoutError = TimeoutError; +class InvalidNodeTypeError extends DOMException { + /** + * @param message - error message + */ + constructor(message = "") { + super("InvalidNodeTypeError", "The supplied node is incorrect or has an incorrect ancestor for this operation. " + message); + } +} +exports.InvalidNodeTypeError = InvalidNodeTypeError; +class DataCloneError extends DOMException { + /** + * @param message - error message + */ + constructor(message = "") { + super("DataCloneError", "The object can not be cloned. " + message); + } +} +exports.DataCloneError = DataCloneError; +class NotImplementedError extends DOMException { + /** + * @param message - error message + */ + constructor(message = "") { + super("NotImplementedError", "The DOM method is not implemented by this module. " + message); + } +} +exports.NotImplementedError = NotImplementedError; +class HierarchyRequestError extends DOMException { + /** + * @param message - error message + */ + constructor(message = "") { + super("HierarchyRequestError", "The operation would yield an incorrect node tree. " + message); + } +} +exports.HierarchyRequestError = HierarchyRequestError; +class NotFoundError extends DOMException { + /** + * @param message - error message + */ + constructor(message = "") { + super("NotFoundError", "The object can not be found here. " + message); + } +} +exports.NotFoundError = NotFoundError; +class IndexSizeError extends DOMException { + /** + * @param message - error message + */ + constructor(message = "") { + super("IndexSizeError", "The index is not in the allowed range. " + message); + } +} +exports.IndexSizeError = IndexSizeError; +class SyntaxError extends DOMException { + /** + * @param message - error message + */ + constructor(message = "") { + super("SyntaxError", "The string did not match the expected pattern. " + message); + } +} +exports.SyntaxError = SyntaxError; +class InvalidCharacterError extends DOMException { + /** + * @param message - error message + */ + constructor(message = "") { + super("InvalidCharacterError", "The string contains invalid characters. " + message); + } +} +exports.InvalidCharacterError = InvalidCharacterError; +//# sourceMappingURL=DOMException.js.map + +/***/ }), + +/***/ 42: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +var ObjectCache_1 = __webpack_require__(568); +exports.ObjectCache = ObjectCache_1.ObjectCache; +var CompareCache_1 = __webpack_require__(938); +exports.CompareCache = CompareCache_1.CompareCache; +/** + * Applies the mixin to a given class. + * + * @param baseClass - class to receive the mixin + * @param mixinClass - mixin class + * @param overrides - an array with names of function overrides. Base class + * functions whose names are in this array will be kept by prepending an + * underscore to their names. + */ +function applyMixin(baseClass, mixinClass, ...overrides) { + Object.getOwnPropertyNames(mixinClass.prototype).forEach(name => { + if (overrides.includes(name)) { + const orgPropDesc = Object.getOwnPropertyDescriptor(baseClass.prototype, name); + /* istanbul ignore else */ + if (orgPropDesc) { + Object.defineProperty(baseClass.prototype, "_" + name, orgPropDesc); + } + } + const propDesc = Object.getOwnPropertyDescriptor(mixinClass.prototype, name); + /* istanbul ignore else */ + if (propDesc) { + Object.defineProperty(baseClass.prototype, name, propDesc); + } + }); +} +exports.applyMixin = applyMixin; +/** + * Applies default values to the given object. + * + * @param obj - an object + * @param defaults - an object with default values + * @param overwrite - if set to `true` defaults object always overwrites object + * values, whether they are `undefined` or not. + */ +function applyDefaults(obj, defaults, overwrite = false) { + const result = clone(obj || {}); + for (const [key, val] of forEachObject(defaults)) { + if (isObject(val)) { + result[key] = applyDefaults(result[key], val); + } + else if (overwrite || result[key] === undefined) { + result[key] = val; + } + } + return result; +} +exports.applyDefaults = applyDefaults; +/** + * Iterates over items pairs of an array. + * + * @param arr - array to iterate + */ +function* forEachArray(arr) { + yield* arr; +} +exports.forEachArray = forEachArray; +/** + * Iterates over key/value pairs of a map or object. + * + * @param obj - map or object to iterate + */ +function* forEachObject(obj) { + if (isMap(obj)) { + yield* obj; + } + else { + for (const key in obj) { + /* istanbul ignore next */ + if (!obj.hasOwnProperty(key)) + continue; + yield [key, obj[key]]; + } + } +} +exports.forEachObject = forEachObject; +/** + * Returns the number of entries in a map or object. + * + * @param obj - map or object + */ +function objectLength(obj) { + if (isMap(obj)) { + return obj.size; + } + else { + return Object.keys(obj).length; + } +} +exports.objectLength = objectLength; +/** + * Gets the value of a key from a map or object. + * + * @param obj - map or object + * @param key - the key to retrieve + */ +function getObjectValue(obj, key) { + if (isMap(obj)) { + return obj.get(key); + } + else { + return obj[key]; + } +} +exports.getObjectValue = getObjectValue; +/** + * Removes a property from a map or object. + * + * @param obj - map or object + * @param key - the key to remove + */ +function removeObjectValue(obj, key) { + if (isMap(obj)) { + obj.delete(key); + } + else { + delete obj[key]; + } +} +exports.removeObjectValue = removeObjectValue; +/** + * Deep clones the given object. + * + * @param obj - an object + */ +function clone(obj) { + if (isFunction(obj)) { + return obj; + } + else if (isArray(obj)) { + const result = []; + for (const item of obj) { + result.push(clone(item)); + } + return result; + } + else if (isObject(obj)) { + const result = {}; + for (const key in obj) { + /* istanbul ignore next */ + if (obj.hasOwnProperty(key)) { + const val = obj[key]; + result[key] = clone(val); + } + } + return result; + } + else { + return obj; + } +} +exports.clone = clone; +/** + * Type guard for boolean types + * + * @param x - a variable to type check + */ +function isBoolean(x) { + return typeof x === "boolean"; +} +exports.isBoolean = isBoolean; +/** + * Type guard for numeric types + * + * @param x - a variable to type check + */ +function isNumber(x) { + return typeof x === "number"; +} +exports.isNumber = isNumber; +/** + * Type guard for strings + * + * @param x - a variable to type check + */ +function isString(x) { + return typeof x === "string"; +} +exports.isString = isString; +/** + * Type guard for function objects + * + * @param x - a variable to type check + */ +function isFunction(x) { + return !!x && Object.prototype.toString.call(x) === '[object Function]'; +} +exports.isFunction = isFunction; +/** + * Type guard for JS objects + * + * _Note:_ Functions are objects too + * + * @param x - a variable to type check + */ +function isObject(x) { + const type = typeof x; + return !!x && (type === 'function' || type === 'object'); +} +exports.isObject = isObject; +/** + * Type guard for arrays + * + * @param x - a variable to type check + */ +function isArray(x) { + return Array.isArray(x); +} +exports.isArray = isArray; +/** + * Type guard for maps. + * + * @param x - a variable to check + */ +function isMap(x) { + return x instanceof Map; +} +exports.isMap = isMap; +/** + * Determines if `x` is an empty Array or an Object with no own properties. + * + * @param x - a variable to check + */ +function isEmpty(x) { + if (isArray(x)) { + return !x.length; + } + else if (isObject(x)) { + for (const key in x) { + if (x.hasOwnProperty(key)) { + return false; + } + } + return true; + } + return false; +} +exports.isEmpty = isEmpty; +/** + * Determines if `x` is a plain Object. + * + * @param x - a variable to check + */ +function isPlainObject(x) { + if (isObject(x)) { + const proto = Object.getPrototypeOf(x); + const ctor = proto.constructor; + return proto && ctor && + (typeof ctor === 'function') && (ctor instanceof ctor) && + (Function.prototype.toString.call(ctor) === Function.prototype.toString.call(Object)); + } + return false; +} +exports.isPlainObject = isPlainObject; +/** + * Determines if `x` is an iterable Object. + * + * @param x - a variable to check + */ +function isIterable(x) { + return x && (typeof x[Symbol.iterator] === 'function'); +} +exports.isIterable = isIterable; +/** + * Gets the primitive value of an object. + */ +function getValue(obj) { + if (isFunction(obj.valueOf)) { + return obj.valueOf(); + } + else { + return obj; + } +} +exports.getValue = getValue; +//# sourceMappingURL=index.js.map + +/***/ }), + +/***/ 43: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const NodeImpl_1 = __webpack_require__(935); +const algorithm_1 = __webpack_require__(163); +/** + * Represents a generic text node. + */ +class CharacterDataImpl extends NodeImpl_1.NodeImpl { + /** + * Initializes a new instance of `CharacterData`. + * + * @param data - the text content + */ + constructor(data) { + super(); + this._data = data; + } + /** @inheritdoc */ + get data() { return this._data; } + set data(value) { + algorithm_1.characterData_replaceData(this, 0, this._data.length, value); + } + /** @inheritdoc */ + get length() { return this._data.length; } + /** @inheritdoc */ + substringData(offset, count) { + /** + * The substringData(offset, count) method, when invoked, must return the + * result of running substring data with node context object, offset offset, and count count. + */ + return algorithm_1.characterData_substringData(this, offset, count); + } + /** @inheritdoc */ + appendData(data) { + /** + * The appendData(data) method, when invoked, must replace data with node + * context object, offset context object’s length, count 0, and data data. + */ + return algorithm_1.characterData_replaceData(this, this._data.length, 0, data); + } + /** @inheritdoc */ + insertData(offset, data) { + /** + * The insertData(offset, data) method, when invoked, must replace data with + * node context object, offset offset, count 0, and data data. + */ + algorithm_1.characterData_replaceData(this, offset, 0, data); + } + /** @inheritdoc */ + deleteData(offset, count) { + /** + * The deleteData(offset, count) method, when invoked, must replace data + * with node context object, offset offset, count count, and data the + * empty string. + */ + algorithm_1.characterData_replaceData(this, offset, count, ''); + } + /** @inheritdoc */ + replaceData(offset, count, data) { + /** + * The replaceData(offset, count, data) method, when invoked, must replace + * data with node context object, offset offset, count count, and data data. + */ + algorithm_1.characterData_replaceData(this, offset, count, data); + } + // MIXIN: NonDocumentTypeChildNode + /* istanbul ignore next */ + get previousElementSibling() { throw new Error("Mixin: NonDocumentTypeChildNode not implemented."); } + /* istanbul ignore next */ + get nextElementSibling() { throw new Error("Mixin: NonDocumentTypeChildNode not implemented."); } + // MIXIN: ChildNode + /* istanbul ignore next */ + before(...nodes) { throw new Error("Mixin: ChildNode not implemented."); } + /* istanbul ignore next */ + after(...nodes) { throw new Error("Mixin: ChildNode not implemented."); } + /* istanbul ignore next */ + replaceWith(...nodes) { throw new Error("Mixin: ChildNode not implemented."); } + /* istanbul ignore next */ + remove() { throw new Error("Mixin: ChildNode not implemented."); } +} +exports.CharacterDataImpl = CharacterDataImpl; +//# sourceMappingURL=CharacterDataImpl.js.map + +/***/ }), + +/***/ 54: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const OrderedSetAlgorithm_1 = __webpack_require__(146); +const DOMAlgorithm_1 = __webpack_require__(304); +const ElementAlgorithm_1 = __webpack_require__(33); +/** + * Validates a given token against the supported tokens defined for the given + * token lists' associated attribute. + * + * @param tokenList - a token list + * @param token - a token + */ +function tokenList_validationSteps(tokenList, token) { + /** + * 1. If the associated attribute’s local name does not define supported + * tokens, throw a TypeError. + * 2. Let lowercase token be a copy of token, in ASCII lowercase. + * 3. If lowercase token is present in supported tokens, return true. + * 4. Return false. + */ + if (!DOMAlgorithm_1.dom_hasSupportedTokens(tokenList._attribute._localName)) { + throw new TypeError(`There are no supported tokens defined for attribute name: '${tokenList._attribute._localName}'.`); + } + return DOMAlgorithm_1.dom_getSupportedTokens(tokenList._attribute._localName).has(token.toLowerCase()); +} +exports.tokenList_validationSteps = tokenList_validationSteps; +/** + * Updates the value of the token lists' associated attribute. + * + * @param tokenList - a token list + */ +function tokenList_updateSteps(tokenList) { + /** + * 1. If the associated element does not have an associated attribute and + * token set is empty, then return. + * 2. Set an attribute value for the associated element using associated + * attribute’s local name and the result of running the ordered set + * serializer for token set. + */ + if (!tokenList._element.hasAttribute(tokenList._attribute._localName) && + tokenList._tokenSet.size === 0) { + return; + } + ElementAlgorithm_1.element_setAnAttributeValue(tokenList._element, tokenList._attribute._localName, OrderedSetAlgorithm_1.orderedSet_serialize(tokenList._tokenSet)); +} +exports.tokenList_updateSteps = tokenList_updateSteps; +/** + * Gets the value of the token lists' associated attribute. + * + * @param tokenList - a token list + */ +function tokenList_serializeSteps(tokenList) { + /** + * A DOMTokenList object’s serialize steps are to return the result of + * running get an attribute value given the associated element and the + * associated attribute’s local name. + */ + return ElementAlgorithm_1.element_getAnAttributeValue(tokenList._element, tokenList._attribute._localName); +} +exports.tokenList_serializeSteps = tokenList_serializeSteps; +//# sourceMappingURL=DOMTokenListAlgorithm.js.map + +/***/ }), + +/***/ 60: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const util_1 = __webpack_require__(337); +const CreateAlgorithm_1 = __webpack_require__(86); +/** + * Converts the given nodes or strings into a node (if `nodes` has + * only one element) or a document fragment. + * + * @param nodes - the array of nodes or strings, + * @param document - owner document + */ +function parentNode_convertNodesIntoANode(nodes, document) { + /** + * 1. Let node be null. + * 2. Replace each string in nodes with a new Text node whose data is the + * string and node document is document. + */ + let node = null; + for (let i = 0; i < nodes.length; i++) { + const item = nodes[i]; + if (util_1.isString(item)) { + const text = CreateAlgorithm_1.create_text(document, item); + nodes[i] = text; + } + } + /** + * 3. If nodes contains one node, set node to that node. + * 4. Otherwise, set node to a new DocumentFragment whose node document is + * document, and then append each node in nodes, if any, to it. + */ + if (nodes.length === 1) { + node = nodes[0]; + } + else { + node = CreateAlgorithm_1.create_documentFragment(document); + const ns = node; + for (const item of nodes) { + ns.appendChild(item); + } + } + /** + * 5. Return node. + */ + return node; +} +exports.parentNode_convertNodesIntoANode = parentNode_convertNodesIntoANode; +//# sourceMappingURL=ParentNodeAlgorithm.js.map + +/***/ }), + +/***/ 68: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +var FixedSizeSet_1 = __webpack_require__(319); +exports.FixedSizeSet = FixedSizeSet_1.FixedSizeSet; +var ObjectCache_1 = __webpack_require__(973); +exports.ObjectCache = ObjectCache_1.ObjectCache; +var CompareCache_1 = __webpack_require__(441); +exports.CompareCache = CompareCache_1.CompareCache; +var Lazy_1 = __webpack_require__(271); +exports.Lazy = Lazy_1.Lazy; +/** + * Applies the mixin to a given class. + * + * @param baseClass - class to receive the mixin + * @param mixinClass - mixin class + * @param overrides - an array with names of function overrides. Base class + * functions whose names are in this array will be kept by prepending an + * underscore to their names. + */ +function applyMixin(baseClass, mixinClass, ...overrides) { + Object.getOwnPropertyNames(mixinClass.prototype).forEach(name => { + if (overrides.includes(name)) { + const orgPropDesc = Object.getOwnPropertyDescriptor(baseClass.prototype, name); + /* istanbul ignore else */ + if (orgPropDesc) { + Object.defineProperty(baseClass.prototype, "_" + name, orgPropDesc); + } + } + const propDesc = Object.getOwnPropertyDescriptor(mixinClass.prototype, name); + /* istanbul ignore else */ + if (propDesc) { + Object.defineProperty(baseClass.prototype, name, propDesc); + } + }); +} +exports.applyMixin = applyMixin; +/** + * Applies default values to the given object. + * + * @param obj - an object + * @param defaults - an object with default values + * @param overwrite - if set to `true` defaults object always overwrites object + * values, whether they are `undefined` or not. + */ +function applyDefaults(obj, defaults, overwrite = false) { + const result = clone(obj || {}); + forEachObject(defaults, (key, val) => { + if (isObject(val)) { + result[key] = applyDefaults(result[key], val); + } + else if (overwrite || result[key] === undefined) { + result[key] = val; + } + }); + return result; +} +exports.applyDefaults = applyDefaults; +/** + * Iterates over items of an array or set. + * + * @param arr - array or set to iterate + * @param callback - a callback function which receives each array item as its + * single argument + * @param thisArg - the value of this inside callback + */ +function forEachArray(arr, callback, thisArg) { + arr.forEach(callback, thisArg); +} +exports.forEachArray = forEachArray; +/** + * Iterates over key/value pairs of a map or object. + * + * @param obj - map or object to iterate + * @param callback - a callback function which receives object key as its first + * argument and object value as its second argument + * @param thisArg - the value of this inside callback + */ +function forEachObject(obj, callback, thisArg) { + if (isMap(obj)) { + obj.forEach((value, key) => callback.call(thisArg, key, value)); + } + else { + for (const key in obj) { + /* istanbul ignore else */ + if (obj.hasOwnProperty(key)) { + callback.call(thisArg, key, obj[key]); + } + } + } +} +exports.forEachObject = forEachObject; +/** + * Returns the number of entries in an array or set. + * + * @param arr - array or set + */ +function arrayLength(obj) { + if (isSet(obj)) { + return obj.size; + } + else { + return obj.length; + } +} +exports.arrayLength = arrayLength; +/** + * Returns the number of entries in a map or object. + * + * @param obj - map or object + */ +function objectLength(obj) { + if (isMap(obj)) { + return obj.size; + } + else { + return Object.keys(obj).length; + } +} +exports.objectLength = objectLength; +/** + * Gets the value of a key from a map or object. + * + * @param obj - map or object + * @param key - the key to retrieve + */ +function getObjectValue(obj, key) { + if (isMap(obj)) { + return obj.get(key); + } + else { + return obj[key]; + } +} +exports.getObjectValue = getObjectValue; +/** + * Removes a property from a map or object. + * + * @param obj - map or object + * @param key - the key to remove + */ +function removeObjectValue(obj, key) { + if (isMap(obj)) { + obj.delete(key); + } + else { + delete obj[key]; + } +} +exports.removeObjectValue = removeObjectValue; +/** + * Deep clones the given object. + * + * @param obj - an object + */ +function clone(obj) { + if (isFunction(obj)) { + return obj; + } + else if (isArray(obj)) { + const result = []; + for (const item of obj) { + result.push(clone(item)); + } + return result; + } + else if (isObject(obj)) { + const result = {}; + for (const key in obj) { + /* istanbul ignore next */ + if (obj.hasOwnProperty(key)) { + const val = obj[key]; + result[key] = clone(val); + } + } + return result; + } + else { + return obj; + } +} +exports.clone = clone; +/** + * Type guard for boolean types + * + * @param x - a variable to type check + */ +function isBoolean(x) { + return typeof x === "boolean"; +} +exports.isBoolean = isBoolean; +/** + * Type guard for numeric types + * + * @param x - a variable to type check + */ +function isNumber(x) { + return typeof x === "number"; +} +exports.isNumber = isNumber; +/** + * Type guard for strings + * + * @param x - a variable to type check + */ +function isString(x) { + return typeof x === "string"; +} +exports.isString = isString; +/** + * Type guard for function objects + * + * @param x - a variable to type check + */ +function isFunction(x) { + return !!x && Object.prototype.toString.call(x) === '[object Function]'; +} +exports.isFunction = isFunction; +/** + * Type guard for JS objects + * + * _Note:_ Functions are objects too + * + * @param x - a variable to type check + */ +function isObject(x) { + const type = typeof x; + return !!x && (type === 'function' || type === 'object'); +} +exports.isObject = isObject; +/** + * Type guard for arrays + * + * @param x - a variable to type check + */ +function isArray(x) { + return Array.isArray(x); +} +exports.isArray = isArray; +/** + * Type guard for sets. + * + * @param x - a variable to check + */ +function isSet(x) { + return x instanceof Set; +} +exports.isSet = isSet; +/** + * Type guard for maps. + * + * @param x - a variable to check + */ +function isMap(x) { + return x instanceof Map; +} +exports.isMap = isMap; +/** + * Determines if `x` is an empty Array or an Object with no own properties. + * + * @param x - a variable to check + */ +function isEmpty(x) { + if (isArray(x)) { + return !x.length; + } + else if (isSet(x)) { + return !x.size; + } + else if (isMap(x)) { + return !x.size; + } + else if (isObject(x)) { + for (const key in x) { + if (x.hasOwnProperty(key)) { + return false; + } + } + return true; + } + return false; +} +exports.isEmpty = isEmpty; +/** + * Determines if `x` is a plain Object. + * + * @param x - a variable to check + */ +function isPlainObject(x) { + if (isObject(x)) { + const proto = Object.getPrototypeOf(x); + const ctor = proto.constructor; + return proto && ctor && + (typeof ctor === 'function') && (ctor instanceof ctor) && + (Function.prototype.toString.call(ctor) === Function.prototype.toString.call(Object)); + } + return false; +} +exports.isPlainObject = isPlainObject; +/** + * Determines if `x` is an iterable Object. + * + * @param x - a variable to check + */ +function isIterable(x) { + return x && (typeof x[Symbol.iterator] === 'function'); +} +exports.isIterable = isIterable; +/** + * Gets the primitive value of an object. + */ +function getValue(obj) { + if (isFunction(obj.valueOf)) { + return obj.valueOf(); + } + else { + return obj; + } +} +exports.getValue = getValue; +/** + * UTF-8 encodes the given string. + * + * @param input - a string + */ +function utf8Encode(input) { + const bytes = new Uint8Array(input.length * 4); + let byteIndex = 0; + for (let i = 0; i < input.length; i++) { + let char = input.charCodeAt(i); + if (char < 128) { + bytes[byteIndex++] = char; + continue; + } + else if (char < 2048) { + bytes[byteIndex++] = char >> 6 | 192; + } + else { + if (char > 0xd7ff && char < 0xdc00) { + if (++i >= input.length) { + throw new Error("Incomplete surrogate pair."); + } + const c2 = input.charCodeAt(i); + if (c2 < 0xdc00 || c2 > 0xdfff) { + throw new Error("Invalid surrogate character."); + } + char = 0x10000 + ((char & 0x03ff) << 10) + (c2 & 0x03ff); + bytes[byteIndex++] = char >> 18 | 240; + bytes[byteIndex++] = char >> 12 & 63 | 128; + } + else { + bytes[byteIndex++] = char >> 12 | 224; + } + bytes[byteIndex++] = char >> 6 & 63 | 128; + } + bytes[byteIndex++] = char & 63 | 128; + } + return bytes.subarray(0, byteIndex); +} +exports.utf8Encode = utf8Encode; +/** + * UTF-8 decodes the given byte sequence into a string. + * + * @param bytes - a byte sequence + */ +function utf8Decode(bytes) { + let result = ""; + let i = 0; + while (i < bytes.length) { + var c = bytes[i++]; + if (c > 127) { + if (c > 191 && c < 224) { + if (i >= bytes.length) { + throw new Error("Incomplete 2-byte sequence."); + } + c = (c & 31) << 6 | bytes[i++] & 63; + } + else if (c > 223 && c < 240) { + if (i + 1 >= bytes.length) { + throw new Error("Incomplete 3-byte sequence."); + } + c = (c & 15) << 12 | (bytes[i++] & 63) << 6 | bytes[i++] & 63; + } + else if (c > 239 && c < 248) { + if (i + 2 >= bytes.length) { + throw new Error("Incomplete 4-byte sequence."); + } + c = (c & 7) << 18 | (bytes[i++] & 63) << 12 | (bytes[i++] & 63) << 6 | bytes[i++] & 63; + } + else { + throw new Error("Unknown multi-byte start."); + } + } + if (c <= 0xffff) { + result += String.fromCharCode(c); + } + else if (c <= 0x10ffff) { + c -= 0x10000; + result += String.fromCharCode(c >> 10 | 0xd800); + result += String.fromCharCode(c & 0x3FF | 0xdc00); + } + else { + throw new Error("Code point exceeds UTF-16 limit."); + } + } + return result; +} +exports.utf8Decode = utf8Decode; +//# sourceMappingURL=index.js.map + +/***/ }), + +/***/ 86: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const DOMImplementationImpl_1 = __webpack_require__(290); +const WindowImpl_1 = __webpack_require__(932); +const XMLDocumentImpl_1 = __webpack_require__(661); +const DocumentImpl_1 = __webpack_require__(488); +const AbortControllerImpl_1 = __webpack_require__(990); +const AbortSignalImpl_1 = __webpack_require__(784); +const DocumentTypeImpl_1 = __webpack_require__(558); +const ElementImpl_1 = __webpack_require__(695); +const DocumentFragmentImpl_1 = __webpack_require__(796); +const ShadowRootImpl_1 = __webpack_require__(581); +const AttrImpl_1 = __webpack_require__(866); +const TextImpl_1 = __webpack_require__(820); +const CDATASectionImpl_1 = __webpack_require__(920); +const CommentImpl_1 = __webpack_require__(760); +const ProcessingInstructionImpl_1 = __webpack_require__(619); +const HTMLCollectionImpl_1 = __webpack_require__(204); +const NodeListImpl_1 = __webpack_require__(636); +const NodeListStaticImpl_1 = __webpack_require__(266); +const NamedNodeMapImpl_1 = __webpack_require__(88); +const RangeImpl_1 = __webpack_require__(90); +const NodeIteratorImpl_1 = __webpack_require__(800); +const TreeWalkerImpl_1 = __webpack_require__(646); +const NodeFilterImpl_1 = __webpack_require__(774); +const MutationRecordImpl_1 = __webpack_require__(730); +const DOMTokenListImpl_1 = __webpack_require__(742); +/** + * Creates a `DOMImplementation`. + * + * @param document - associated document + */ +function create_domImplementation(document) { + return DOMImplementationImpl_1.DOMImplementationImpl._create(document); +} +exports.create_domImplementation = create_domImplementation; +/** + * Creates a `Window` node. + */ +function create_window() { + return WindowImpl_1.WindowImpl._create(); +} +exports.create_window = create_window; +/** + * Creates an `XMLDocument` node. + */ +function create_xmlDocument() { + return new XMLDocumentImpl_1.XMLDocumentImpl(); +} +exports.create_xmlDocument = create_xmlDocument; +/** + * Creates a `Document` node. + */ +function create_document() { + return new DocumentImpl_1.DocumentImpl(); +} +exports.create_document = create_document; +/** + * Creates an `AbortController`. + */ +function create_abortController() { + return new AbortControllerImpl_1.AbortControllerImpl(); +} +exports.create_abortController = create_abortController; +/** + * Creates an `AbortSignal`. + */ +function create_abortSignal() { + return AbortSignalImpl_1.AbortSignalImpl._create(); +} +exports.create_abortSignal = create_abortSignal; +/** + * Creates a `DocumentType` node. + * + * @param document - owner document + * @param name - name of the node + * @param publicId - `PUBLIC` identifier + * @param systemId - `SYSTEM` identifier + */ +function create_documentType(document, name, publicId, systemId) { + return DocumentTypeImpl_1.DocumentTypeImpl._create(document, name, publicId, systemId); +} +exports.create_documentType = create_documentType; +/** + * Creates a new `Element` node. + * + * @param document - owner document + * @param localName - local name + * @param namespace - namespace + * @param prefix - namespace prefix + */ +function create_element(document, localName, namespace, prefix) { + return ElementImpl_1.ElementImpl._create(document, localName, namespace, prefix); +} +exports.create_element = create_element; +/** + * Creates a new `HTMLElement` node. + * + * @param document - owner document + * @param localName - local name + * @param namespace - namespace + * @param prefix - namespace prefix + */ +function create_htmlElement(document, localName, namespace, prefix) { + // TODO: Implement in HTML DOM + return ElementImpl_1.ElementImpl._create(document, localName, namespace, prefix); +} +exports.create_htmlElement = create_htmlElement; +/** + * Creates a new `HTMLUnknownElement` node. + * + * @param document - owner document + * @param localName - local name + * @param namespace - namespace + * @param prefix - namespace prefix + */ +function create_htmlUnknownElement(document, localName, namespace, prefix) { + // TODO: Implement in HTML DOM + return ElementImpl_1.ElementImpl._create(document, localName, namespace, prefix); +} +exports.create_htmlUnknownElement = create_htmlUnknownElement; +/** + * Creates a new `DocumentFragment` node. + * + * @param document - owner document + */ +function create_documentFragment(document) { + return DocumentFragmentImpl_1.DocumentFragmentImpl._create(document); +} +exports.create_documentFragment = create_documentFragment; +/** + * Creates a new `ShadowRoot` node. + * + * @param document - owner document + * @param host - shadow root's host element node + */ +function create_shadowRoot(document, host) { + return ShadowRootImpl_1.ShadowRootImpl._create(document, host); +} +exports.create_shadowRoot = create_shadowRoot; +/** + * Creates a new `Attr` node. + * + * @param document - owner document + * @param localName - local name + */ +function create_attr(document, localName) { + return AttrImpl_1.AttrImpl._create(document, localName); +} +exports.create_attr = create_attr; +/** + * Creates a new `Text` node. + * + * @param document - owner document + * @param data - node contents + */ +function create_text(document, data) { + return TextImpl_1.TextImpl._create(document, data); +} +exports.create_text = create_text; +/** + * Creates a new `CDATASection` node. + * + * @param document - owner document + * @param data - node contents + */ +function create_cdataSection(document, data) { + return CDATASectionImpl_1.CDATASectionImpl._create(document, data); +} +exports.create_cdataSection = create_cdataSection; +/** + * Creates a new `Comment` node. + * + * @param document - owner document + * @param data - node contents + */ +function create_comment(document, data) { + return CommentImpl_1.CommentImpl._create(document, data); +} +exports.create_comment = create_comment; +/** + * Creates a new `ProcessingInstruction` node. + * + * @param document - owner document + * @param target - instruction target + * @param data - node contents + */ +function create_processingInstruction(document, target, data) { + return ProcessingInstructionImpl_1.ProcessingInstructionImpl._create(document, target, data); +} +exports.create_processingInstruction = create_processingInstruction; +/** + * Creates a new `HTMLCollection`. + * + * @param root - root node + * @param filter - node filter + */ +function create_htmlCollection(root, filter = (() => true)) { + return HTMLCollectionImpl_1.HTMLCollectionImpl._create(root, filter); +} +exports.create_htmlCollection = create_htmlCollection; +/** + * Creates a new live `NodeList`. + * + * @param root - root node + */ +function create_nodeList(root) { + return NodeListImpl_1.NodeListImpl._create(root); +} +exports.create_nodeList = create_nodeList; +/** + * Creates a new static `NodeList`. + * + * @param root - root node + * @param items - a list of items to initialize the list + */ +function create_nodeListStatic(root, items) { + return NodeListStaticImpl_1.NodeListStaticImpl._create(root, items); +} +exports.create_nodeListStatic = create_nodeListStatic; +/** + * Creates a new `NamedNodeMap`. + * + * @param element - parent element + */ +function create_namedNodeMap(element) { + return NamedNodeMapImpl_1.NamedNodeMapImpl._create(element); +} +exports.create_namedNodeMap = create_namedNodeMap; +/** + * Creates a new `Range`. + * + * @param start - start point + * @param end - end point + */ +function create_range(start, end) { + return RangeImpl_1.RangeImpl._create(start, end); +} +exports.create_range = create_range; +/** + * Creates a new `NodeIterator`. + * + * @param root - iterator's root node + * @param reference - reference node + * @param pointerBeforeReference - whether the iterator is before or after the + * reference node + */ +function create_nodeIterator(root, reference, pointerBeforeReference) { + return NodeIteratorImpl_1.NodeIteratorImpl._create(root, reference, pointerBeforeReference); +} +exports.create_nodeIterator = create_nodeIterator; +/** + * Creates a new `TreeWalker`. + * + * @param root - iterator's root node + * @param current - current node + */ +function create_treeWalker(root, current) { + return TreeWalkerImpl_1.TreeWalkerImpl._create(root, current); +} +exports.create_treeWalker = create_treeWalker; +/** + * Creates a new `NodeFilter`. + */ +function create_nodeFilter() { + return NodeFilterImpl_1.NodeFilterImpl._create(); +} +exports.create_nodeFilter = create_nodeFilter; +/** + * Creates a new `MutationRecord`. + * + * @param type - type of mutation: `"attributes"` for an attribute + * mutation, `"characterData"` for a mutation to a CharacterData node + * and `"childList"` for a mutation to the tree of nodes. + * @param target - node affected by the mutation. + * @param addedNodes - list of added nodes. + * @param removedNodes - list of removed nodes. + * @param previousSibling - previous sibling of added or removed nodes. + * @param nextSibling - next sibling of added or removed nodes. + * @param attributeName - local name of the changed attribute, + * and `null` otherwise. + * @param attributeNamespace - namespace of the changed attribute, + * and `null` otherwise. + * @param oldValue - value before mutation: attribute value for an attribute + * mutation, node `data` for a mutation to a CharacterData node and `null` + * for a mutation to the tree of nodes. + */ +function create_mutationRecord(type, target, addedNodes, removedNodes, previousSibling, nextSibling, attributeName, attributeNamespace, oldValue) { + return MutationRecordImpl_1.MutationRecordImpl._create(type, target, addedNodes, removedNodes, previousSibling, nextSibling, attributeName, attributeNamespace, oldValue); +} +exports.create_mutationRecord = create_mutationRecord; +/** + * Creates a new `DOMTokenList`. + * + * @param element - associated element + * @param attribute - associated attribute + */ +function create_domTokenList(element, attribute) { + return DOMTokenListImpl_1.DOMTokenListImpl._create(element, attribute); +} +exports.create_domTokenList = create_domTokenList; +//# sourceMappingURL=CreateAlgorithm.js.map + +/***/ }), + +/***/ 87: +/***/ (function(module) { + +module.exports = require("os"); + +/***/ }), + +/***/ 88: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const DOMException_1 = __webpack_require__(35); +const algorithm_1 = __webpack_require__(163); +/** + * Represents a collection of attributes. + */ +class NamedNodeMapImpl extends Array { + /** + * Initializes a new instance of `NamedNodeMap`. + * + * @param element - parent element + */ + constructor(element) { + super(); + this._element = element; + } + _asArray() { return this; } + /** @inheritdoc */ + item(index) { + /** + * 1. If index is equal to or greater than context object’s attribute list’s + * size, then return null. + * 2. Otherwise, return context object’s attribute list[index]. + * + */ + return this[index] || null; + } + /** @inheritdoc */ + getNamedItem(qualifiedName) { + /** + * The getNamedItem(qualifiedName) method, when invoked, must return the + * result of getting an attribute given qualifiedName and element. + */ + return algorithm_1.element_getAnAttributeByName(qualifiedName, this._element); + } + /** @inheritdoc */ + getNamedItemNS(namespace, localName) { + /** + * The getNamedItemNS(namespace, localName) method, when invoked, must + * return the result of getting an attribute given namespace, localName, + * and element. + */ + return algorithm_1.element_getAnAttributeByNamespaceAndLocalName(namespace || '', localName, this._element); + } + /** @inheritdoc */ + setNamedItem(attr) { + /** + * The setNamedItem(attr) and setNamedItemNS(attr) methods, when invoked, + * must return the result of setting an attribute given attr and element. + */ + return algorithm_1.element_setAnAttribute(attr, this._element); + } + /** @inheritdoc */ + setNamedItemNS(attr) { + return algorithm_1.element_setAnAttribute(attr, this._element); + } + /** @inheritdoc */ + removeNamedItem(qualifiedName) { + /** + * 1. Let attr be the result of removing an attribute given qualifiedName + * and element. + * 2. If attr is null, then throw a "NotFoundError" DOMException. + * 3. Return attr. + */ + const attr = algorithm_1.element_removeAnAttributeByName(qualifiedName, this._element); + if (attr === null) + throw new DOMException_1.NotFoundError(); + return attr; + } + /** @inheritdoc */ + removeNamedItemNS(namespace, localName) { + /** + * 1. Let attr be the result of removing an attribute given namespace, + * localName, and element. + * 2. If attr is null, then throw a "NotFoundError" DOMException. + * 3. Return attr. + */ + const attr = algorithm_1.element_removeAnAttributeByNamespaceAndLocalName(namespace || '', localName, this._element); + if (attr === null) + throw new DOMException_1.NotFoundError(); + return attr; + } + /** + * Creates a new `NamedNodeMap`. + * + * @param element - parent element + */ + static _create(element) { + return new NamedNodeMapImpl(element); + } +} +exports.NamedNodeMapImpl = NamedNodeMapImpl; +//# sourceMappingURL=NamedNodeMapImpl.js.map + +/***/ }), + +/***/ 90: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const _1 = __webpack_require__(113); +const interfaces_1 = __webpack_require__(970); +const AbstractRangeImpl_1 = __webpack_require__(537); +const DOMException_1 = __webpack_require__(35); +const algorithm_1 = __webpack_require__(163); +const WebIDLAlgorithm_1 = __webpack_require__(495); +const util_1 = __webpack_require__(918); +/** + * Represents a live range. + */ +class RangeImpl extends AbstractRangeImpl_1.AbstractRangeImpl { + /** + * Initializes a new instance of `Range`. + */ + constructor() { + super(); + /** + * The Range() constructor, when invoked, must return a new live range with + * (current global object’s associated Document, 0) as its start and end. + */ + const doc = _1.dom.window._associatedDocument; + this._start = [doc, 0]; + this._end = [doc, 0]; + _1.dom.rangeList.add(this); + } + /** @inheritdoc */ + get commonAncestorContainer() { + /** + * 1. Let container be start node. + * 2. While container is not an inclusive ancestor of end node, let + * container be container’s parent. + * 3. Return container. + */ + let container = this._start[0]; + while (!algorithm_1.tree_isAncestorOf(this._end[0], container, true)) { + if (container._parent === null) { + throw new Error("Parent node is null."); + } + container = container._parent; + } + return container; + } + /** @inheritdoc */ + setStart(node, offset) { + /** + * The setStart(node, offset) method, when invoked, must set the start of + * context object to boundary point (node, offset). + */ + algorithm_1.range_setTheStart(this, node, offset); + } + /** @inheritdoc */ + setEnd(node, offset) { + /** + * The setEnd(node, offset) method, when invoked, must set the end of + * context object to boundary point (node, offset). + */ + algorithm_1.range_setTheEnd(this, node, offset); + } + /** @inheritdoc */ + setStartBefore(node) { + /** + * 1. Let parent be node’s parent. + * 2. If parent is null, then throw an "InvalidNodeTypeError" DOMException. + * 3. Set the start of the context object to boundary point + * (parent, node’s index). + */ + let parent = node._parent; + if (parent === null) + throw new DOMException_1.InvalidNodeTypeError(); + algorithm_1.range_setTheStart(this, parent, algorithm_1.tree_index(node)); + } + /** @inheritdoc */ + setStartAfter(node) { + /** + * 1. Let parent be node’s parent. + * 2. If parent is null, then throw an "InvalidNodeTypeError" DOMException. + * 3. Set the start of the context object to boundary point + * (parent, node’s index plus 1). + */ + let parent = node._parent; + if (parent === null) + throw new DOMException_1.InvalidNodeTypeError(); + algorithm_1.range_setTheStart(this, parent, algorithm_1.tree_index(node) + 1); + } + /** @inheritdoc */ + setEndBefore(node) { + /** + * 1. Let parent be node’s parent. + * 2. If parent is null, then throw an "InvalidNodeTypeError" DOMException. + * 3. Set the end of the context object to boundary point + * (parent, node’s index). + */ + let parent = node._parent; + if (parent === null) + throw new DOMException_1.InvalidNodeTypeError(); + algorithm_1.range_setTheEnd(this, parent, algorithm_1.tree_index(node)); + } + /** @inheritdoc */ + setEndAfter(node) { + /** + * 1. Let parent be node’s parent. + * 2. If parent is null, then throw an "InvalidNodeTypeError" DOMException. + * 3. Set the end of the context object to boundary point + * (parent, node’s index plus 1). + */ + let parent = node._parent; + if (parent === null) + throw new DOMException_1.InvalidNodeTypeError(); + algorithm_1.range_setTheEnd(this, parent, algorithm_1.tree_index(node) + 1); + } + /** @inheritdoc */ + collapse(toStart) { + /** + * The collapse(toStart) method, when invoked, must if toStart is true, + * set end to start, and set start to end otherwise. + */ + if (toStart) { + this._end = this._start; + } + else { + this._start = this._end; + } + } + /** @inheritdoc */ + selectNode(node) { + /** + * The selectNode(node) method, when invoked, must select node within + * context object. + */ + algorithm_1.range_select(node, this); + } + /** @inheritdoc */ + selectNodeContents(node) { + /** + * 1. If node is a doctype, throw an "InvalidNodeTypeError" DOMException. + * 2. Let length be the length of node. + * 3. Set start to the boundary point (node, 0). + * 4. Set end to the boundary point (node, length). + */ + if (util_1.Guard.isDocumentTypeNode(node)) + throw new DOMException_1.InvalidNodeTypeError(); + const length = algorithm_1.tree_nodeLength(node); + this._start = [node, 0]; + this._end = [node, length]; + } + /** @inheritdoc */ + compareBoundaryPoints(how, sourceRange) { + /** + * 1. If how is not one of + * - START_TO_START, + * - START_TO_END, + * - END_TO_END, and + * - END_TO_START, + * then throw a "NotSupportedError" DOMException. + */ + if (how !== interfaces_1.HowToCompare.StartToStart && how !== interfaces_1.HowToCompare.StartToEnd && + how !== interfaces_1.HowToCompare.EndToEnd && how !== interfaces_1.HowToCompare.EndToStart) + throw new DOMException_1.NotSupportedError(); + /** + * 2. If context object’s root is not the same as sourceRange’s root, + * then throw a "WrongDocumentError" DOMException. + */ + if (algorithm_1.range_root(this) !== algorithm_1.range_root(sourceRange)) + throw new DOMException_1.WrongDocumentError(); + /** + * 3. If how is: + * - START_TO_START: + * Let this point be the context object’s start. Let other point be + * sourceRange’s start. + * - START_TO_END: + * Let this point be the context object’s end. Let other point be + * sourceRange’s start. + * - END_TO_END: + * Let this point be the context object’s end. Let other point be + * sourceRange’s end. + * - END_TO_START: + * Let this point be the context object’s start. Let other point be + * sourceRange’s end. + */ + let thisPoint; + let otherPoint; + switch (how) { + case interfaces_1.HowToCompare.StartToStart: + thisPoint = this._start; + otherPoint = sourceRange._start; + break; + case interfaces_1.HowToCompare.StartToEnd: + thisPoint = this._end; + otherPoint = sourceRange._start; + break; + case interfaces_1.HowToCompare.EndToEnd: + thisPoint = this._end; + otherPoint = sourceRange._end; + break; + case interfaces_1.HowToCompare.EndToStart: + thisPoint = this._start; + otherPoint = sourceRange._end; + break; + /* istanbul ignore next */ + default: + throw new DOMException_1.NotSupportedError(); + } + /** + * 4. If the position of this point relative to other point is + * - before + * Return −1. + * - equal + * Return 0. + * - after + * Return 1. + */ + const position = algorithm_1.boundaryPoint_position(thisPoint, otherPoint); + if (position === interfaces_1.BoundaryPosition.Before) { + return -1; + } + else if (position === interfaces_1.BoundaryPosition.After) { + return 1; + } + else { + return 0; + } + } + /** @inheritdoc */ + deleteContents() { + /** + * 1. If the context object is collapsed, then return. + * 2. Let original start node, original start offset, original end node, + * and original end offset be the context object’s start node, + * start offset, end node, and end offset, respectively. + */ + if (algorithm_1.range_collapsed(this)) + return; + const originalStartNode = this._startNode; + const originalStartOffset = this._startOffset; + const originalEndNode = this._endNode; + const originalEndOffset = this._endOffset; + /** + * 3. If original start node and original end node are the same, and they + * are a Text, ProcessingInstruction, or Comment node, replace data with + * node original start node, offset original start offset, count original + * end offset minus original start offset, and data the empty string, + * and then return. + */ + if (originalStartNode === originalEndNode && + util_1.Guard.isCharacterDataNode(originalStartNode)) { + algorithm_1.characterData_replaceData(originalStartNode, originalStartOffset, originalEndOffset - originalStartOffset, ''); + return; + } + /** + * 4. Let nodes to remove be a list of all the nodes that are contained in + * the context object, in tree order, omitting any node whose parent is also + * contained in the context object. + */ + const nodesToRemove = []; + for (const node of algorithm_1.range_getContainedNodes(this)) { + const parent = node._parent; + if (parent !== null && algorithm_1.range_isContained(parent, this)) { + continue; + } + nodesToRemove.push(node); + } + let newNode; + let newOffset; + if (algorithm_1.tree_isAncestorOf(originalEndNode, originalStartNode, true)) { + /** + * 5. If original start node is an inclusive ancestor of original end + * node, set new node to original start node and new offset to original + * start offset. + */ + newNode = originalStartNode; + newOffset = originalStartOffset; + } + else { + /** + * 6. Otherwise: + * 6.1. Let reference node equal original start node. + * 6.2. While reference node’s parent is not null and is not an inclusive + * ancestor of original end node, set reference node to its parent. + * 6.3. Set new node to the parent of reference node, and new offset to + * one plus the index of reference node. + */ + let referenceNode = originalStartNode; + while (referenceNode._parent !== null && + !algorithm_1.tree_isAncestorOf(originalEndNode, referenceNode._parent, true)) { + referenceNode = referenceNode._parent; + } + /* istanbul ignore next */ + if (referenceNode._parent === null) { + throw new Error("Parent node is null."); + } + newNode = referenceNode._parent; + newOffset = algorithm_1.tree_index(referenceNode) + 1; + } + /** + * 7. If original start node is a Text, ProcessingInstruction, or Comment + * node, replace data with node original start node, offset original start + * offset, count original start node’s length minus original start offset, + * data the empty string. + */ + if (util_1.Guard.isCharacterDataNode(originalStartNode)) { + algorithm_1.characterData_replaceData(originalStartNode, originalStartOffset, algorithm_1.tree_nodeLength(originalStartNode) - originalStartOffset, ''); + } + /** + * 8. For each node in nodes to remove, in tree order, remove node from its + * parent. + */ + for (const node of nodesToRemove) { + /* istanbul ignore else */ + if (node._parent) { + algorithm_1.mutation_remove(node, node._parent); + } + } + /** + * 9. If original end node is a Text, ProcessingInstruction, or Comment + * node, replace data with node original end node, offset 0, count original + * end offset and data the empty string. + */ + if (util_1.Guard.isCharacterDataNode(originalEndNode)) { + algorithm_1.characterData_replaceData(originalEndNode, 0, originalEndOffset, ''); + } + /** + * 10. Set start and end to (new node, new offset). + */ + this._start = [newNode, newOffset]; + this._end = [newNode, newOffset]; + } + /** @inheritdoc */ + extractContents() { + /** + * The extractContents() method, when invoked, must return the result of + * extracting the context object. + */ + return algorithm_1.range_extract(this); + } + /** @inheritdoc */ + cloneContents() { + /** + * The cloneContents() method, when invoked, must return the result of + * cloning the contents of the context object. + */ + return algorithm_1.range_cloneTheContents(this); + } + /** @inheritdoc */ + insertNode(node) { + /** + * The insertNode(node) method, when invoked, must insert node into the + * context object. + */ + return algorithm_1.range_insert(node, this); + } + /** @inheritdoc */ + surroundContents(newParent) { + /** + * 1. If a non-Text node is partially contained in the context object, then + * throw an "InvalidStateError" DOMException. + */ + for (const node of algorithm_1.range_getPartiallyContainedNodes(this)) { + if (!util_1.Guard.isTextNode(node)) { + throw new DOMException_1.InvalidStateError(); + } + } + /** + * 2. If newParent is a Document, DocumentType, or DocumentFragment node, + * then throw an "InvalidNodeTypeError" DOMException. + */ + if (util_1.Guard.isDocumentNode(newParent) || + util_1.Guard.isDocumentTypeNode(newParent) || + util_1.Guard.isDocumentFragmentNode(newParent)) { + throw new DOMException_1.InvalidNodeTypeError(); + } + /** + * 3. Let fragment be the result of extracting the context object. + */ + const fragment = algorithm_1.range_extract(this); + /** + * 4. If newParent has children, then replace all with null within newParent. + */ + if ((newParent)._children.size !== 0) { + algorithm_1.mutation_replaceAll(null, newParent); + } + /** + * 5. Insert newParent into the context object. + * 6. Append fragment to newParent. + */ + algorithm_1.range_insert(newParent, this); + algorithm_1.mutation_append(fragment, newParent); + /** + * 7. Select newParent within the context object. + */ + algorithm_1.range_select(newParent, this); + } + /** @inheritdoc */ + cloneRange() { + /** + * The cloneRange() method, when invoked, must return a new live range with + * the same start and end as the context object. + */ + return algorithm_1.create_range(this._start, this._end); + } + /** @inheritdoc */ + detach() { + /** + * The detach() method, when invoked, must do nothing. + * + * since JS lacks weak references, we still use detach + */ + _1.dom.rangeList.delete(this); + } + /** @inheritdoc */ + isPointInRange(node, offset) { + /** + * 1. If node’s root is different from the context object’s root, return false. + */ + if (algorithm_1.tree_rootNode(node) !== algorithm_1.range_root(this)) { + return false; + } + /** + * 2. If node is a doctype, then throw an "InvalidNodeTypeError" DOMException. + * 3. If offset is greater than node’s length, then throw an + * "IndexSizeError" DOMException. + */ + if (util_1.Guard.isDocumentTypeNode(node)) + throw new DOMException_1.InvalidNodeTypeError(); + if (offset > algorithm_1.tree_nodeLength(node)) + throw new DOMException_1.IndexSizeError(); + /** + * 4. If (node, offset) is before start or after end, return false. + */ + const bp = [node, offset]; + if (algorithm_1.boundaryPoint_position(bp, this._start) === interfaces_1.BoundaryPosition.Before || + algorithm_1.boundaryPoint_position(bp, this._end) === interfaces_1.BoundaryPosition.After) { + return false; + } + /** + * 5. Return true. + */ + return true; + } + /** @inheritdoc */ + comparePoint(node, offset) { + /** + * 1. If node’s root is different from the context object’s root, then throw + * a "WrongDocumentError" DOMException. + * 2. If node is a doctype, then throw an "InvalidNodeTypeError" DOMException. + * 3. If offset is greater than node’s length, then throw an + * "IndexSizeError" DOMException. + */ + if (algorithm_1.tree_rootNode(node) !== algorithm_1.range_root(this)) + throw new DOMException_1.WrongDocumentError(); + if (util_1.Guard.isDocumentTypeNode(node)) + throw new DOMException_1.InvalidNodeTypeError(); + if (offset > algorithm_1.tree_nodeLength(node)) + throw new DOMException_1.IndexSizeError(); + /** + * 4. If (node, offset) is before start, return −1. + * 5. If (node, offset) is after end, return 1. + * 6. Return 0. + */ + const bp = [node, offset]; + if (algorithm_1.boundaryPoint_position(bp, this._start) === interfaces_1.BoundaryPosition.Before) { + return -1; + } + else if (algorithm_1.boundaryPoint_position(bp, this._end) === interfaces_1.BoundaryPosition.After) { + return 1; + } + else { + return 0; + } + } + /** @inheritdoc */ + intersectsNode(node) { + /** + * 1. If node’s root is different from the context object’s root, return false. + */ + if (algorithm_1.tree_rootNode(node) !== algorithm_1.range_root(this)) { + return false; + } + /** + * 2. Let parent be node’s parent. + * 3. If parent is null, return true. + */ + const parent = node._parent; + if (parent === null) + return true; + /** + * 4. Let offset be node’s index. + */ + const offset = algorithm_1.tree_index(node); + /** + * 5. If (parent, offset) is before end and (parent, offset plus 1) is + * after start, return true. + */ + if (algorithm_1.boundaryPoint_position([parent, offset], this._end) === interfaces_1.BoundaryPosition.Before && + algorithm_1.boundaryPoint_position([parent, offset + 1], this._start) === interfaces_1.BoundaryPosition.After) { + return true; + } + /** + * 6. Return false. + */ + return false; + } + toString() { + /** + * 1. Let s be the empty string. + */ + let s = ''; + /** + * 2. If the context object’s start node is the context object’s end node + * and it is a Text node, then return the substring of that Text node’s data + * beginning at the context object’s start offset and ending at the context + * object’s end offset. + */ + if (this._startNode === this._endNode && util_1.Guard.isTextNode(this._startNode)) { + return this._startNode._data.substring(this._startOffset, this._endOffset); + } + /** + * 3. If the context object’s start node is a Text node, then append the + * substring of that node’s data from the context object’s start offset + * until the end to s. + */ + if (util_1.Guard.isTextNode(this._startNode)) { + s += this._startNode._data.substring(this._startOffset); + } + /** + * 4. Append the concatenation of the data of all Text nodes that are + * contained in the context object, in tree order, to s. + */ + for (const child of algorithm_1.range_getContainedNodes(this)) { + if (util_1.Guard.isTextNode(child)) { + s += child._data; + } + } + /** + * 5. If the context object’s end node is a Text node, then append the + * substring of that node’s data from its start until the context object’s + * end offset to s. + */ + if (util_1.Guard.isTextNode(this._endNode)) { + s += this._endNode._data.substring(0, this._endOffset); + } + /** + * 6. Return s. + */ + return s; + } + /** + * Creates a new `Range`. + * + * @param start - start point + * @param end - end point + */ + static _create(start, end) { + const range = new RangeImpl(); + if (start) + range._start = start; + if (end) + range._end = end; + return range; + } +} +exports.RangeImpl = RangeImpl; +RangeImpl.START_TO_START = 0; +RangeImpl.START_TO_END = 1; +RangeImpl.END_TO_END = 2; +RangeImpl.END_TO_START = 3; +/** + * Define constants on prototype. + */ +WebIDLAlgorithm_1.idl_defineConst(RangeImpl.prototype, "START_TO_START", 0); +WebIDLAlgorithm_1.idl_defineConst(RangeImpl.prototype, "START_TO_END", 1); +WebIDLAlgorithm_1.idl_defineConst(RangeImpl.prototype, "END_TO_END", 2); +WebIDLAlgorithm_1.idl_defineConst(RangeImpl.prototype, "END_TO_START", 3); +//# sourceMappingURL=RangeImpl.js.map + +/***/ }), + +/***/ 92: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const ObjectWriter_1 = __webpack_require__(419); +const util_1 = __webpack_require__(592); +const BaseWriter_1 = __webpack_require__(462); +/** + * Serializes XML nodes into a JSON string. + */ +class JSONWriter extends BaseWriter_1.BaseWriter { + /** + * Produces an XML serialization of the given node. + * + * @param node - node to serialize + * @param writerOptions - serialization options + */ + serialize(node, writerOptions) { + // provide default options + const options = util_1.applyDefaults(writerOptions, { + wellFormed: false, + noDoubleEncoding: false, + prettyPrint: false, + indent: ' ', + newline: '\n', + offset: 0, + group: false + }); + // convert to object + const objectWriterOptions = util_1.applyDefaults(options, { + format: "object", + wellFormed: false, + noDoubleEncoding: false, + }); + const objectWriter = new ObjectWriter_1.ObjectWriter(this._builderOptions); + const val = objectWriter.serialize(node, objectWriterOptions); + // recursively convert object into JSON string + return this._beginLine(options, 0) + this._convertObject(val, options); + } + /** + * Produces an XML serialization of the given object. + * + * @param obj - object to serialize + * @param options - serialization options + * @param level - depth of the XML tree + */ + _convertObject(obj, options, level = 0) { + let markup = ''; + const isLeaf = this._isLeafNode(obj); + if (util_1.isArray(obj)) { + markup += '['; + const len = obj.length; + let i = 0; + for (const val of obj) { + markup += this._endLine(options, level + 1) + + this._beginLine(options, level + 1) + + this._convertObject(val, options, level + 1); + if (i < len - 1) { + markup += ','; + } + i++; + } + markup += this._endLine(options, level) + this._beginLine(options, level); + markup += ']'; + } + else if (util_1.isObject(obj)) { + markup += '{'; + const len = util_1.objectLength(obj); + let i = 0; + util_1.forEachObject(obj, (key, val) => { + if (isLeaf && options.prettyPrint) { + markup += ' '; + } + else { + markup += this._endLine(options, level + 1) + this._beginLine(options, level + 1); + } + markup += '"' + key + '":'; + if (options.prettyPrint) { + markup += ' '; + } + markup += this._convertObject(val, options, level + 1); + if (i < len - 1) { + markup += ','; + } + i++; + }, this); + if (isLeaf && options.prettyPrint) { + markup += ' '; + } + else { + markup += this._endLine(options, level) + this._beginLine(options, level); + } + markup += '}'; + } + else { + markup += '"' + obj + '"'; + } + return markup; + } + /** + * Produces characters to be prepended to a line of string in pretty-print + * mode. + * + * @param options - serialization options + * @param level - current depth of the XML tree + */ + _beginLine(options, level) { + if (!options.prettyPrint) { + return ''; + } + else { + const indentLevel = options.offset + level + 1; + if (indentLevel > 0) { + return new Array(indentLevel).join(options.indent); + } + } + return ''; + } + /** + * Produces characters to be appended to a line of string in pretty-print + * mode. + * + * @param options - serialization options + * @param level - current depth of the XML tree + */ + _endLine(options, level) { + if (!options.prettyPrint) { + return ''; + } + else { + return options.newline; + } + } + /** + * Determines if an object is a leaf node. + * + * @param obj + */ + _isLeafNode(obj) { + return this._descendantCount(obj) <= 1; + } + /** + * Counts the number of descendants of the given object. + * + * @param obj + * @param count + */ + _descendantCount(obj, count = 0) { + if (util_1.isArray(obj)) { + util_1.forEachArray(obj, val => count += this._descendantCount(val, count), this); + } + else if (util_1.isObject(obj)) { + util_1.forEachObject(obj, (key, val) => count += this._descendantCount(val, count), this); + } + else { + count++; + } + return count; + } +} +exports.JSONWriter = JSONWriter; +//# sourceMappingURL=JSONWriter.js.map + +/***/ }), + +/***/ 95: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +var MapWriter_1 = __webpack_require__(750); +exports.MapWriter = MapWriter_1.MapWriter; +var XMLWriter_1 = __webpack_require__(764); +exports.XMLWriter = XMLWriter_1.XMLWriter; +var ObjectWriter_1 = __webpack_require__(419); +exports.ObjectWriter = ObjectWriter_1.ObjectWriter; +var JSONWriter_1 = __webpack_require__(92); +exports.JSONWriter = JSONWriter_1.JSONWriter; +//# sourceMappingURL=index.js.map + +/***/ }), + +/***/ 97: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const CodePoints_1 = __webpack_require__(11); +const ByteSequence_1 = __webpack_require__(263); +const Byte_1 = __webpack_require__(782); +const util_1 = __webpack_require__(68); +/** + * Determines if the string `a` is a code unit prefix of string `b`. + * + * @param a - a string + * @param b - a string + */ +function isCodeUnitPrefix(a, b) { + /** + * 1. Let i be 0. + * 2. While true: + * 2.1. Let aCodeUnit be the ith code unit of a if i is less than a’s length; + * otherwise null. + * 2.2. Let bCodeUnit be the ith code unit of b if i is less than b’s length; + * otherwise null. + * 2.3. If bCodeUnit is null, then return true. + * 2.4. Return false if aCodeUnit is different from bCodeUnit. + * 2.5. Set i to i + 1. + */ + let i = 0; + while (true) { + const aCodeUnit = i < a.length ? a.charCodeAt(i) : null; + const bCodeUnit = i < b.length ? b.charCodeAt(i) : null; + if (aCodeUnit === null) + return true; + if (aCodeUnit !== bCodeUnit) + return false; + i++; + } +} +exports.isCodeUnitPrefix = isCodeUnitPrefix; +/** + * Determines if the string `a` is a code unit less than string `b`. + * + * @param a - a string + * @param b - a string + */ +function isCodeUnitLessThan(a, b) { + /** + * 1. If b is a code unit prefix of a, then return false. + * 2. If a is a code unit prefix of b, then return true. + * 3. Let n be the smallest index such that the nth code unit of a is + * different from the nth code unit of b. (There has to be such an index, + * since neither string is a prefix of the other.) + * 4. If the nth code unit of a is less than the nth code unit of b, then + * return true. + * 5. Return false. + */ + if (isCodeUnitPrefix(b, a)) + return false; + if (isCodeUnitPrefix(a, b)) + return true; + for (let i = 0; i < Math.min(a.length, b.length); i++) { + const aCodeUnit = a.charCodeAt(i); + const bCodeUnit = b.charCodeAt(i); + if (aCodeUnit === bCodeUnit) + continue; + return (aCodeUnit < bCodeUnit); + } + /* istanbul ignore next */ + return false; +} +exports.isCodeUnitLessThan = isCodeUnitLessThan; +/** + * Isomorphic encodes the given string. + * + * @param str - a string + */ +function isomorphicEncode(str) { + /** + * 1. Assert: input contains no code points greater than U+00FF. + * 2. Return a byte sequence whose length is equal to input’s length and whose + * bytes have the same values as input’s code points, in the same order. + */ + const codePoints = Array.from(str); + const bytes = new Uint8Array(codePoints.length); + let i = 0; + for (const codePoint of str) { + const byte = codePoint.codePointAt(0); + console.assert(byte !== undefined && byte <= 0x00FF, "isomorphicEncode requires string bytes to be less than or equal to 0x00FF."); + if (byte !== undefined && byte <= 0x00FF) { + bytes[i++] = byte; + } + } + return bytes; +} +exports.isomorphicEncode = isomorphicEncode; +/** + * Determines if the given string is An ASCII string. + * + * @param str - a string + */ +function isASCIIString(str) { + /** + * An ASCII string is a string whose code points are all ASCII code points. + */ + return /^[\u0000-\u007F]*$/.test(str); +} +exports.isASCIIString = isASCIIString; +/** + * Converts all uppercase ASCII code points to lowercase. + * + * @param str - a string + */ +function asciiLowercase(str) { + /** + * To ASCII lowercase a string, replace all ASCII upper alphas in the string + * with their corresponding code point in ASCII lower alpha. + */ + let result = ""; + for (const c of str) { + const code = c.codePointAt(0); + if (code !== undefined && code >= 0x41 && code <= 0x5A) { + result += String.fromCodePoint(code + 0x20); + } + else { + result += c; + } + } + return result; +} +exports.asciiLowercase = asciiLowercase; +/** + * Converts all uppercase ASCII code points to uppercase. + * + * @param str - a string + */ +function asciiUppercase(str) { + /** + * To ASCII uppercase a string, replace all ASCII lower alphas in the string + * with their corresponding code point in ASCII upper alpha. + */ + let result = ""; + for (const c of str) { + const code = c.codePointAt(0); + if (code !== undefined && code >= 0x61 && code <= 0x7A) { + result += String.fromCodePoint(code - 0x20); + } + else { + result += c; + } + } + return result; +} +exports.asciiUppercase = asciiUppercase; +/** + * Compares two ASCII strings case-insensitively. + * + * @param a - a string + * @param b - a string + */ +function asciiCaseInsensitiveMatch(a, b) { + /** + * A string A is an ASCII case-insensitive match for a string B, if the ASCII + * lowercase of A is the ASCII lowercase of B. + */ + return asciiLowercase(a) === asciiLowercase(b); +} +exports.asciiCaseInsensitiveMatch = asciiCaseInsensitiveMatch; +/** + * ASCII encodes a string. + * + * @param str - a string + */ +function asciiEncode(str) { + /** + * 1. Assert: input is an ASCII string. + * 2. Return the isomorphic encoding of input. + */ + console.assert(isASCIIString(str), "asciiEncode requires an ASCII string."); + return isomorphicEncode(str); +} +exports.asciiEncode = asciiEncode; +/** + * ASCII decodes a byte sequence. + * + * @param bytes - a byte sequence + */ +function asciiDecode(bytes) { + /** + * 1. Assert: All bytes in input are ASCII bytes. + * 2. Return the isomorphic decoding of input. + */ + for (const byte of bytes) { + console.assert(Byte_1.isASCIIByte(byte), "asciiDecode requires an ASCII byte sequence."); + } + return ByteSequence_1.isomorphicDecode(bytes); +} +exports.asciiDecode = asciiDecode; +/** + * Strips newline characters from a string. + * + * @param str - a string + */ +function stripNewlines(str) { + /** + * To strip newlines from a string, remove any U+000A LF and U+000D CR code + * points from the string. + */ + return str.replace(/[\n\r]/g, ""); +} +exports.stripNewlines = stripNewlines; +/** + * Normalizes newline characters in a string by converting consecutive + * carriage-return newline characters and also single carriage return characters + * into a single newline. + * + * @param str - a string + */ +function normalizeNewlines(str) { + /** + * To normalize newlines in a string, replace every U+000D CR U+000A LF code + * point pair with a single U+000A LF code point, and then replace every + * remaining U+000D CR code point with a U+000A LF code point. + */ + return str.replace(/\r\n/g, "\n").replace(/\r/g, "\n"); +} +exports.normalizeNewlines = normalizeNewlines; +/** + * Removes leading and trailing whitespace characters from a string. + * + * @param str - a string + */ +function stripLeadingAndTrailingASCIIWhitespace(str) { + /** + * To strip leading and trailing ASCII whitespace from a string, remove all + * ASCII whitespace that are at the start or the end of the string. + */ + return str.replace(/^[\t\n\f\r ]+/, "").replace(/[\t\n\f\r ]+$/, ""); +} +exports.stripLeadingAndTrailingASCIIWhitespace = stripLeadingAndTrailingASCIIWhitespace; +/** + * Removes consecutive newline characters from a string. + * + * @param str - a string + */ +function stripAndCollapseASCIIWhitespace(str) { + /** + * To strip and collapse ASCII whitespace in a string, replace any sequence of + * one or more consecutive code points that are ASCII whitespace in the string + * with a single U+0020 SPACE code point, and then remove any leading and + * trailing ASCII whitespace from that string. + */ + return stripLeadingAndTrailingASCIIWhitespace(str.replace(/[\t\n\f\r ]{2,}/g, " ")); +} +exports.stripAndCollapseASCIIWhitespace = stripAndCollapseASCIIWhitespace; +/** + * Collects a sequence of code points matching a given condition from the input + * string. + * + * @param condition - a condition to match + * @param input - a string + * @param options - starting position + */ +function collectASequenceOfCodePoints(condition, input, options) { + /** + * 1. Let result be the empty string. + * 2. While position doesn’t point past the end of input and the code point at + * position within input meets the condition condition: + * 2.1. Append that code point to the end of result. + * 2.2. Advance position by 1. + * 3. Return result. + */ + if (!util_1.isArray(input)) + return collectASequenceOfCodePoints(condition, Array.from(input), options); + let result = ""; + while (options.position < input.length && !!condition.call(null, input[options.position])) { + result += input[options.position]; + options.position++; + } + return result; +} +exports.collectASequenceOfCodePoints = collectASequenceOfCodePoints; +/** + * Skips over ASCII whitespace. + * + * @param input - input string + * @param options - starting position + */ +function skipASCIIWhitespace(input, options) { + /** + * To skip ASCII whitespace within a string input given a position variable + * position, collect a sequence of code points that are ASCII whitespace from + * input given position. The collected code points are not used, but position + * is still updated. + */ + collectASequenceOfCodePoints(str => CodePoints_1.ASCIIWhiteSpace.test(str), input, options); +} +exports.skipASCIIWhitespace = skipASCIIWhitespace; +/** + * Solits a string at the given delimiter. + * + * @param input - input string + * @param delimiter - a delimiter string + */ +function strictlySplit(input, delimiter) { + /** + * 1. Let position be a position variable for input, initially pointing at the + * start of input. + * 2. Let tokens be a list of strings, initially empty. + * 3. Let token be the result of collecting a sequence of code points that are + * not equal to delimiter from input, given position. + * 4. Append token to tokens. + * 5. While position is not past the end of input: + * 5.1. Assert: the code point at position within input is delimiter. + * 5.2. Advance position by 1. + * 5.3. Let token be the result of collecting a sequence of code points that + * are not equal to delimiter from input, given position. + * 5.4. Append token to tokens. + * 6. Return tokens. + */ + if (!util_1.isArray(input)) + return strictlySplit(Array.from(input), delimiter); + const options = { position: 0 }; + const tokens = []; + let token = collectASequenceOfCodePoints(str => delimiter !== str, input, options); + tokens.push(token); + while (options.position < input.length) { + console.assert(input[options.position] === delimiter, "strictlySplit found no delimiter in input string."); + options.position++; + token = collectASequenceOfCodePoints(str => delimiter !== str, input, options); + tokens.push(token); + } + return tokens; +} +exports.strictlySplit = strictlySplit; +/** + * Splits a string on ASCII whitespace. + * + * @param input - a string + */ +function splitAStringOnASCIIWhitespace(input) { + /** + * 1. Let position be a position variable for input, initially pointing at the + * start of input. + * 2. Let tokens be a list of strings, initially empty. + * 3. Skip ASCII whitespace within input given position. + * 4. While position is not past the end of input: + * 4.1. Let token be the result of collecting a sequence of code points that + * are not ASCII whitespace from input, given position. + * 4.2. Append token to tokens. + * 4.3. Skip ASCII whitespace within input given position. + * 5. Return tokens. + */ + if (!util_1.isArray(input)) + return splitAStringOnASCIIWhitespace(Array.from(input)); + const options = { position: 0 }; + const tokens = []; + skipASCIIWhitespace(input, options); + while (options.position < input.length) { + const token = collectASequenceOfCodePoints(str => !CodePoints_1.ASCIIWhiteSpace.test(str), input, options); + tokens.push(token); + skipASCIIWhitespace(input, options); + } + return tokens; +} +exports.splitAStringOnASCIIWhitespace = splitAStringOnASCIIWhitespace; +/** + * Splits a string on commas. + * + * @param input - a string + */ +function splitAStringOnCommas(input) { + /** + * 1. Let position be a position variable for input, initially pointing at the + * start of input. + * 2. Let tokens be a list of strings, initially empty. + * 3. While position is not past the end of input: + * 3.1. Let token be the result of collecting a sequence of code points that + * are not U+002C (,) from input, given position. + * 3.2. Strip leading and trailing ASCII whitespace from token. + * 3.3. Append token to tokens. + * 3.4. If position is not past the end of input, then: + * 3.4.1. Assert: the code point at position within input is U+002C (,). + * 3.4.2. Advance position by 1. + * 4. Return tokens. + */ + if (!util_1.isArray(input)) + return splitAStringOnCommas(Array.from(input)); + const options = { position: 0 }; + const tokens = []; + while (options.position < input.length) { + const token = collectASequenceOfCodePoints(str => str !== ',', input, options); + tokens.push(stripLeadingAndTrailingASCIIWhitespace(token)); + if (options.position < input.length) { + console.assert(input[options.position] === ',', "splitAStringOnCommas found no delimiter in input string."); + options.position++; + } + } + return tokens; +} +exports.splitAStringOnCommas = splitAStringOnCommas; +/** + * Concatenates a list of strings with the given separator. + * + * @param list - a list of strings + * @param separator - a separator string + */ +function concatenate(list, separator = "") { + /** + * 1. If list is empty, then return the empty string. + * 2. If separator is not given, then set separator to the empty string. + * 3. Return a string whose contents are list’s items, in order, separated + * from each other by separator. + */ + if (list.length === 0) + return ""; + return list.join(separator); +} +exports.concatenate = concatenate; +//# sourceMappingURL=String.js.map + +/***/ }), + +/***/ 98: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const interfaces_1 = __webpack_require__(970); +const LocalNameSet_1 = __webpack_require__(575); +const NamespacePrefixMap_1 = __webpack_require__(392); +const DOMException_1 = __webpack_require__(35); +const infra_1 = __webpack_require__(23); +const algorithm_1 = __webpack_require__(163); +/** + * Represents an XML serializer. + * + * Implements: https://www.w3.org/TR/DOM-Parsing/#serializing + */ +class XMLSerializerImpl { + /** @inheritdoc */ + serializeToString(root) { + /** + * The serializeToString(root) method must produce an XML serialization + * of root passing a value of false for the require well-formed parameter, + * and return the result. + */ + return this._xmlSerialization(root, false); + } + /** + * Produces an XML serialization of the given node. + * + * @param node - node to serialize + * @param requireWellFormed - whether to check conformance + */ + _xmlSerialization(node, requireWellFormed) { + // To increase performance, use a namespace-aware serializer only if the + // document has namespaced elements + if (node._nodeDocument === undefined || node._nodeDocument._hasNamespaces) { + /** From: https://w3c.github.io/DOM-Parsing/#xml-serialization + * + * 1. Let namespace be a context namespace with value null. + * The context namespace tracks the XML serialization algorithm's current + * default namespace. The context namespace is changed when either an Element + * Node has a default namespace declaration, or the algorithm generates a + * default namespace declaration for the Element Node to match its own + * namespace. The algorithm assumes no namespace (null) to start. + * 2. Let prefix map be a new namespace prefix map. + * 3. Add the XML namespace with prefix value "xml" to prefix map. + * 4. Let prefix index be a generated namespace prefix index with value 1. + * The generated namespace prefix index is used to generate a new unique + * prefix value when no suitable existing namespace prefix is available to + * serialize a node's namespaceURI (or the namespaceURI of one of node's + * attributes). See the generate a prefix algorithm. + */ + const namespace = null; + const prefixMap = new NamespacePrefixMap_1.NamespacePrefixMap(); + prefixMap.set("xml", infra_1.namespace.XML); + const prefixIndex = { value: 1 }; + /** + * 5. Return the result of running the XML serialization algorithm on node + * passing the context namespace namespace, namespace prefix map prefix map, + * generated namespace prefix index reference to prefix index, and the + * flag require well-formed. If an exception occurs during the execution + * of the algorithm, then catch that exception and throw an + * "InvalidStateError" DOMException. + */ + try { + return this._serializeNodeNS(node, namespace, prefixMap, prefixIndex, requireWellFormed); + } + catch (_a) { + throw new DOMException_1.InvalidStateError(); + } + } + else { + try { + return this._serializeNode(node, requireWellFormed); + } + catch (_b) { + throw new DOMException_1.InvalidStateError(); + } + } + } + /** + * Produces an XML serialization of a node. + * + * @param node - node to serialize + * @param namespace - context namespace + * @param prefixMap - namespace prefix map + * @param prefixIndex - generated namespace prefix index + * @param requireWellFormed - whether to check conformance + */ + _serializeNodeNS(node, namespace, prefixMap, prefixIndex, requireWellFormed) { + switch (node.nodeType) { + case interfaces_1.NodeType.Element: + return this._serializeElementNS(node, namespace, prefixMap, prefixIndex, requireWellFormed); + case interfaces_1.NodeType.Document: + return this._serializeDocumentNS(node, namespace, prefixMap, prefixIndex, requireWellFormed); + case interfaces_1.NodeType.Comment: + return this._serializeComment(node, requireWellFormed); + case interfaces_1.NodeType.Text: + return this._serializeText(node, requireWellFormed); + case interfaces_1.NodeType.DocumentFragment: + return this._serializeDocumentFragmentNS(node, namespace, prefixMap, prefixIndex, requireWellFormed); + case interfaces_1.NodeType.DocumentType: + return this._serializeDocumentType(node, requireWellFormed); + case interfaces_1.NodeType.ProcessingInstruction: + return this._serializeProcessingInstruction(node, requireWellFormed); + case interfaces_1.NodeType.CData: + return this._serializeCData(node, requireWellFormed); + default: + throw new Error(`Unknown node type: ${node.nodeType}`); + } + } + /** + * Produces an XML serialization of a node. + * + * @param node - node to serialize + * @param requireWellFormed - whether to check conformance + */ + _serializeNode(node, requireWellFormed) { + switch (node.nodeType) { + case interfaces_1.NodeType.Element: + return this._serializeElement(node, requireWellFormed); + case interfaces_1.NodeType.Document: + return this._serializeDocument(node, requireWellFormed); + case interfaces_1.NodeType.Comment: + return this._serializeComment(node, requireWellFormed); + case interfaces_1.NodeType.Text: + return this._serializeText(node, requireWellFormed); + case interfaces_1.NodeType.DocumentFragment: + return this._serializeDocumentFragment(node, requireWellFormed); + case interfaces_1.NodeType.DocumentType: + return this._serializeDocumentType(node, requireWellFormed); + case interfaces_1.NodeType.ProcessingInstruction: + return this._serializeProcessingInstruction(node, requireWellFormed); + case interfaces_1.NodeType.CData: + return this._serializeCData(node, requireWellFormed); + default: + throw new Error(`Unknown node type: ${node.nodeType}`); + } + } + /** + * Produces an XML serialization of an element node. + * + * @param node - node to serialize + * @param namespace - context namespace + * @param prefixMap - namespace prefix map + * @param prefixIndex - generated namespace prefix index + * @param requireWellFormed - whether to check conformance + */ + _serializeElementNS(node, namespace, prefixMap, prefixIndex, requireWellFormed) { + /** + * From: https://w3c.github.io/DOM-Parsing/#xml-serializing-an-element-node + * + * 1. If the require well-formed flag is set (its value is true), and this + * node's localName attribute contains the character ":" (U+003A COLON) or + * does not match the XML Name production, then throw an exception; the + * serialization of this node would not be a well-formed element. + */ + if (requireWellFormed && (node.localName.indexOf(":") !== -1 || + !algorithm_1.xml_isName(node.localName))) { + throw new Error("Node local name contains invalid characters (well-formed required)."); + } + /** + * 2. Let markup be the string "<" (U+003C LESS-THAN SIGN). + * 3. Let qualified name be an empty string. + * 4. Let skip end tag be a boolean flag with value false. + * 5. Let ignore namespace definition attribute be a boolean flag with value + * false. + * 6. Given prefix map, copy a namespace prefix map and let map be the + * result. + * 7. Let local prefixes map be an empty map. The map has unique Node prefix + * strings as its keys, with corresponding namespaceURI Node values as the + * map's key values (in this map, the null namespace is represented by the + * empty string). + * + * _Note:_ This map is local to each element. It is used to ensure there + * are no conflicting prefixes should a new namespace prefix attribute need + * to be generated. It is also used to enable skipping of duplicate prefix + * definitions when writing an element's attributes: the map allows the + * algorithm to distinguish between a prefix in the namespace prefix map + * that might be locally-defined (to the current Element) and one that is + * not. + * 8. Let local default namespace be the result of recording the namespace + * information for node given map and local prefixes map. + * + * _Note:_ The above step will update map with any found namespace prefix + * definitions, add the found prefix definitions to the local prefixes map + * and return a local default namespace value defined by a default namespace + * attribute if one exists. Otherwise it returns null. + * 9. Let inherited ns be a copy of namespace. + * 10. Let ns be the value of node's namespaceURI attribute. + */ + let markup = "<"; + let qualifiedName = ''; + let skipEndTag = false; + let ignoreNamespaceDefinitionAttribute = false; + let map = prefixMap.copy(); + let localPrefixesMap = {}; + let localDefaultNamespace = this._recordNamespaceInformation(node, map, localPrefixesMap); + let inheritedNS = namespace; + let ns = node.namespaceURI; + /** 11. If inherited ns is equal to ns, then: */ + if (inheritedNS === ns) { + /** + * 11.1. If local default namespace is not null, then set ignore + * namespace definition attribute to true. + */ + if (localDefaultNamespace !== null) { + ignoreNamespaceDefinitionAttribute = true; + } + /** + * 11.2. If ns is the XML namespace, then append to qualified name the + * concatenation of the string "xml:" and the value of node's localName. + * 11.3. Otherwise, append to qualified name the value of node's + * localName. The node's prefix if it exists, is dropped. + */ + if (ns === infra_1.namespace.XML) { + qualifiedName = 'xml:' + node.localName; + } + else { + qualifiedName = node.localName; + } + /** 11.4. Append the value of qualified name to markup. */ + markup += qualifiedName; + } + else { + /** + * 12. Otherwise, inherited ns is not equal to ns (the node's own + * namespace is different from the context namespace of its parent). + * Run these sub-steps: + * + * 12.1. Let prefix be the value of node's prefix attribute. + * 12.2. Let candidate prefix be the result of retrieving a preferred + * prefix string prefix from map given namespace ns. The above may return + * null if no namespace key ns exists in map. + */ + let prefix = node.prefix; + /** + * We don't need to run "retrieving a preferred prefix string" algorithm if + * the element has no prefix and its namespace matches to the default + * namespace. + * See: https://github.com/web-platform-tests/wpt/pull/16703 + */ + let candidatePrefix = null; + if (prefix !== null || ns !== localDefaultNamespace) { + candidatePrefix = map.get(prefix, ns); + } + /** + * 12.3. If the value of prefix matches "xmlns", then run the following + * steps: + */ + if (prefix === "xmlns") { + /** + * 12.3.1. If the require well-formed flag is set, then throw an error. + * An Element with prefix "xmlns" will not legally round-trip in a + * conforming XML parser. + */ + if (requireWellFormed) { + throw new Error("An element cannot have the 'xmlns' prefix (well-formed required)."); + } + /** + * 12.3.2. Let candidate prefix be the value of prefix. + */ + candidatePrefix = prefix; + } + /** + * 12.4.Found a suitable namespace prefix: if candidate prefix is not + * null (a namespace prefix is defined which maps to ns), then: + */ + if (candidatePrefix !== null) { + /** + * The following may serialize a different prefix than the Element's + * existing prefix if it already had one. However, the retrieving a + * preferred prefix string algorithm already tried to match the + * existing prefix if possible. + * + * 12.4.1. Append to qualified name the concatenation of candidate + * prefix, ":" (U+003A COLON), and node's localName. There exists on + * this node or the node's ancestry a namespace prefix definition that + * defines the node's namespace. + * 12.4.2. If the local default namespace is not null (there exists a + * locally-defined default namespace declaration attribute) and its + * value is not the XML namespace, then let inherited ns get the value + * of local default namespace unless the local default namespace is the + * empty string in which case let it get null (the context namespace + * is changed to the declared default, rather than this node's own + * namespace). + * + * _Note:_ Any default namespace definitions or namespace prefixes that + * define the XML namespace are omitted when serializing this node's + * attributes. + */ + qualifiedName = candidatePrefix + ':' + node.localName; + if (localDefaultNamespace !== null && localDefaultNamespace !== infra_1.namespace.XML) { + inheritedNS = localDefaultNamespace || null; + } + /** + * 12.4.3. Append the value of qualified name to markup. + */ + markup += qualifiedName; + /** 12.5. Otherwise, if prefix is not null, then: */ + } + else if (prefix !== null) { + /** + * _Note:_ By this step, there is no namespace or prefix mapping + * declaration in this node (or any parent node visited by this + * algorithm) that defines prefix otherwise the step labelled Found + * a suitable namespace prefix would have been followed. The sub-steps + * that follow will create a new namespace prefix declaration for prefix + * and ensure that prefix does not conflict with an existing namespace + * prefix declaration of the same localName in node's attribute list. + * + * 12.5.1. If the local prefixes map contains a key matching prefix, + * then let prefix be the result of generating a prefix providing as + * input map, ns, and prefix index. + */ + if (prefix in localPrefixesMap) { + prefix = this._generatePrefix(ns, map, prefixIndex); + } + /** + * 12.5.2. Add prefix to map given namespace ns. + * 12.5.3. Append to qualified name the concatenation of prefix, ":" + * (U+003A COLON), and node's localName. + * 12.5.4. Append the value of qualified name to markup. + */ + map.set(prefix, ns); + qualifiedName += prefix + ':' + node.localName; + markup += qualifiedName; + /** + * 12.5.5. Append the following to markup, in the order listed: + * + * _Note:_ The following serializes a namespace prefix declaration for + * prefix which was just added to the map. + * + * 12.5.5.1. " " (U+0020 SPACE); + * 12.5.5.2. The string "xmlns:"; + * 12.5.5.3. The value of prefix; + * 12.5.5.4. "="" (U+003D EQUALS SIGN, U+0022 QUOTATION MARK); + * 12.5.5.5. The result of serializing an attribute value given ns and + * the require well-formed flag as input; + * 12.5.5.6. """ (U+0022 QUOTATION MARK). + */ + markup += " xmlns:" + prefix + "=\"" + + this._serializeAttributeValue(ns, requireWellFormed) + "\""; + /** + * 12.5.5.7. If local default namespace is not null (there exists a + * locally-defined default namespace declaration attribute), then + * let inherited ns get the value of local default namespace unless the + * local default namespace is the empty string in which case let it get + * null. + */ + if (localDefaultNamespace !== null) { + inheritedNS = localDefaultNamespace || null; + } + /** + * 12.6. Otherwise, if local default namespace is null, or local + * default namespace is not null and its value is not equal to ns, then: + */ + } + else if (localDefaultNamespace === null || + (localDefaultNamespace !== null && localDefaultNamespace !== ns)) { + /** + * _Note:_ At this point, the namespace for this node still needs to be + * serialized, but there's no prefix (or candidate prefix) available; the + * following uses the default namespace declaration to define the + * namespace--optionally replacing an existing default declaration + * if present. + * + * 12.6.1. Set the ignore namespace definition attribute flag to true. + * 12.6.2. Append to qualified name the value of node's localName. + * 12.6.3. Let the value of inherited ns be ns. + * + * _Note:_ The new default namespace will be used in the serialization + * to define this node's namespace and act as the context namespace for + * its children. + */ + ignoreNamespaceDefinitionAttribute = true; + qualifiedName += node.localName; + inheritedNS = ns; + /** + * 12.6.4. Append the value of qualified name to markup. + */ + markup += qualifiedName; + /** + * 12.6.5. Append the following to markup, in the order listed: + * + * _Note:_ The following serializes the new (or replacement) default + * namespace definition. + * + * 12.6.5.1. " " (U+0020 SPACE); + * 12.6.5.2. The string "xmlns"; + * 12.6.5.3. "="" (U+003D EQUALS SIGN, U+0022 QUOTATION MARK); + * 12.6.5.4. The result of serializing an attribute value given ns + * and the require well-formed flag as input; + * 12.6.5.5. """ (U+0022 QUOTATION MARK). + */ + markup += " xmlns" + "=\"" + + this._serializeAttributeValue(ns, requireWellFormed) + "\""; + /** + * 12.7. Otherwise, the node has a local default namespace that matches + * ns. Append to qualified name the value of node's localName, let the + * value of inherited ns be ns, and append the value of qualified name + * to markup. + */ + } + else { + qualifiedName += node.localName; + inheritedNS = ns; + markup += qualifiedName; + } + } + /** + * 13. Append to markup the result of the XML serialization of node's + * attributes given map, prefix index, local prefixes map, ignore namespace + * definition attribute flag, and require well-formed flag. + */ + markup += this._serializeAttributesNS(node, map, prefixIndex, localPrefixesMap, ignoreNamespaceDefinitionAttribute, requireWellFormed); + /** + * 14. If ns is the HTML namespace, and the node's list of children is + * empty, and the node's localName matches any one of the following void + * elements: "area", "base", "basefont", "bgsound", "br", "col", "embed", + * "frame", "hr", "img", "input", "keygen", "link", "menuitem", "meta", + * "param", "source", "track", "wbr"; then append the following to markup, + * in the order listed: + * 14.1. " " (U+0020 SPACE); + * 14.2. "/" (U+002F SOLIDUS). + * and set the skip end tag flag to true. + * 15. If ns is not the HTML namespace, and the node's list of children is + * empty, then append "/" (U+002F SOLIDUS) to markup and set the skip end + * tag flag to true. + * 16. Append ">" (U+003E GREATER-THAN SIGN) to markup. + */ + const isHTML = (ns === infra_1.namespace.HTML); + if (isHTML && node.childNodes.length === 0 && + XMLSerializerImpl._VoidElementNames.has(node.localName)) { + markup += " /"; + skipEndTag = true; + } + else if (!isHTML && node.childNodes.length === 0) { + markup += "/"; + skipEndTag = true; + } + markup += ">"; + /** + * 17. If the value of skip end tag is true, then return the value of markup + * and skip the remaining steps. The node is a leaf-node. + */ + if (skipEndTag) + return markup; + /** + * 18. If ns is the HTML namespace, and the node's localName matches the + * string "template", then this is a template element. Append to markup the + * result of XML serializing a DocumentFragment node given the template + * element's template contents (a DocumentFragment), providing inherited + * ns, map, prefix index, and the require well-formed flag. + * + * _Note:_ This allows template content to round-trip, given the rules for + * parsing XHTML documents. + * + * 19. Otherwise, append to markup the result of running the XML + * serialization algorithm on each of node's children, in tree order, + * providing inherited ns, map, prefix index, and the require well-formed + * flag. + */ + if (isHTML && node.localName === "template") { + // TODO: serialize template contents + } + else { + for (const childNode of node._children || node.childNodes) { + markup += this._serializeNodeNS(childNode, inheritedNS, map, prefixIndex, requireWellFormed); + } + } + /** + * 20. Append the following to markup, in the order listed: + * 20.1. "" (U+003E GREATER-THAN SIGN). + */ + markup += ""; + /** + * 21. Return the value of markup. + */ + return markup; + } + /** + * Produces an XML serialization of a document node. + * + * @param node - node to serialize + * @param namespace - context namespace + * @param prefixMap - namespace prefix map + * @param prefixIndex - generated namespace prefix index + * @param requireWellFormed - whether to check conformance + */ + _serializeDocumentNS(node, namespace, prefixMap, prefixIndex, requireWellFormed) { + /** + * If the require well-formed flag is set (its value is true), and this node + * has no documentElement (the documentElement attribute's value is null), + * then throw an exception; the serialization of this node would not be a + * well-formed document. + */ + if (requireWellFormed && node.documentElement === null) { + throw new Error("Missing document element (well-formed required)."); + } + /** + * Otherwise, run the following steps: + * 1. Let serialized document be an empty string. + * 2. For each child child of node, in tree order, run the XML + * serialization algorithm on the child passing along the provided + * arguments, and append the result to serialized document. + * + * _Note:_ This will serialize any number of ProcessingInstruction and + * Comment nodes both before and after the Document's documentElement node, + * including at most one DocumentType node. (Text nodes are not allowed as + * children of the Document.) + * + * 3. Return the value of serialized document. + */ + let serializedDocument = ""; + for (const childNode of node._children || node.childNodes) { + serializedDocument += this._serializeNodeNS(childNode, namespace, prefixMap, prefixIndex, requireWellFormed); + } + return serializedDocument; + } + /** + * Produces an XML serialization of a comment node. + * + * @param node - node to serialize + * @param requireWellFormed - whether to check conformance + */ + _serializeComment(node, requireWellFormed) { + /** + * If the require well-formed flag is set (its value is true), and node's + * data contains characters that are not matched by the XML Char production + * or contains "--" (two adjacent U+002D HYPHEN-MINUS characters) or that + * ends with a "-" (U+002D HYPHEN-MINUS) character, then throw an exception; + * the serialization of this node's data would not be well-formed. + */ + if (requireWellFormed && (!algorithm_1.xml_isLegalChar(node.data) || + node.data.indexOf("--") !== -1 || node.data.endsWith("-"))) { + throw new Error("Comment data contains invalid characters (well-formed required)."); + } + /** + * Otherwise, return the concatenation of "". + */ + return ""; + } + /** + * Produces an XML serialization of a text node. + * + * @param node - node to serialize + * @param requireWellFormed - whether to check conformance + * @param level - current depth of the XML tree + */ + _serializeText(node, requireWellFormed) { + /** + * 1. If the require well-formed flag is set (its value is true), and + * node's data contains characters that are not matched by the XML Char + * production, then throw an exception; the serialization of this node's + * data would not be well-formed. + */ + if (requireWellFormed && !algorithm_1.xml_isLegalChar(node.data)) { + throw new Error("Text data contains invalid characters (well-formed required)."); + } + /** + * 2. Let markup be the value of node's data. + * 3. Replace any occurrences of "&" in markup by "&". + * 4. Replace any occurrences of "<" in markup by "<". + * 5. Replace any occurrences of ">" in markup by ">". + * 6. Return the value of markup. + */ + let result = ""; + for (let i = 0; i < node.data.length; i++) { + const c = node.data[i]; + if (c === "&") + result += "&"; + else if (c === "<") + result += "<"; + else if (c === ">") + result += ">"; + else + result += c; + } + return result; + } + /** + * Produces an XML serialization of a document fragment node. + * + * @param node - node to serialize + * @param namespace - context namespace + * @param prefixMap - namespace prefix map + * @param prefixIndex - generated namespace prefix index + * @param requireWellFormed - whether to check conformance + */ + _serializeDocumentFragmentNS(node, namespace, prefixMap, prefixIndex, requireWellFormed) { + /** + * 1. Let markup the empty string. + * 2. For each child child of node, in tree order, run the XML serialization + * algorithm on the child given namespace, prefix map, a reference to prefix + * index, and flag require well-formed. Concatenate the result to markup. + * 3. Return the value of markup. + */ + let markup = ""; + for (const childNode of node._children || node.childNodes) { + markup += this._serializeNodeNS(childNode, namespace, prefixMap, prefixIndex, requireWellFormed); + } + return markup; + } + /** + * Produces an XML serialization of a document type node. + * + * @param node - node to serialize + * @param requireWellFormed - whether to check conformance + */ + _serializeDocumentType(node, requireWellFormed) { + /** + * 1. If the require well-formed flag is true and the node's publicId + * attribute contains characters that are not matched by the XML PubidChar + * production, then throw an exception; the serialization of this node + * would not be a well-formed document type declaration. + */ + if (requireWellFormed && !algorithm_1.xml_isPubidChar(node.publicId)) { + throw new Error("DocType public identifier does not match PubidChar construct (well-formed required)."); + } + /** + * 2. If the require well-formed flag is true and the node's systemId + * attribute contains characters that are not matched by the XML Char + * production or that contains both a """ (U+0022 QUOTATION MARK) and a + * "'" (U+0027 APOSTROPHE), then throw an exception; the serialization + * of this node would not be a well-formed document type declaration. + */ + if (requireWellFormed && + (!algorithm_1.xml_isLegalChar(node.systemId) || + (node.systemId.indexOf('"') !== -1 && node.systemId.indexOf("'") !== -1))) { + throw new Error("DocType system identifier contains invalid characters (well-formed required)."); + } + /** + * 3. Let markup be an empty string. + * 4. Append the string "" (U+003E GREATER-THAN SIGN) to markup. + * 11. Return the value of markup. + */ + return node.publicId && node.systemId ? + "" + : node.publicId ? + "" + : node.systemId ? + "" + : + ""; + } + /** + * Produces an XML serialization of a processing instruction node. + * + * @param node - node to serialize + * @param requireWellFormed - whether to check conformance + */ + _serializeProcessingInstruction(node, requireWellFormed) { + /** + * 1. If the require well-formed flag is set (its value is true), and node's + * target contains a ":" (U+003A COLON) character or is an ASCII + * case-insensitive match for the string "xml", then throw an exception; + * the serialization of this node's target would not be well-formed. + */ + if (requireWellFormed && (node.target.indexOf(":") !== -1 || (/^xml$/i).test(node.target))) { + throw new Error("Processing instruction target contains invalid characters (well-formed required)."); + } + /** + * 2. If the require well-formed flag is set (its value is true), and node's + * data contains characters that are not matched by the XML Char production + * or contains the string "?>" (U+003F QUESTION MARK, + * U+003E GREATER-THAN SIGN), then throw an exception; the serialization of + * this node's data would not be well-formed. + */ + if (requireWellFormed && (!algorithm_1.xml_isLegalChar(node.data) || + node.data.indexOf("?>") !== -1)) { + throw new Error("Processing instruction data contains invalid characters (well-formed required)."); + } + /** + * 3. Let markup be the concatenation of the following, in the order listed: + * 3.1. "" (U+003F QUESTION MARK, U+003E GREATER-THAN SIGN). + * 4. Return the value of markup. + */ + return ""; + } + /** + * Produces an XML serialization of a CDATA node. + * + * @param node - node to serialize + * @param requireWellFormed - whether to check conformance + */ + _serializeCData(node, requireWellFormed) { + if (requireWellFormed && (node.data.indexOf("]]>") !== -1)) { + throw new Error("CDATA contains invalid characters (well-formed required)."); + } + return ""; + } + /** + * Produces an XML serialization of the attributes of an element node. + * + * @param node - node to serialize + * @param map - namespace prefix map + * @param prefixIndex - generated namespace prefix index + * @param localPrefixesMap - local prefixes map + * @param ignoreNamespaceDefinitionAttribute - whether to ignore namespace + * attributes + * @param requireWellFormed - whether to check conformance + */ + _serializeAttributesNS(node, map, prefixIndex, localPrefixesMap, ignoreNamespaceDefinitionAttribute, requireWellFormed) { + /** + * 1. Let result be the empty string. + * 2. Let localname set be a new empty namespace localname set. This + * localname set will contain tuples of unique attribute namespaceURI and + * localName pairs, and is populated as each attr is processed. This set is + * used to [optionally] enforce the well-formed constraint that an element + * cannot have two attributes with the same namespaceURI and localName. + * This can occur when two otherwise identical attributes on the same + * element differ only by their prefix values. + */ + let result = ""; + const localNameSet = requireWellFormed ? new LocalNameSet_1.LocalNameSet() : undefined; + /** + * 3. Loop: For each attribute attr in element's attributes, in the order + * they are specified in the element's attribute list: + */ + for (const attr of node.attributes) { + // Optimize common case + if (!ignoreNamespaceDefinitionAttribute && !requireWellFormed && attr.namespaceURI === null) { + result += " " + attr.localName + "=\"" + + this._serializeAttributeValue(attr.value, requireWellFormed) + "\""; + continue; + } + /** + * 3.1. If the require well-formed flag is set (its value is true), and the + * localname set contains a tuple whose values match those of a new tuple + * consisting of attr's namespaceURI attribute and localName attribute, + * then throw an exception; the serialization of this attr would fail to + * produce a well-formed element serialization. + */ + if (requireWellFormed && localNameSet && localNameSet.has(attr.namespaceURI, attr.localName)) { + throw new Error("Element contains duplicate attributes (well-formed required)."); + } + /** + * 3.2. Create a new tuple consisting of attr's namespaceURI attribute and + * localName attribute, and add it to the localname set. + * 3.3. Let attribute namespace be the value of attr's namespaceURI value. + * 3.4. Let candidate prefix be null. + */ + if (requireWellFormed && localNameSet) + localNameSet.set(attr.namespaceURI, attr.localName); + let attributeNamespace = attr.namespaceURI; + let candidatePrefix = null; + /** 3.5. If attribute namespace is not null, then run these sub-steps: */ + if (attributeNamespace !== null) { + /** + * 3.5.1. Let candidate prefix be the result of retrieving a preferred + * prefix string from map given namespace attribute namespace with + * preferred prefix being attr's prefix value. + */ + candidatePrefix = map.get(attr.prefix, attributeNamespace); + /** + * 3.5.2. If the value of attribute namespace is the XMLNS namespace, + * then run these steps: + */ + if (attributeNamespace === infra_1.namespace.XMLNS) { + /** + * 3.5.2.1. If any of the following are true, then stop running these + * steps and goto Loop to visit the next attribute: + * - the attr's value is the XML namespace; + * _Note:_ The XML namespace cannot be redeclared and survive + * round-tripping (unless it defines the prefix "xml"). To avoid this + * problem, this algorithm always prefixes elements in the XML + * namespace with "xml" and drops any related definitions as seen + * in the above condition. + * - the attr's prefix is null and the ignore namespace definition + * attribute flag is true (the Element's default namespace attribute + * should be skipped); + * - the attr's prefix is not null and either + * * the attr's localName is not a key contained in the local + * prefixes map, or + * * the attr's localName is present in the local prefixes map but + * the value of the key does not match attr's value + * and furthermore that the attr's localName (as the prefix to find) + * is found in the namespace prefix map given the namespace consisting + * of the attr's value (the current namespace prefix definition was + * exactly defined previously--on an ancestor element not the current + * element whose attributes are being processed). + */ + if (attr.value === infra_1.namespace.XML || + (attr.prefix === null && ignoreNamespaceDefinitionAttribute) || + (attr.prefix !== null && (!(attr.localName in localPrefixesMap) || + localPrefixesMap[attr.localName] !== attr.value) && + map.has(attr.localName, attr.value))) + continue; + /** + * 3.5.2.2. If the require well-formed flag is set (its value is true), + * and the value of attr's value attribute matches the XMLNS + * namespace, then throw an exception; the serialization of this + * attribute would produce invalid XML because the XMLNS namespace + * is reserved and cannot be applied as an element's namespace via + * XML parsing. + * + * _Note:_ DOM APIs do allow creation of elements in the XMLNS + * namespace but with strict qualifications. + */ + if (requireWellFormed && attr.value === infra_1.namespace.XMLNS) { + throw new Error("XMLNS namespace is reserved (well-formed required)."); + } + /** + * 3.5.2.3. If the require well-formed flag is set (its value is true), + * and the value of attr's value attribute is the empty string, then + * throw an exception; namespace prefix declarations cannot be used + * to undeclare a namespace (use a default namespace declaration + * instead). + */ + if (requireWellFormed && attr.value === '') { + throw new Error("Namespace prefix declarations cannot be used to undeclare a namespace (well-formed required)."); + } + /** + * 3.5.2.4. the attr's prefix matches the string "xmlns", then let + * candidate prefix be the string "xmlns". + */ + if (attr.prefix === 'xmlns') + candidatePrefix = 'xmlns'; + /** + * 3.5.3. Otherwise, the attribute namespace is not the XMLNS namespace. + * Run these steps: + * + * _Note:_ The (candidatePrefix === null) check is not in the spec. + * We deviate from the spec here. Otherwise a prefix is generated for + * all attributes with namespaces. + */ + } + else if (candidatePrefix === null) { + if (attr.prefix !== null && + (!map.hasPrefix(attr.prefix) || + map.has(attr.prefix, attributeNamespace))) { + /** + * Check if we can use the attribute's own prefix. + * We deviate from the spec here. + * TODO: This is not an efficient way of searching for prefixes. + * Follow developments to the spec. + */ + candidatePrefix = attr.prefix; + } + else { + /** + * 3.5.3.1. Let candidate prefix be the result of generating a prefix + * providing map, attribute namespace, and prefix index as input. + */ + candidatePrefix = this._generatePrefix(attributeNamespace, map, prefixIndex); + } + /** + * 3.5.3.2. Append the following to result, in the order listed: + * 3.5.3.2.1. " " (U+0020 SPACE); + * 3.5.3.2.2. The string "xmlns:"; + * 3.5.3.2.3. The value of candidate prefix; + * 3.5.3.2.4. "="" (U+003D EQUALS SIGN, U+0022 QUOTATION MARK); + * 3.5.3.2.5. The result of serializing an attribute value given + * attribute namespace and the require well-formed flag as input; + * 3.5.3.2.6. """ (U+0022 QUOTATION MARK). + */ + result += " xmlns:" + candidatePrefix + "=\"" + + this._serializeAttributeValue(attributeNamespace, requireWellFormed) + "\""; + } + } + /** + * 3.6. Append a " " (U+0020 SPACE) to result. + * 3.7. If candidate prefix is not null, then append to result the + * concatenation of candidate prefix with ":" (U+003A COLON). + */ + result += " "; + if (candidatePrefix !== null) { + result += candidatePrefix + ':'; + } + /** + * 3.8. If the require well-formed flag is set (its value is true), and + * this attr's localName attribute contains the character + * ":" (U+003A COLON) or does not match the XML Name production or + * equals "xmlns" and attribute namespace is null, then throw an + * exception; the serialization of this attr would not be a + * well-formed attribute. + */ + if (requireWellFormed && (attr.localName.indexOf(":") !== -1 || + !algorithm_1.xml_isName(attr.localName) || + (attr.localName === "xmlns" && attributeNamespace === null))) { + throw new Error("Attribute local name contains invalid characters (well-formed required)."); + } + /** + * 3.9. Append the following strings to result, in the order listed: + * 3.9.1. The value of attr's localName; + * 3.9.2. "="" (U+003D EQUALS SIGN, U+0022 QUOTATION MARK); + * 3.9.3. The result of serializing an attribute value given attr's value + * attribute and the require well-formed flag as input; + * 3.9.4. """ (U+0022 QUOTATION MARK). + */ + result += attr.localName + "=\"" + + this._serializeAttributeValue(attr.value, requireWellFormed) + "\""; + } + /** + * 4. Return the value of result. + */ + return result; + } + /** + * Records namespace information for the given element and returns the + * default namespace attribute value. + * + * @param node - element node to process + * @param map - namespace prefix map + * @param localPrefixesMap - local prefixes map + */ + _recordNamespaceInformation(node, map, localPrefixesMap) { + /** + * 1. Let default namespace attr value be null. + */ + let defaultNamespaceAttrValue = null; + /** + * 2. Main: For each attribute attr in element's attributes, in the order + * they are specified in the element's attribute list: + */ + for (const attr of node.attributes) { + /** + * _Note:_ The following conditional steps find namespace prefixes. Only + * attributes in the XMLNS namespace are considered (e.g., attributes made + * to look like namespace declarations via + * setAttribute("xmlns:pretend-prefix", "pretend-namespace") are not + * included). + */ + /** 2.1. Let attribute namespace be the value of attr's namespaceURI value. */ + let attributeNamespace = attr.namespaceURI; + /** 2.2. Let attribute prefix be the value of attr's prefix. */ + let attributePrefix = attr.prefix; + /** 2.3. If the attribute namespace is the XMLNS namespace, then: */ + if (attributeNamespace === infra_1.namespace.XMLNS) { + /** + * 2.3.1. If attribute prefix is null, then attr is a default namespace + * declaration. Set the default namespace attr value to attr's value and + * stop running these steps, returning to Main to visit the next + * attribute. + */ + if (attributePrefix === null) { + defaultNamespaceAttrValue = attr.value; + continue; + /** + * 2.3.2. Otherwise, the attribute prefix is not null and attr is a + * namespace prefix definition. Run the following steps: + */ + } + else { + /** 2.3.2.1. Let prefix definition be the value of attr's localName. */ + let prefixDefinition = attr.localName; + /** 2.3.2.2. Let namespace definition be the value of attr's value. */ + let namespaceDefinition = attr.value; + /** + * 2.3.2.3. If namespace definition is the XML namespace, then stop + * running these steps, and return to Main to visit the next + * attribute. + * + * _Note:_ XML namespace definitions in prefixes are completely + * ignored (in order to avoid unnecessary work when there might be + * prefix conflicts). XML namespaced elements are always handled + * uniformly by prefixing (and overriding if necessary) the element's + * localname with the reserved "xml" prefix. + */ + if (namespaceDefinition === infra_1.namespace.XML) { + continue; + } + /** + * 2.3.2.4. If namespace definition is the empty string (the + * declarative form of having no namespace), then let namespace + * definition be null instead. + */ + if (namespaceDefinition === '') { + namespaceDefinition = null; + } + /** + * 2.3.2.5. If prefix definition is found in map given the namespace + * namespace definition, then stop running these steps, and return to + * Main to visit the next attribute. + * + * _Note:_ This step avoids adding duplicate prefix definitions for + * the same namespace in the map. This has the side-effect of avoiding + * later serialization of duplicate namespace prefix declarations in + * any descendant nodes. + */ + if (map.has(prefixDefinition, namespaceDefinition)) { + continue; + } + /** + * 2.3.2.6. Add the prefix prefix definition to map given namespace + * namespace definition. + */ + map.set(prefixDefinition, namespaceDefinition); + /** + * 2.3.2.7. Add the value of prefix definition as a new key to the + * local prefixes map, with the namespace definition as the key's + * value replacing the value of null with the empty string if + * applicable. + */ + localPrefixesMap[prefixDefinition] = namespaceDefinition || ''; + } + } + } + /** + * 3. Return the value of default namespace attr value. + * + * _Note:_ The empty string is a legitimate return value and is not + * converted to null. + */ + return defaultNamespaceAttrValue; + } + /** + * Generates a new prefix for the given namespace. + * + * @param newNamespace - a namespace to generate prefix for + * @param prefixMap - namespace prefix map + * @param prefixIndex - generated namespace prefix index + */ + _generatePrefix(newNamespace, prefixMap, prefixIndex) { + /** + * 1. Let generated prefix be the concatenation of the string "ns" and the + * current numerical value of prefix index. + * 2. Let the value of prefix index be incremented by one. + * 3. Add to map the generated prefix given the new namespace namespace. + * 4. Return the value of generated prefix. + */ + let generatedPrefix = "ns" + prefixIndex.value; + prefixIndex.value++; + prefixMap.set(generatedPrefix, newNamespace); + return generatedPrefix; + } + /** + * Produces an XML serialization of an attribute value. + * + * @param value - attribute value + * @param requireWellFormed - whether to check conformance + */ + _serializeAttributeValue(value, requireWellFormed) { + /** + * From: https://w3c.github.io/DOM-Parsing/#dfn-serializing-an-attribute-value + * + * 1. If the require well-formed flag is set (its value is true), and + * attribute value contains characters that are not matched by the XML Char + * production, then throw an exception; the serialization of this attribute + * value would fail to produce a well-formed element serialization. + */ + if (requireWellFormed && value !== null && !algorithm_1.xml_isLegalChar(value)) { + throw new Error("Invalid characters in attribute value."); + } + /** + * 2. If attribute value is null, then return the empty string. + */ + if (value === null) + return ""; + /** + * 3. Otherwise, attribute value is a string. Return the value of attribute + * value, first replacing any occurrences of the following: + * - "&" with "&" + * - """ with """ + * - "<" with "<" + * - ">" with ">" + * NOTE + * This matches behavior present in browsers, and goes above and beyond the + * grammar requirement in the XML specification's AttValue production by + * also replacing ">" characters. + */ + let result = ""; + for (let i = 0; i < value.length; i++) { + const c = value[i]; + if (c === "\"") + result += """; + else if (c === "&") + result += "&"; + else if (c === "<") + result += "<"; + else if (c === ">") + result += ">"; + else + result += c; + } + return result; + } + /** + * Produces an XML serialization of an element node. + * + * @param node - node to serialize + * @param requireWellFormed - whether to check conformance + */ + _serializeElement(node, requireWellFormed) { + /** + * From: https://w3c.github.io/DOM-Parsing/#xml-serializing-an-element-node + * + * 1. If the require well-formed flag is set (its value is true), and this + * node's localName attribute contains the character ":" (U+003A COLON) or + * does not match the XML Name production, then throw an exception; the + * serialization of this node would not be a well-formed element. + */ + if (requireWellFormed && (node.localName.indexOf(":") !== -1 || + !algorithm_1.xml_isName(node.localName))) { + throw new Error("Node local name contains invalid characters (well-formed required)."); + } + /** + * 2. Let markup be the string "<" (U+003C LESS-THAN SIGN). + * 3. Let qualified name be an empty string. + * 4. Let skip end tag be a boolean flag with value false. + * 5. Let ignore namespace definition attribute be a boolean flag with value + * false. + * 6. Given prefix map, copy a namespace prefix map and let map be the + * result. + * 7. Let local prefixes map be an empty map. The map has unique Node prefix + * strings as its keys, with corresponding namespaceURI Node values as the + * map's key values (in this map, the null namespace is represented by the + * empty string). + * + * _Note:_ This map is local to each element. It is used to ensure there + * are no conflicting prefixes should a new namespace prefix attribute need + * to be generated. It is also used to enable skipping of duplicate prefix + * definitions when writing an element's attributes: the map allows the + * algorithm to distinguish between a prefix in the namespace prefix map + * that might be locally-defined (to the current Element) and one that is + * not. + * 8. Let local default namespace be the result of recording the namespace + * information for node given map and local prefixes map. + * + * _Note:_ The above step will update map with any found namespace prefix + * definitions, add the found prefix definitions to the local prefixes map + * and return a local default namespace value defined by a default namespace + * attribute if one exists. Otherwise it returns null. + * 9. Let inherited ns be a copy of namespace. + * 10. Let ns be the value of node's namespaceURI attribute. + */ + let skipEndTag = false; + /** 11. If inherited ns is equal to ns, then: */ + /** + * 11.1. If local default namespace is not null, then set ignore + * namespace definition attribute to true. + * 11.2. If ns is the XML namespace, then append to qualified name the + * concatenation of the string "xml:" and the value of node's localName. + * 11.3. Otherwise, append to qualified name the value of node's + * localName. The node's prefix if it exists, is dropped. + */ + const qualifiedName = node.localName; + /** 11.4. Append the value of qualified name to markup. */ + let markup = "<" + qualifiedName; + /** + * 13. Append to markup the result of the XML serialization of node's + * attributes given map, prefix index, local prefixes map, ignore namespace + * definition attribute flag, and require well-formed flag. + */ + markup += this._serializeAttributes(node, requireWellFormed); + /** + * 14. If ns is the HTML namespace, and the node's list of children is + * empty, and the node's localName matches any one of the following void + * elements: "area", "base", "basefont", "bgsound", "br", "col", "embed", + * "frame", "hr", "img", "input", "keygen", "link", "menuitem", "meta", + * "param", "source", "track", "wbr"; then append the following to markup, + * in the order listed: + * 14.1. " " (U+0020 SPACE); + * 14.2. "/" (U+002F SOLIDUS). + * and set the skip end tag flag to true. + * 15. If ns is not the HTML namespace, and the node's list of children is + * empty, then append "/" (U+002F SOLIDUS) to markup and set the skip end + * tag flag to true. + * 16. Append ">" (U+003E GREATER-THAN SIGN) to markup. + */ + if (node._children.size === 0) { + markup += "/"; + skipEndTag = true; + } + markup += ">"; + /** + * 17. If the value of skip end tag is true, then return the value of markup + * and skip the remaining steps. The node is a leaf-node. + */ + if (skipEndTag) + return markup; + /** + * 18. If ns is the HTML namespace, and the node's localName matches the + * string "template", then this is a template element. Append to markup the + * result of XML serializing a DocumentFragment node given the template + * element's template contents (a DocumentFragment), providing inherited + * ns, map, prefix index, and the require well-formed flag. + * + * _Note:_ This allows template content to round-trip, given the rules for + * parsing XHTML documents. + * + * 19. Otherwise, append to markup the result of running the XML + * serialization algorithm on each of node's children, in tree order, + * providing inherited ns, map, prefix index, and the require well-formed + * flag. + */ + for (const childNode of node._children) { + markup += this._serializeNode(childNode, requireWellFormed); + } + /** + * 20. Append the following to markup, in the order listed: + * 20.1. "" (U+003E GREATER-THAN SIGN). + */ + markup += ""; + /** + * 21. Return the value of markup. + */ + return markup; + } + /** + * Produces an XML serialization of a document node. + * + * @param node - node to serialize + * @param requireWellFormed - whether to check conformance + */ + _serializeDocument(node, requireWellFormed) { + /** + * If the require well-formed flag is set (its value is true), and this node + * has no documentElement (the documentElement attribute's value is null), + * then throw an exception; the serialization of this node would not be a + * well-formed document. + */ + if (requireWellFormed && node.documentElement === null) { + throw new Error("Missing document element (well-formed required)."); + } + /** + * Otherwise, run the following steps: + * 1. Let serialized document be an empty string. + * 2. For each child child of node, in tree order, run the XML + * serialization algorithm on the child passing along the provided + * arguments, and append the result to serialized document. + * + * _Note:_ This will serialize any number of ProcessingInstruction and + * Comment nodes both before and after the Document's documentElement node, + * including at most one DocumentType node. (Text nodes are not allowed as + * children of the Document.) + * + * 3. Return the value of serialized document. + */ + let serializedDocument = ""; + for (const childNode of node._children) { + serializedDocument += this._serializeNode(childNode, requireWellFormed); + } + return serializedDocument; + } + /** + * Produces an XML serialization of a document fragment node. + * + * @param node - node to serialize + * @param requireWellFormed - whether to check conformance + */ + _serializeDocumentFragment(node, requireWellFormed) { + /** + * 1. Let markup the empty string. + * 2. For each child child of node, in tree order, run the XML serialization + * algorithm on the child given namespace, prefix map, a reference to prefix + * index, and flag require well-formed. Concatenate the result to markup. + * 3. Return the value of markup. + */ + let markup = ""; + for (const childNode of node._children) { + markup += this._serializeNode(childNode, requireWellFormed); + } + return markup; + } + /** + * Produces an XML serialization of the attributes of an element node. + * + * @param node - node to serialize + * @param requireWellFormed - whether to check conformance + */ + _serializeAttributes(node, requireWellFormed) { + /** + * 1. Let result be the empty string. + * 2. Let localname set be a new empty namespace localname set. This + * localname set will contain tuples of unique attribute namespaceURI and + * localName pairs, and is populated as each attr is processed. This set is + * used to [optionally] enforce the well-formed constraint that an element + * cannot have two attributes with the same namespaceURI and localName. + * This can occur when two otherwise identical attributes on the same + * element differ only by their prefix values. + */ + let result = ""; + const localNameSet = requireWellFormed ? {} : undefined; + /** + * 3. Loop: For each attribute attr in element's attributes, in the order + * they are specified in the element's attribute list: + */ + for (const attr of node.attributes) { + /** + * 3.1. If the require well-formed flag is set (its value is true), and the + * localname set contains a tuple whose values match those of a new tuple + * consisting of attr's namespaceURI attribute and localName attribute, + * then throw an exception; the serialization of this attr would fail to + * produce a well-formed element serialization. + */ + if (requireWellFormed && localNameSet && (attr.localName in localNameSet)) { + throw new Error("Element contains duplicate attributes (well-formed required)."); + } + /** + * 3.2. Create a new tuple consisting of attr's namespaceURI attribute and + * localName attribute, and add it to the localname set. + * 3.3. Let attribute namespace be the value of attr's namespaceURI value. + * 3.4. Let candidate prefix be null. + */ + if (requireWellFormed && localNameSet) + localNameSet[attr.localName] = true; + /** 3.5. If attribute namespace is not null, then run these sub-steps: */ + /** + * 3.6. Append a " " (U+0020 SPACE) to result. + * 3.7. If candidate prefix is not null, then append to result the + * concatenation of candidate prefix with ":" (U+003A COLON). + */ + /** + * 3.8. If the require well-formed flag is set (its value is true), and + * this attr's localName attribute contains the character + * ":" (U+003A COLON) or does not match the XML Name production or + * equals "xmlns" and attribute namespace is null, then throw an + * exception; the serialization of this attr would not be a + * well-formed attribute. + */ + if (requireWellFormed && (attr.localName.indexOf(":") !== -1 || + !algorithm_1.xml_isName(attr.localName))) { + throw new Error("Attribute local name contains invalid characters (well-formed required)."); + } + /** + * 3.9. Append the following strings to result, in the order listed: + * 3.9.1. The value of attr's localName; + * 3.9.2. "="" (U+003D EQUALS SIGN, U+0022 QUOTATION MARK); + * 3.9.3. The result of serializing an attribute value given attr's value + * attribute and the require well-formed flag as input; + * 3.9.4. """ (U+0022 QUOTATION MARK). + */ + result += " " + attr.localName + "=\"" + + this._serializeAttributeValue(attr.value, requireWellFormed) + "\""; + } + /** + * 4. Return the value of result. + */ + return result; + } +} +exports.XMLSerializerImpl = XMLSerializerImpl; +XMLSerializerImpl._VoidElementNames = new Set(['area', 'base', 'basefont', + 'bgsound', 'br', 'col', 'embed', 'frame', 'hr', 'img', 'input', 'keygen', + 'link', 'menuitem', 'meta', 'param', 'source', 'track', 'wbr']); +//# sourceMappingURL=XMLSerializerImpl.js.map + +/***/ }), + +/***/ 106: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const util_1 = __webpack_require__(337); +/** + * Flattens the given options argument. + * + * @param options - options argument + */ +function eventTarget_flatten(options) { + /** + * 1. If options is a boolean, then return options. + * 2. Return options’s capture. + */ + if (util_1.isBoolean(options)) { + return options; + } + else { + return options.capture || false; + } +} +exports.eventTarget_flatten = eventTarget_flatten; +/** + * Flattens the given options argument. + * + * @param options - options argument + */ +function eventTarget_flattenMore(options) { + /** + * 1. Let capture be the result of flattening options. + * 2. Let once and passive be false. + * 3. If options is a dictionary, then set passive to options’s passive and + * once to options’s once. + * 4. Return capture, passive, and once. + */ + const capture = eventTarget_flatten(options); + let once = false; + let passive = false; + if (!util_1.isBoolean(options)) { + once = options.once || false; + passive = options.passive || false; + } + return [capture, passive, once]; +} +exports.eventTarget_flattenMore = eventTarget_flattenMore; +/** + * Adds a new event listener. + * + * @param eventTarget - event target + * @param listener - event listener + */ +function eventTarget_addEventListener(eventTarget, listener) { + /** + * 1. If eventTarget is a ServiceWorkerGlobalScope object, its service + * worker’s script resource’s has ever been evaluated flag is set, and + * listener’s type matches the type attribute value of any of the service + * worker events, then report a warning to the console that this might not + * give the expected results. [SERVICE-WORKERS] + */ + // TODO: service worker + /** + * 2. If listener’s callback is null, then return. + */ + if (listener.callback === null) + return; + /** + * 3. If eventTarget’s event listener list does not contain an event listener + * whose type is listener’s type, callback is listener’s callback, and capture + * is listener’s capture, then append listener to eventTarget’s event listener + * list. + */ + for (let i = 0; i < eventTarget._eventListenerList.length; i++) { + const entry = eventTarget._eventListenerList[i]; + if (entry.type === listener.type && entry.callback.handleEvent === listener.callback.handleEvent + && entry.capture === listener.capture) { + return; + } + } + eventTarget._eventListenerList.push(listener); +} +exports.eventTarget_addEventListener = eventTarget_addEventListener; +/** + * Removes an event listener. + * + * @param eventTarget - event target + * @param listener - event listener + */ +function eventTarget_removeEventListener(eventTarget, listener, index) { + /** + * 1. If eventTarget is a ServiceWorkerGlobalScope object and its service + * worker’s set of event types to handle contains type, then report a + * warning to the console that this might not give the expected results. + * [SERVICE-WORKERS] + */ + // TODO: service worker + /** + * 2. Set listener’s removed to true and remove listener from eventTarget’s + * event listener list. + */ + listener.removed = true; + eventTarget._eventListenerList.splice(index, 1); +} +exports.eventTarget_removeEventListener = eventTarget_removeEventListener; +/** + * Removes all event listeners. + * + * @param eventTarget - event target + */ +function eventTarget_removeAllEventListeners(eventTarget) { + /** + * To remove all event listeners, given an EventTarget object eventTarget, + * for each listener of eventTarget’s event listener list, remove an event + * listener with eventTarget and listener. + */ + for (const e of eventTarget._eventListenerList) { + e.removed = true; + } + eventTarget._eventListenerList.length = 0; +} +exports.eventTarget_removeAllEventListeners = eventTarget_removeAllEventListeners; +//# sourceMappingURL=EventTargetAlgorithm.js.map + +/***/ }), + +/***/ 108: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const dom_1 = __webpack_require__(113); +const interfaces_1 = __webpack_require__(970); +const util_1 = __webpack_require__(918); +const CustomEventImpl_1 = __webpack_require__(164); +const EventImpl_1 = __webpack_require__(427); +const DOMException_1 = __webpack_require__(35); +const TreeAlgorithm_1 = __webpack_require__(873); +const ShadowTreeAlgorithm_1 = __webpack_require__(180); +const DOMAlgorithm_1 = __webpack_require__(304); +/** + * Sets the canceled flag of an event. + * + * @param event - an event + */ +function event_setTheCanceledFlag(event) { + if (event._cancelable && !event._inPassiveListenerFlag) { + event._canceledFlag = true; + } +} +exports.event_setTheCanceledFlag = event_setTheCanceledFlag; +/** + * Initializes the value of an event. + * + * @param event - an event to initialize + * @param type - the type of event + * @param bubbles - whether the event propagates in reverse + * @param cancelable - whether the event can be cancelled + */ +function event_initialize(event, type, bubbles, cancelable) { + event._initializedFlag = true; + event._stopPropagationFlag = false; + event._stopImmediatePropagationFlag = false; + event._canceledFlag = false; + event._isTrusted = false; + event._target = null; + event._type = type; + event._bubbles = bubbles; + event._cancelable = cancelable; +} +exports.event_initialize = event_initialize; +/** + * Creates a new event. + * + * @param eventInterface - event interface + * @param realm - realm + */ +function event_createAnEvent(eventInterface, realm = undefined) { + /** + * 1. If realm is not given, then set it to null. + * 2. Let dictionary be the result of converting the JavaScript value + * undefined to the dictionary type accepted by eventInterface’s + * constructor. (This dictionary type will either be EventInit or a + * dictionary that inherits from it.) + * 3. Let event be the result of running the inner event creation steps with + * eventInterface, realm, the time of the occurrence that the event is + * signaling, and dictionary. + * 4. Initialize event’s isTrusted attribute to true. + * 5. Return event. + */ + if (realm === undefined) + realm = null; + const dictionary = {}; + const event = event_innerEventCreationSteps(eventInterface, realm, new Date(), dictionary); + event._isTrusted = true; + return event; +} +exports.event_createAnEvent = event_createAnEvent; +/** + * Performs event creation steps. + * + * @param eventInterface - event interface + * @param realm - realm + * @param time - time of occurrance + * @param dictionary - event attributes + * + */ +function event_innerEventCreationSteps(eventInterface, realm, time, dictionary) { + /** + * 1. Let event be the result of creating a new object using eventInterface. + * TODO: Implement realms + * If realm is non-null, then use that Realm; otherwise, use the default + * behavior defined in Web IDL. + */ + const event = new eventInterface(""); + /** + * 2. Set event’s initialized flag. + * 3. Initialize event’s timeStamp attribute to a DOMHighResTimeStamp + * representing the high resolution time from the time origin to time. + * 4. For each member → value in dictionary, if event has an attribute + * whose identifier is member, then initialize that attribute to value. + * 5. Run the event constructing steps with event. + * 6. Return event. + */ + event._initializedFlag = true; + event._timeStamp = time.getTime(); + Object.assign(event, dictionary); + if (dom_1.dom.features.steps) { + DOMAlgorithm_1.dom_runEventConstructingSteps(event); + } + return event; +} +exports.event_innerEventCreationSteps = event_innerEventCreationSteps; +/** + * Dispatches an event to an event target. + * + * @param event - the event to dispatch + * @param target - event target + * @param legacyTargetOverrideFlag - legacy target override flag + * @param legacyOutputDidListenersThrowFlag - legacy output flag that returns + * whether the event listener's callback threw an exception + */ +function event_dispatch(event, target, legacyTargetOverrideFlag = false, legacyOutputDidListenersThrowFlag = { value: false }) { + let clearTargets = false; + /** + * 1. Set event's dispatch flag. + */ + event._dispatchFlag = true; + /** + * 2. Let targetOverride be target, if legacy target override flag is not + * given, and target's associated Document otherwise. + * + * _Note:_ legacy target override flag is only used by HTML and only when + * target is a Window object. + */ + let targetOverride = target; + if (legacyTargetOverrideFlag) { + const doc = target._associatedDocument; + if (util_1.Guard.isDocumentNode(doc)) { + targetOverride = doc; + } + } + /** + * 3. Let activationTarget be null. + * 4. Let relatedTarget be the result of retargeting event's relatedTarget + * against target. + * 5. If target is not relatedTarget or target is event's relatedTarget, + * then: + */ + let activationTarget = null; + let relatedTarget = TreeAlgorithm_1.tree_retarget(event._relatedTarget, target); + if (target !== relatedTarget || target === event._relatedTarget) { + /** + * 5.1. Let touchTargets be a new list. + * 5.2. For each touchTarget of event's touch target list, append the + * result of retargeting touchTarget against target to touchTargets. + * 5.3. Append to an event path with event, target, targetOverride, + * relatedTarget, touchTargets, and false. + * 5.4. Let isActivationEvent be true, if event is a MouseEvent object + * and event's type attribute is "click", and false otherwise. + * 5.5. If isActivationEvent is true and target has activation behavior, + * then set activationTarget to target. + * 5.6. Let slotable be target, if target is a slotable and is assigned, + * and null otherwise. + * 5.7. Let slot-in-closed-tree be false. + * 5.8. Let parent be the result of invoking target's get the parent with + * event. + */ + let touchTargets = []; + for (const touchTarget of event._touchTargetList) { + touchTargets.push(TreeAlgorithm_1.tree_retarget(touchTarget, target)); + } + event_appendToAnEventPath(event, target, targetOverride, relatedTarget, touchTargets, false); + const isActivationEvent = (util_1.Guard.isMouseEvent(event) && event._type === "click"); + if (isActivationEvent && target._activationBehavior !== undefined) { + activationTarget = target; + } + let slotable = (util_1.Guard.isSlotable(target) && ShadowTreeAlgorithm_1.shadowTree_isAssigned(target)) ? + target : null; + let slotInClosedTree = false; + let parent = target._getTheParent(event); + /** + * 5.9. While parent is non-null: + */ + while (parent !== null && util_1.Guard.isNode(parent)) { + /** + * 5.9.1 If slotable is non-null: + * 5.9.1.1. Assert: parent is a slot. + * 5.9.1.2. Set slotable to null. + * 5.9.1.3. If parent's root is a shadow root whose mode is "closed", + * then set slot-in-closed-tree to true. + */ + if (slotable !== null) { + if (!util_1.Guard.isSlot(parent)) { + throw new Error("Parent node of a slotable should be a slot."); + } + slotable = null; + const root = TreeAlgorithm_1.tree_rootNode(parent, true); + if (util_1.Guard.isShadowRoot(root) && root._mode === "closed") { + slotInClosedTree = true; + } + } + /** + * 5.9.2 If parent is a slotable and is assigned, then set slotable to + * parent. + * 5.9.3. Let relatedTarget be the result of retargeting event's + * relatedTarget against parent. + * 5.9.4. Let touchTargets be a new list. + * 5.9.4. For each touchTarget of event's touch target list, append the + * result of retargeting touchTarget against parent to touchTargets. + */ + if (util_1.Guard.isSlotable(parent) && ShadowTreeAlgorithm_1.shadowTree_isAssigned(parent)) { + slotable = parent; + } + relatedTarget = TreeAlgorithm_1.tree_retarget(event._relatedTarget, parent); + touchTargets = []; + for (const touchTarget of event._touchTargetList) { + touchTargets.push(TreeAlgorithm_1.tree_retarget(touchTarget, parent)); + } + /** + * 5.9.6. If parent is a Window object, or parent is a node and target's + * root is a shadow-including inclusive ancestor of parent, then: + */ + if (util_1.Guard.isWindow(parent) || (util_1.Guard.isNode(parent) && util_1.Guard.isNode(target) && + TreeAlgorithm_1.tree_isAncestorOf(TreeAlgorithm_1.tree_rootNode(target, true), parent, true, true))) { + /** + * 5.9.6.1. If isActivationEvent is true, event's bubbles attribute + * is true, activationTarget is null, and parent has activation + * behavior, then set activationTarget to parent. + * 5.9.6.2. Append to an event path with event, parent, null, + * relatedTarget, touchTargets, and slot-in-closed-tree. + */ + if (isActivationEvent && event._bubbles && activationTarget === null && + parent._activationBehavior) { + activationTarget = parent; + } + event_appendToAnEventPath(event, parent, null, relatedTarget, touchTargets, slotInClosedTree); + } + else if (parent === relatedTarget) { + /** + * 5.9.7. Otherwise, if parent is relatedTarget, + * then set parent to null. + */ + parent = null; + } + else { + /** + * 5.9.8. Otherwise, set target to parent and then: + * 5.9.8.1. If isActivationEvent is true, activationTarget is null, + * and target has activation behavior, then set activationTarget + * to target. + * 5.9.8.2. Append to an event path with event, parent, target, + * relatedTarget, touchTargets, and slot-in-closed-tree. + */ + target = parent; + if (isActivationEvent && activationTarget === null && + target._activationBehavior) { + activationTarget = target; + } + event_appendToAnEventPath(event, parent, target, relatedTarget, touchTargets, slotInClosedTree); + } + /** + * 5.9.9. If parent is non-null, then set parent to the result of + * invoking parent's get the parent with event. + * 5.9.10. Set slot-in-closed-tree to false. + */ + if (parent !== null) { + parent = parent._getTheParent(event); + } + slotInClosedTree = false; + } + /** + * 5.10. Let clearTargetsStruct be the last struct in event's path whose + * shadow-adjusted target is non-null. + */ + let clearTargetsStruct = null; + const path = event._path; + for (let i = path.length - 1; i >= 0; i--) { + const struct = path[i]; + if (struct.shadowAdjustedTarget !== null) { + clearTargetsStruct = struct; + break; + } + } + /** + * 5.11. Let clearTargets be true if clearTargetsStruct's shadow-adjusted + * target, clearTargetsStruct's relatedTarget, or an EventTarget object + * in clearTargetsStruct's touch target list is a node and its root is + * a shadow root, and false otherwise. + */ + if (clearTargetsStruct !== null) { + if (util_1.Guard.isNode(clearTargetsStruct.shadowAdjustedTarget) && + util_1.Guard.isShadowRoot(TreeAlgorithm_1.tree_rootNode(clearTargetsStruct.shadowAdjustedTarget, true))) { + clearTargets = true; + } + else if (util_1.Guard.isNode(clearTargetsStruct.relatedTarget) && + util_1.Guard.isShadowRoot(TreeAlgorithm_1.tree_rootNode(clearTargetsStruct.relatedTarget, true))) { + clearTargets = true; + } + else { + for (let j = 0; j < clearTargetsStruct.touchTargetList.length; j++) { + const struct = clearTargetsStruct.touchTargetList[j]; + if (util_1.Guard.isNode(struct) && + util_1.Guard.isShadowRoot(TreeAlgorithm_1.tree_rootNode(struct, true))) { + clearTargets = true; + break; + } + } + } + } + /** + * 5.12. If activationTarget is non-null and activationTarget has + * legacy-pre-activation behavior, then run activationTarget's + * legacy-pre-activation behavior. + */ + if (activationTarget !== null && + activationTarget._legacyPreActivationBehavior !== undefined) { + activationTarget._legacyPreActivationBehavior(event); + } + /** + * 5.13. For each struct in event's path, in reverse order: + */ + for (let i = path.length - 1; i >= 0; i--) { + const struct = path[i]; + /** + * 5.13.1. If struct's shadow-adjusted target is non-null, then set + * event's eventPhase attribute to AT_TARGET. + * 5.13.2. Otherwise, set event's eventPhase attribute to + * CAPTURING_PHASE. + * 5.13.3. Invoke with struct, event, "capturing", and + * legacyOutputDidListenersThrowFlag if given. + */ + if (struct.shadowAdjustedTarget !== null) { + event._eventPhase = interfaces_1.EventPhase.AtTarget; + } + else { + event._eventPhase = interfaces_1.EventPhase.Capturing; + } + event_invoke(struct, event, "capturing", legacyOutputDidListenersThrowFlag); + } + /** + * 5.14. For each struct in event's path + */ + for (let i = 0; i < path.length; i++) { + const struct = path[i]; + /** + * 5.14.1. If struct's shadow-adjusted target is non-null, then set + * event's eventPhase attribute to AT_TARGET. + * 5.14.2. Otherwise: + * 5.14.2.1. If event's bubbles attribute is false, then continue. + * 5.14.2.2. Set event's eventPhase attribute to BUBBLING_PHASE. + * 5.14.3. Invoke with struct, event, "bubbling", and + * legacyOutputDidListenersThrowFlag if given. + */ + if (struct.shadowAdjustedTarget !== null) { + event._eventPhase = interfaces_1.EventPhase.AtTarget; + } + else { + if (!event._bubbles) + continue; + event._eventPhase = interfaces_1.EventPhase.Bubbling; + } + event_invoke(struct, event, "bubbling", legacyOutputDidListenersThrowFlag); + } + } + /** + * 6. Set event's eventPhase attribute to NONE. + * 7. Set event's currentTarget attribute to null. + * 8. Set event's path to the empty list. + * 9. Unset event's dispatch flag, stop propagation flag, and stop + * immediate propagation flag. + */ + event._eventPhase = interfaces_1.EventPhase.None; + event._currentTarget = null; + event._path = []; + event._dispatchFlag = false; + event._stopPropagationFlag = false; + event._stopImmediatePropagationFlag = false; + /** + * 10. If clearTargets, then: + * 10.1. Set event's target to null. + * 10.2. Set event's relatedTarget to null. + * 10.3. Set event's touch target list to the empty list. + */ + if (clearTargets) { + event._target = null; + event._relatedTarget = null; + event._touchTargetList = []; + } + /** + * 11. If activationTarget is non-null, then: + * 11.1. If event's canceled flag is unset, then run activationTarget's + * activation behavior with event. + * 11.2. Otherwise, if activationTarget has legacy-canceled-activation + * behavior, then run activationTarget's legacy-canceled-activation + * behavior. + */ + if (activationTarget !== null) { + if (!event._canceledFlag && activationTarget._activationBehavior !== undefined) { + activationTarget._activationBehavior(event); + } + else if (activationTarget._legacyCanceledActivationBehavior !== undefined) { + activationTarget._legacyCanceledActivationBehavior(event); + } + } + /** + * 12. Return false if event's canceled flag is set, and true otherwise. + */ + return !event._canceledFlag; +} +exports.event_dispatch = event_dispatch; +/** + * Appends a new struct to an event's path. + * + * @param event - an event + * @param invocationTarget - the target of the invocation + * @param shadowAdjustedTarget - shadow-root adjusted event target + * @param relatedTarget - related event target + * @param touchTargets - a list of touch targets + * @param slotInClosedTree - if the target's parent is a closed shadow root + */ +function event_appendToAnEventPath(event, invocationTarget, shadowAdjustedTarget, relatedTarget, touchTargets, slotInClosedTree) { + /** + * 1. Let invocationTargetInShadowTree be false. + * 2. If invocationTarget is a node and its root is a shadow root, then + * set invocationTargetInShadowTree to true. + */ + let invocationTargetInShadowTree = false; + if (util_1.Guard.isNode(invocationTarget) && + util_1.Guard.isShadowRoot(TreeAlgorithm_1.tree_rootNode(invocationTarget))) { + invocationTargetInShadowTree = true; + } + /** + * 3. Let root-of-closed-tree be false. + * 4. If invocationTarget is a shadow root whose mode is "closed", then + * set root-of-closed-tree to true. + */ + let rootOfClosedTree = false; + if (util_1.Guard.isShadowRoot(invocationTarget) && + invocationTarget._mode === "closed") { + rootOfClosedTree = true; + } + /** + * 5. Append a new struct to event's path whose invocation target is + * invocationTarget, invocation-target-in-shadow-tree is + * invocationTargetInShadowTree, shadow-adjusted target is + * shadowAdjustedTarget, relatedTarget is relatedTarget, + * touch target list is touchTargets, root-of-closed-tree is + * root-of-closed-tree, and slot-in-closed-tree is slot-in-closed-tree. + */ + event._path.push({ + invocationTarget: invocationTarget, + invocationTargetInShadowTree: invocationTargetInShadowTree, + shadowAdjustedTarget: shadowAdjustedTarget, + relatedTarget: relatedTarget, + touchTargetList: touchTargets, + rootOfClosedTree: rootOfClosedTree, + slotInClosedTree: slotInClosedTree + }); +} +exports.event_appendToAnEventPath = event_appendToAnEventPath; +/** + * Invokes an event. + * + * @param struct - a struct defining event's path + * @param event - the event to invoke + * @param phase - event phase + * @param legacyOutputDidListenersThrowFlag - legacy output flag that returns + * whether the event listener's callback threw an exception + */ +function event_invoke(struct, event, phase, legacyOutputDidListenersThrowFlag = { value: false }) { + /** + * 1. Set event's target to the shadow-adjusted target of the last struct + * in event's path, that is either struct or preceding struct, whose + * shadow-adjusted target is non-null. + */ + const path = event._path; + let index = -1; + for (let i = 0; i < path.length; i++) { + if (path[i] === struct) { + index = i; + break; + } + } + if (index !== -1) { + let item = path[index]; + if (item.shadowAdjustedTarget !== null) { + event._target = item.shadowAdjustedTarget; + } + else if (index > 0) { + item = path[index - 1]; + if (item.shadowAdjustedTarget !== null) { + event._target = item.shadowAdjustedTarget; + } + } + } + /** + * 2. Set event's relatedTarget to struct's relatedTarget. + * 3. Set event's touch target list to struct's touch target list. + * 4. If event's stop propagation flag is set, then return. + * 5. Initialize event's currentTarget attribute to struct's invocation + * target. + * 6. Let listeners be a clone of event's currentTarget attribute value's + * event listener list. + * + * _Note:_ This avoids event listeners added after this point from being + * run. Note that removal still has an effect due to the removed field. + */ + event._relatedTarget = struct.relatedTarget; + event._touchTargetList = struct.touchTargetList; + if (event._stopPropagationFlag) + return; + event._currentTarget = struct.invocationTarget; + const currentTarget = event._currentTarget; + const targetListeners = currentTarget._eventListenerList; + let listeners = new Array(...targetListeners); + /** + * 7. Let found be the result of running inner invoke with event, listeners, + * phase, and legacyOutputDidListenersThrowFlag if given. + */ + const found = event_innerInvoke(event, listeners, phase, struct, legacyOutputDidListenersThrowFlag); + /** + * 8. If found is false and event's isTrusted attribute is true, then: + */ + if (!found && event._isTrusted) { + /** + * 8.1. Let originalEventType be event's type attribute value. + * 8.2. If event's type attribute value is a match for any of the strings + * in the first column in the following table, set event's type attribute + * value to the string in the second column on the same row as the matching + * string, and return otherwise. + * + * Event type | Legacy event type + * ------------------------------------------------- + * "animationend" | "webkitAnimationEnd" + * "animationiteration" | "webkitAnimationIteration" + * "animationstart" | "webkitAnimationStart" + * "transitionend" | "webkitTransitionEnd" + */ + const originalEventType = event._type; + if (originalEventType === "animationend") { + event._type = "webkitAnimationEnd"; + } + else if (originalEventType === "animationiteration") { + event._type = "webkitAnimationIteration"; + } + else if (originalEventType === "animationstart") { + event._type = "webkitAnimationStart"; + } + else if (originalEventType === "transitionend") { + event._type = "webkitTransitionEnd"; + } + /** + * 8.3. Inner invoke with event, listeners, phase, and + * legacyOutputDidListenersThrowFlag if given. + * 8.4. Set event's type attribute value to originalEventType. + */ + event_innerInvoke(event, listeners, phase, struct, legacyOutputDidListenersThrowFlag); + event._type = originalEventType; + } +} +exports.event_invoke = event_invoke; +/** + * Invokes an event. + * + * @param event - the event to invoke + * @param listeners - event listeners + * @param phase - event phase + * @param struct - a struct defining event's path + * @param legacyOutputDidListenersThrowFlag - legacy output flag that returns + * whether the event listener's callback threw an exception + */ +function event_innerInvoke(event, listeners, phase, struct, legacyOutputDidListenersThrowFlag = { value: false }) { + /** + * 1. Let found be false. + * 2. For each listener in listeners, whose removed is false: + */ + let found = false; + for (let i = 0; i < listeners.length; i++) { + const listener = listeners[i]; + if (!listener.removed) { + /** + * 2.1. If event's type attribute value is not listener's type, then + * continue. + * 2.2. Set found to true. + * 2.3. If phase is "capturing" and listener's capture is false, then + * continue. + * 2.4. If phase is "bubbling" and listener's capture is true, then + * continue. + */ + if (event._type !== listener.type) + continue; + found = true; + if (phase === "capturing" && !listener.capture) + continue; + if (phase === "bubbling" && listener.capture) + continue; + /** + * 2.5. If listener's once is true, then remove listener from event's + * currentTarget attribute value's event listener list. + */ + if (listener.once && event._currentTarget !== null) { + const impl = event._currentTarget; + let index = -1; + for (let i = 0; i < impl._eventListenerList.length; i++) { + if (impl._eventListenerList[i] === listener) { + index = i; + break; + } + } + if (index !== -1) { + impl._eventListenerList.splice(index, 1); + } + } + /** + * TODO: Implement realms + * + * 2.6. Let global be listener callback's associated Realm's global + * object. + */ + const globalObject = undefined; + /** + * 2.7. Let currentEvent be undefined. + * 2.8. If global is a Window object, then: + * 2.8.1. Set currentEvent to global's current event. + * 2.8.2. If struct's invocation-target-in-shadow-tree is false, then + * set global's current event to event. + */ + let currentEvent = undefined; + if (util_1.Guard.isWindow(globalObject)) { + currentEvent = globalObject._currentEvent; + if (struct.invocationTargetInShadowTree === false) { + globalObject._currentEvent = event; + } + } + /** + * 2.9. If listener's passive is true, then set event's in passive + * listener flag. + * 2.10. Call a user object's operation with listener's callback, + * "handleEvent", « event », and event's currentTarget attribute value. + */ + if (listener.passive) + event._inPassiveListenerFlag = true; + try { + listener.callback.handleEvent.call(event._currentTarget, event); + } + catch (err) { + /** + * If this throws an exception, then: + * 2.10.1. Report the exception. + * 2.10.2. Set legacyOutputDidListenersThrowFlag if given. + * + * _Note:_ The legacyOutputDidListenersThrowFlag is only used by + * Indexed Database API. + * TODO: Report the exception + * See: https://html.spec.whatwg.org/multipage/webappapis.html#runtime-script-errors-in-documents + */ + legacyOutputDidListenersThrowFlag.value = true; + } + /** + * 2.11. Unset event's in passive listener flag. + */ + if (listener.passive) + event._inPassiveListenerFlag = false; + /** + * 2.12. If global is a Window object, then set global's current event + * to currentEvent. + */ + if (util_1.Guard.isWindow(globalObject)) { + globalObject._currentEvent = currentEvent; + } + /** + * 2.13. If event's stop immediate propagation flag is set, then return + * found. + */ + if (event._stopImmediatePropagationFlag) + return found; + } + } + /** + * 3. Return found. + */ + return found; +} +exports.event_innerInvoke = event_innerInvoke; +/** + * Fires an event at target. + * @param e - event name + * @param target - event target + * @param eventConstructor - an event constructor, with a description of how + * IDL attributes are to be initialized + * @param idlAttributes - a dictionary describing how IDL attributes are + * to be initialized + * @param legacyTargetOverrideFlag - legacy target override flag + */ +function event_fireAnEvent(e, target, eventConstructor, idlAttributes, legacyTargetOverrideFlag) { + /** + * 1. If eventConstructor is not given, then let eventConstructor be Event. + */ + if (eventConstructor === undefined) { + eventConstructor = EventImpl_1.EventImpl; + } + /** + * 2. Let event be the result of creating an event given eventConstructor, + * in the relevant Realm of target. + */ + const event = event_createAnEvent(eventConstructor); + /** + * 3. Initialize event’s type attribute to e. + */ + event._type = e; + /** + * 4. Initialize any other IDL attributes of event as described in the + * invocation of this algorithm. + * _Note:_ This also allows for the isTrusted attribute to be set to false. + */ + if (idlAttributes) { + for (const key in idlAttributes) { + const idlObj = event; + idlObj[key] = idlAttributes[key]; + } + } + /** + * 5. Return the result of dispatching event at target, with legacy target + * override flag set if set. + */ + return event_dispatch(event, target, legacyTargetOverrideFlag); +} +exports.event_fireAnEvent = event_fireAnEvent; +/** + * Creates an event. + * + * @param eventInterface - the name of the event interface + */ +function event_createLegacyEvent(eventInterface) { + /** + * 1. Let constructor be null. + */ + let constructor = null; + /** + * TODO: Implement in HTML DOM + * 2. If interface is an ASCII case-insensitive match for any of the strings + * in the first column in the following table, then set constructor to the + * interface in the second column on the same row as the matching string: + * + * String | Interface + * -------|---------- + * "beforeunloadevent" | BeforeUnloadEvent + * "compositionevent" | CompositionEvent + * "customevent" | CustomEvent + * "devicemotionevent" | DeviceMotionEvent + * "deviceorientationevent" | DeviceOrientationEvent + * "dragevent" | DragEvent + * "event" | Event + * "events" | Event + * "focusevent" | FocusEvent + * "hashchangeevent" | HashChangeEvent + * "htmlevents" | Event + * "keyboardevent" | KeyboardEvent + * "messageevent" | MessageEvent + * "mouseevent" | MouseEvent + * "mouseevents" | + * "storageevent" | StorageEvent + * "svgevents" | Event + * "textevent" | CompositionEvent + * "touchevent" | TouchEvent + * "uievent" | UIEvent + * "uievents" | UIEvent + */ + switch (eventInterface.toLowerCase()) { + case "beforeunloadevent": + break; + case "compositionevent": + break; + case "customevent": + constructor = CustomEventImpl_1.CustomEventImpl; + break; + case "devicemotionevent": + break; + case "deviceorientationevent": + break; + case "dragevent": + break; + case "event": + case "events": + constructor = EventImpl_1.EventImpl; + break; + case "focusevent": + break; + case "hashchangeevent": + break; + case "htmlevents": + break; + case "keyboardevent": + break; + case "messageevent": + break; + case "mouseevent": + break; + case "mouseevents": + break; + case "storageevent": + break; + case "svgevents": + break; + case "textevent": + break; + case "touchevent": + break; + case "uievent": + break; + case "uievents": + break; + } + /** + * 3. If constructor is null, then throw a "NotSupportedError" DOMException. + */ + if (constructor === null) { + throw new DOMException_1.NotSupportedError(`Event constructor not found for interface ${eventInterface}.`); + } + /** + * 4. If the interface indicated by constructor is not exposed on the + * relevant global object of the context object, then throw a + * "NotSupportedError" DOMException. + * _Note:_ Typically user agents disable support for touch events in some + * configurations, in which case this clause would be triggered for the + * interface TouchEvent. + */ + // TODO: Implement realms + /** + * 5. Let event be the result of creating an event given constructor. + * 6. Initialize event’s type attribute to the empty string. + * 7. Initialize event’s timeStamp attribute to a DOMHighResTimeStamp + * representing the high resolution time from the time origin to now. + * 8. Initialize event’s isTrusted attribute to false. + * 9. Unset event’s initialized flag. + */ + const event = new constructor(""); + event._type = ""; + event._timeStamp = new Date().getTime(); + event._isTrusted = false; + event._initializedFlag = false; + /** + * 10. Return event. + */ + return event; +} +exports.event_createLegacyEvent = event_createLegacyEvent; +/** + * Getter of an event handler IDL attribute. + * + * @param eventTarget - event target + * @param name - event name + */ +function event_getterEventHandlerIDLAttribute(thisObj, name) { + /** + * 1. Let eventTarget be the result of determining the target of an event + * handler given this object and name. + * 2. If eventTarget is null, then return null. + * 3. Return the result of getting the current value of the event handler + * given eventTarget and name. + */ + const eventTarget = event_determineTheTargetOfAnEventHandler(thisObj, name); + if (eventTarget === null) + return null; + return event_getTheCurrentValueOfAnEventHandler(eventTarget, name); +} +exports.event_getterEventHandlerIDLAttribute = event_getterEventHandlerIDLAttribute; +/** + * Setter of an event handler IDL attribute. + * + * @param eventTarget - event target + * @param name - event name + * @param value - event handler + */ +function event_setterEventHandlerIDLAttribute(thisObj, name, value) { + /** + * 1. Let eventTarget be the result of determining the target of an event + * handler given this object and name. + * 2. If eventTarget is null, then return. + * 3. If the given value is null, then deactivate an event handler given + * eventTarget and name. + * 4. Otherwise: + * 4.1. Let handlerMap be eventTarget's event handler map. + * 4.2. Let eventHandler be handlerMap[name]. + * 4.3. Set eventHandler's value to the given value. + * 4.4. Activate an event handler given eventTarget and name. + */ + const eventTarget = event_determineTheTargetOfAnEventHandler(thisObj, name); + if (eventTarget === null) + return; + if (value === null) { + event_deactivateAnEventHandler(eventTarget, name); + } + else { + const handlerMap = eventTarget._eventHandlerMap; + const eventHandler = handlerMap["onabort"]; + if (eventHandler !== undefined) { + eventHandler.value = value; + } + event_activateAnEventHandler(eventTarget, name); + } +} +exports.event_setterEventHandlerIDLAttribute = event_setterEventHandlerIDLAttribute; +/** + * Determines the target of an event handler. + * + * @param eventTarget - event target + * @param name - event name + */ +function event_determineTheTargetOfAnEventHandler(eventTarget, name) { + // TODO: Implement in HTML DOM + return null; +} +exports.event_determineTheTargetOfAnEventHandler = event_determineTheTargetOfAnEventHandler; +/** + * Gets the current value of an event handler. + * + * @param eventTarget - event target + * @param name - event name + */ +function event_getTheCurrentValueOfAnEventHandler(eventTarget, name) { + // TODO: Implement in HTML DOM + return null; +} +exports.event_getTheCurrentValueOfAnEventHandler = event_getTheCurrentValueOfAnEventHandler; +/** + * Activates an event handler. + * + * @param eventTarget - event target + * @param name - event name + */ +function event_activateAnEventHandler(eventTarget, name) { + // TODO: Implement in HTML DOM +} +exports.event_activateAnEventHandler = event_activateAnEventHandler; +/** + * Deactivates an event handler. + * + * @param eventTarget - event target + * @param name - event name + */ +function event_deactivateAnEventHandler(eventTarget, name) { + // TODO: Implement in HTML DOM +} +exports.event_deactivateAnEventHandler = event_deactivateAnEventHandler; +//# sourceMappingURL=EventAlgorithm.js.map + +/***/ }), + +/***/ 113: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const util_1 = __webpack_require__(337); +// Import implementation classes +const AbortControllerImpl_1 = __webpack_require__(990); +exports.AbortController = AbortControllerImpl_1.AbortControllerImpl; +const AbortSignalImpl_1 = __webpack_require__(784); +exports.AbortSignal = AbortSignalImpl_1.AbortSignalImpl; +const AbstractRangeImpl_1 = __webpack_require__(537); +exports.AbstractRange = AbstractRangeImpl_1.AbstractRangeImpl; +const AttrImpl_1 = __webpack_require__(866); +exports.Attr = AttrImpl_1.AttrImpl; +const CDATASectionImpl_1 = __webpack_require__(920); +exports.CDATASection = CDATASectionImpl_1.CDATASectionImpl; +const CharacterDataImpl_1 = __webpack_require__(43); +exports.CharacterData = CharacterDataImpl_1.CharacterDataImpl; +const ChildNodeImpl_1 = __webpack_require__(983); +const CommentImpl_1 = __webpack_require__(760); +exports.Comment = CommentImpl_1.CommentImpl; +const CustomEventImpl_1 = __webpack_require__(164); +exports.CustomEvent = CustomEventImpl_1.CustomEventImpl; +const DocumentFragmentImpl_1 = __webpack_require__(796); +exports.DocumentFragment = DocumentFragmentImpl_1.DocumentFragmentImpl; +const DocumentImpl_1 = __webpack_require__(488); +exports.Document = DocumentImpl_1.DocumentImpl; +const DocumentOrShadowRootImpl_1 = __webpack_require__(247); +const DocumentTypeImpl_1 = __webpack_require__(558); +exports.DocumentType = DocumentTypeImpl_1.DocumentTypeImpl; +const DOMImpl_1 = __webpack_require__(648); +exports.dom = DOMImpl_1.dom; +const DOMImplementationImpl_1 = __webpack_require__(290); +exports.DOMImplementation = DOMImplementationImpl_1.DOMImplementationImpl; +const DOMTokenListImpl_1 = __webpack_require__(742); +exports.DOMTokenList = DOMTokenListImpl_1.DOMTokenListImpl; +const ElementImpl_1 = __webpack_require__(695); +exports.Element = ElementImpl_1.ElementImpl; +const EventImpl_1 = __webpack_require__(427); +exports.Event = EventImpl_1.EventImpl; +const EventTargetImpl_1 = __webpack_require__(597); +exports.EventTarget = EventTargetImpl_1.EventTargetImpl; +const HTMLCollectionImpl_1 = __webpack_require__(204); +exports.HTMLCollection = HTMLCollectionImpl_1.HTMLCollectionImpl; +const MutationObserverImpl_1 = __webpack_require__(175); +exports.MutationObserver = MutationObserverImpl_1.MutationObserverImpl; +const MutationRecordImpl_1 = __webpack_require__(730); +exports.MutationRecord = MutationRecordImpl_1.MutationRecordImpl; +const NamedNodeMapImpl_1 = __webpack_require__(88); +exports.NamedNodeMap = NamedNodeMapImpl_1.NamedNodeMapImpl; +const NodeFilterImpl_1 = __webpack_require__(774); +exports.NodeFilter = NodeFilterImpl_1.NodeFilterImpl; +const NodeImpl_1 = __webpack_require__(935); +exports.Node = NodeImpl_1.NodeImpl; +const NodeIteratorImpl_1 = __webpack_require__(800); +exports.NodeIterator = NodeIteratorImpl_1.NodeIteratorImpl; +const NodeListImpl_1 = __webpack_require__(636); +exports.NodeList = NodeListImpl_1.NodeListImpl; +const NodeListStaticImpl_1 = __webpack_require__(266); +exports.NodeListStatic = NodeListStaticImpl_1.NodeListStaticImpl; +const NonDocumentTypeChildNodeImpl_1 = __webpack_require__(18); +const NonElementParentNodeImpl_1 = __webpack_require__(574); +const ParentNodeImpl_1 = __webpack_require__(934); +const ProcessingInstructionImpl_1 = __webpack_require__(619); +exports.ProcessingInstruction = ProcessingInstructionImpl_1.ProcessingInstructionImpl; +const RangeImpl_1 = __webpack_require__(90); +exports.Range = RangeImpl_1.RangeImpl; +const ShadowRootImpl_1 = __webpack_require__(581); +exports.ShadowRoot = ShadowRootImpl_1.ShadowRootImpl; +const SlotableImpl_1 = __webpack_require__(476); +const StaticRangeImpl_1 = __webpack_require__(688); +exports.StaticRange = StaticRangeImpl_1.StaticRangeImpl; +const TextImpl_1 = __webpack_require__(820); +exports.Text = TextImpl_1.TextImpl; +const TraverserImpl_1 = __webpack_require__(487); +exports.Traverser = TraverserImpl_1.TraverserImpl; +const TreeWalkerImpl_1 = __webpack_require__(646); +exports.TreeWalker = TreeWalkerImpl_1.TreeWalkerImpl; +const WindowImpl_1 = __webpack_require__(932); +exports.Window = WindowImpl_1.WindowImpl; +const XMLDocumentImpl_1 = __webpack_require__(661); +exports.XMLDocument = XMLDocumentImpl_1.XMLDocumentImpl; +// Apply mixins +// ChildNode +util_1.applyMixin(ElementImpl_1.ElementImpl, ChildNodeImpl_1.ChildNodeImpl); +util_1.applyMixin(CharacterDataImpl_1.CharacterDataImpl, ChildNodeImpl_1.ChildNodeImpl); +util_1.applyMixin(DocumentTypeImpl_1.DocumentTypeImpl, ChildNodeImpl_1.ChildNodeImpl); +// DocumentOrShadowRoot +util_1.applyMixin(DocumentImpl_1.DocumentImpl, DocumentOrShadowRootImpl_1.DocumentOrShadowRootImpl); +util_1.applyMixin(ShadowRootImpl_1.ShadowRootImpl, DocumentOrShadowRootImpl_1.DocumentOrShadowRootImpl); +// NonDocumentTypeChildNode +util_1.applyMixin(ElementImpl_1.ElementImpl, NonDocumentTypeChildNodeImpl_1.NonDocumentTypeChildNodeImpl); +util_1.applyMixin(CharacterDataImpl_1.CharacterDataImpl, NonDocumentTypeChildNodeImpl_1.NonDocumentTypeChildNodeImpl); +// NonElementParentNode +util_1.applyMixin(DocumentImpl_1.DocumentImpl, NonElementParentNodeImpl_1.NonElementParentNodeImpl); +util_1.applyMixin(DocumentFragmentImpl_1.DocumentFragmentImpl, NonElementParentNodeImpl_1.NonElementParentNodeImpl); +// ParentNode +util_1.applyMixin(DocumentImpl_1.DocumentImpl, ParentNodeImpl_1.ParentNodeImpl); +util_1.applyMixin(DocumentFragmentImpl_1.DocumentFragmentImpl, ParentNodeImpl_1.ParentNodeImpl); +util_1.applyMixin(ElementImpl_1.ElementImpl, ParentNodeImpl_1.ParentNodeImpl); +// Slotable +util_1.applyMixin(TextImpl_1.TextImpl, SlotableImpl_1.SlotableImpl); +util_1.applyMixin(ElementImpl_1.ElementImpl, SlotableImpl_1.SlotableImpl); +//# sourceMappingURL=index.js.map + +/***/ }), + +/***/ 129: +/***/ (function(module) { + +module.exports = require("child_process"); + +/***/ }), + +/***/ 134: +/***/ (function(__unusedmodule, exports) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * Pushes the given item to the stack. + * + * @param list - a list + * @param item - an item + */ +function push(list, item) { + list.push(item); +} +exports.push = push; +/** + * Pops and returns an item from the stack. + * + * @param list - a list + */ +function pop(list) { + return list.pop() || null; +} +exports.pop = pop; +//# sourceMappingURL=Stack.js.map + +/***/ }), + +/***/ 139: +/***/ (function(module, __unusedexports, __webpack_require__) { + +// Unique ID creation requires a high quality random # generator. In node.js +// this is pretty straight-forward - we use the crypto API. + +var crypto = __webpack_require__(417); + +module.exports = function nodeRNG() { + return crypto.randomBytes(16); +}; + + +/***/ }), + +/***/ 141: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + + +var net = __webpack_require__(631); +var tls = __webpack_require__(16); +var http = __webpack_require__(605); +var https = __webpack_require__(211); +var events = __webpack_require__(614); +var assert = __webpack_require__(357); +var util = __webpack_require__(669); + + +exports.httpOverHttp = httpOverHttp; +exports.httpsOverHttp = httpsOverHttp; +exports.httpOverHttps = httpOverHttps; +exports.httpsOverHttps = httpsOverHttps; + + +function httpOverHttp(options) { + var agent = new TunnelingAgent(options); + agent.request = http.request; + return agent; +} + +function httpsOverHttp(options) { + var agent = new TunnelingAgent(options); + agent.request = http.request; + agent.createSocket = createSecureSocket; + agent.defaultPort = 443; + return agent; +} + +function httpOverHttps(options) { + var agent = new TunnelingAgent(options); + agent.request = https.request; + return agent; +} + +function httpsOverHttps(options) { + var agent = new TunnelingAgent(options); + agent.request = https.request; + agent.createSocket = createSecureSocket; + agent.defaultPort = 443; + return agent; +} + + +function TunnelingAgent(options) { + var self = this; + self.options = options || {}; + self.proxyOptions = self.options.proxy || {}; + self.maxSockets = self.options.maxSockets || http.Agent.defaultMaxSockets; + self.requests = []; + self.sockets = []; + + self.on('free', function onFree(socket, host, port, localAddress) { + var options = toOptions(host, port, localAddress); + for (var i = 0, len = self.requests.length; i < len; ++i) { + var pending = self.requests[i]; + if (pending.host === options.host && pending.port === options.port) { + // Detect the request to connect same origin server, + // reuse the connection. + self.requests.splice(i, 1); + pending.request.onSocket(socket); + return; + } + } + socket.destroy(); + self.removeSocket(socket); + }); +} +util.inherits(TunnelingAgent, events.EventEmitter); + +TunnelingAgent.prototype.addRequest = function addRequest(req, host, port, localAddress) { + var self = this; + var options = mergeOptions({request: req}, self.options, toOptions(host, port, localAddress)); + + if (self.sockets.length >= this.maxSockets) { + // We are over limit so we'll add it to the queue. + self.requests.push(options); + return; + } + + // If we are under maxSockets create a new one. + self.createSocket(options, function(socket) { + socket.on('free', onFree); + socket.on('close', onCloseOrRemove); + socket.on('agentRemove', onCloseOrRemove); + req.onSocket(socket); + + function onFree() { + self.emit('free', socket, options); + } + + function onCloseOrRemove(err) { + self.removeSocket(socket); + socket.removeListener('free', onFree); + socket.removeListener('close', onCloseOrRemove); + socket.removeListener('agentRemove', onCloseOrRemove); + } + }); +}; + +TunnelingAgent.prototype.createSocket = function createSocket(options, cb) { + var self = this; + var placeholder = {}; + self.sockets.push(placeholder); + + var connectOptions = mergeOptions({}, self.proxyOptions, { + method: 'CONNECT', + path: options.host + ':' + options.port, + agent: false, + headers: { + host: options.host + ':' + options.port + } + }); + if (options.localAddress) { + connectOptions.localAddress = options.localAddress; + } + if (connectOptions.proxyAuth) { + connectOptions.headers = connectOptions.headers || {}; + connectOptions.headers['Proxy-Authorization'] = 'Basic ' + + new Buffer(connectOptions.proxyAuth).toString('base64'); + } + + debug('making CONNECT request'); + var connectReq = self.request(connectOptions); + connectReq.useChunkedEncodingByDefault = false; // for v0.6 + connectReq.once('response', onResponse); // for v0.6 + connectReq.once('upgrade', onUpgrade); // for v0.6 + connectReq.once('connect', onConnect); // for v0.7 or later + connectReq.once('error', onError); + connectReq.end(); + + function onResponse(res) { + // Very hacky. This is necessary to avoid http-parser leaks. + res.upgrade = true; + } + + function onUpgrade(res, socket, head) { + // Hacky. + process.nextTick(function() { + onConnect(res, socket, head); + }); + } + + function onConnect(res, socket, head) { + connectReq.removeAllListeners(); + socket.removeAllListeners(); + + if (res.statusCode !== 200) { + debug('tunneling socket could not be established, statusCode=%d', + res.statusCode); + socket.destroy(); + var error = new Error('tunneling socket could not be established, ' + + 'statusCode=' + res.statusCode); + error.code = 'ECONNRESET'; + options.request.emit('error', error); + self.removeSocket(placeholder); + return; + } + if (head.length > 0) { + debug('got illegal response body from proxy'); + socket.destroy(); + var error = new Error('got illegal response body from proxy'); + error.code = 'ECONNRESET'; + options.request.emit('error', error); + self.removeSocket(placeholder); + return; + } + debug('tunneling connection has established'); + self.sockets[self.sockets.indexOf(placeholder)] = socket; + return cb(socket); + } + + function onError(cause) { + connectReq.removeAllListeners(); + + debug('tunneling socket could not be established, cause=%s\n', + cause.message, cause.stack); + var error = new Error('tunneling socket could not be established, ' + + 'cause=' + cause.message); + error.code = 'ECONNRESET'; + options.request.emit('error', error); + self.removeSocket(placeholder); + } +}; + +TunnelingAgent.prototype.removeSocket = function removeSocket(socket) { + var pos = this.sockets.indexOf(socket) + if (pos === -1) { + return; + } + this.sockets.splice(pos, 1); + + var pending = this.requests.shift(); + if (pending) { + // If we have pending requests and a socket gets closed a new one + // needs to be created to take over in the pool for the one that closed. + this.createSocket(pending, function(socket) { + pending.request.onSocket(socket); + }); + } +}; + +function createSecureSocket(options, cb) { + var self = this; + TunnelingAgent.prototype.createSocket.call(self, options, function(socket) { + var hostHeader = options.request.getHeader('host'); + var tlsOptions = mergeOptions({}, self.options, { + socket: socket, + servername: hostHeader ? hostHeader.replace(/:.*$/, '') : options.host + }); + + // 0 is dummy port for v0.6 + var secureSocket = tls.connect(0, tlsOptions); + self.sockets[self.sockets.indexOf(socket)] = secureSocket; + cb(secureSocket); + }); +} + + +function toOptions(host, port, localAddress) { + if (typeof host === 'string') { // since v0.10 + return { + host: host, + port: port, + localAddress: localAddress + }; + } + return host; // for v0.11 or later +} + +function mergeOptions(target) { + for (var i = 1, len = arguments.length; i < len; ++i) { + var overrides = arguments[i]; + if (typeof overrides === 'object') { + var keys = Object.keys(overrides); + for (var j = 0, keyLen = keys.length; j < keyLen; ++j) { + var k = keys[j]; + if (overrides[k] !== undefined) { + target[k] = overrides[k]; + } + } + } + } + return target; +} + + +var debug; +if (process.env.NODE_DEBUG && /\btunnel\b/.test(process.env.NODE_DEBUG)) { + debug = function() { + var args = Array.prototype.slice.call(arguments); + if (typeof args[0] === 'string') { + args[0] = 'TUNNEL: ' + args[0]; + } else { + args.unshift('TUNNEL:'); + } + console.error.apply(console, args); + } +} else { + debug = function() {}; +} +exports.debug = debug; // for test + + +/***/ }), + +/***/ 146: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const infra_1 = __webpack_require__(23); +/** + * Converts a whitespace separated string into an array of tokens. + * + * @param value - a string of whitespace separated tokens + */ +function orderedSet_parse(value) { + /** + * 1. Let inputTokens be the result of splitting input on ASCII whitespace. + * 2. Let tokens be a new ordered set. + * 3. For each token in inputTokens, append token to tokens. + * 4. Return tokens. + */ + const inputTokens = infra_1.string.splitAStringOnASCIIWhitespace(value); + return new Set(inputTokens); +} +exports.orderedSet_parse = orderedSet_parse; +/** + * Converts an array of tokens into a space separated string. + * + * @param tokens - an array of token strings + */ +function orderedSet_serialize(tokens) { + /** + * The ordered set serializer takes a set and returns the concatenation of + * set using U+0020 SPACE. + */ + return [...tokens].join(' '); +} +exports.orderedSet_serialize = orderedSet_serialize; +/** + * Removes duplicate tokens and convert all whitespace characters + * to space. + * + * @param value - a string of whitespace separated tokens + */ +function orderedSet_sanitize(value) { + return orderedSet_serialize(orderedSet_parse(value)); +} +exports.orderedSet_sanitize = orderedSet_sanitize; +/** + * Determines whether a set contains the other. + * + * @param set1 - a set + * @param set1 - a set that is contained in set1 + * @param caseSensitive - whether matches are case-sensitive + */ +function orderedSet_contains(set1, set2, caseSensitive) { + for (const val2 of set2) { + let found = false; + for (const val1 of set1) { + if (caseSensitive) { + if (val1 === val2) { + found = true; + break; + } + } + else { + if (val1.toUpperCase() === val2.toUpperCase()) { + found = true; + break; + } + } + } + if (!found) + return false; + } + return true; +} +exports.orderedSet_contains = orderedSet_contains; +//# sourceMappingURL=OrderedSetAlgorithm.js.map + +/***/ }), + +/***/ 151: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const dom_1 = __webpack_require__(113); +const util_1 = __webpack_require__(918); +const infra_1 = __webpack_require__(23); +const CreateAlgorithm_1 = __webpack_require__(86); +const TreeAlgorithm_1 = __webpack_require__(873); +const EventAlgorithm_1 = __webpack_require__(108); +/** + * Queues a mutation observer microtask to the surrounding agent’s mutation + * observers. + */ +function observer_queueAMutationObserverMicrotask() { + /** + * 1. If the surrounding agent’s mutation observer microtask queued is true, + * then return. + * 2. Set the surrounding agent’s mutation observer microtask queued to true. + * 3. Queue a microtask to notify mutation observers. + */ + const window = dom_1.dom.window; + if (window._mutationObserverMicrotaskQueued) + return; + window._mutationObserverMicrotaskQueued = true; + Promise.resolve().then(() => { observer_notifyMutationObservers(); }); +} +exports.observer_queueAMutationObserverMicrotask = observer_queueAMutationObserverMicrotask; +/** + * Notifies the surrounding agent’s mutation observers. + */ +function observer_notifyMutationObservers() { + /** + * 1. Set the surrounding agent’s mutation observer microtask queued to false. + * 2. Let notifySet be a clone of the surrounding agent’s mutation observers. + * 3. Let signalSet be a clone of the surrounding agent’s signal slots. + * 4. Empty the surrounding agent’s signal slots. + */ + const window = dom_1.dom.window; + window._mutationObserverMicrotaskQueued = false; + const notifySet = infra_1.set.clone(window._mutationObservers); + const signalSet = infra_1.set.clone(window._signalSlots); + infra_1.set.empty(window._signalSlots); + /** + * 5. For each mo of notifySet: + */ + for (const mo of notifySet) { + /** + * 5.1. Let records be a clone of mo’s record queue. + * 5.2. Empty mo’s record queue. + */ + const records = infra_1.list.clone(mo._recordQueue); + infra_1.list.empty(mo._recordQueue); + /** + * 5.3. For each node of mo’s node list, remove all transient registered + * observers whose observer is mo from node’s registered observer list. + */ + for (let i = 0; i < mo._nodeList.length; i++) { + const node = mo._nodeList[i]; + infra_1.list.remove(node._registeredObserverList, (observer) => { + return util_1.Guard.isTransientRegisteredObserver(observer) && observer.observer === mo; + }); + } + /** + * 5.4. If records is not empty, then invoke mo’s callback with « records, + * mo », and mo. If this throws an exception, then report the exception. + */ + if (!infra_1.list.isEmpty(records)) { + try { + mo._callback.call(mo, records, mo); + } + catch (err) { + // TODO: Report the exception + } + } + } + /** + * 6. For each slot of signalSet, fire an event named slotchange, with its + * bubbles attribute set to true, at slot. + */ + if (dom_1.dom.features.slots) { + for (const slot of signalSet) { + EventAlgorithm_1.event_fireAnEvent("slotchange", slot, undefined, { bubbles: true }); + } + } +} +exports.observer_notifyMutationObservers = observer_notifyMutationObservers; +/** + * Queues a mutation record of the given type for target. + * + * @param type - mutation record type + * @param target - target node + * @param name - name before mutation + * @param namespace - namespace before mutation + * @param oldValue - attribute value before mutation + * @param addedNodes - a list od added nodes + * @param removedNodes - a list of removed nodes + * @param previousSibling - previous sibling of target before mutation + * @param nextSibling - next sibling of target before mutation + */ +function observer_queueMutationRecord(type, target, name, namespace, oldValue, addedNodes, removedNodes, previousSibling, nextSibling) { + /** + * 1. Let interestedObservers be an empty map. + * 2. Let nodes be the inclusive ancestors of target. + * 3. For each node in nodes, and then for each registered of node’s + * registered observer list: + */ + const interestedObservers = new Map(); + let node = TreeAlgorithm_1.tree_getFirstAncestorNode(target, true); + while (node !== null) { + for (let i = 0; i < node._registeredObserverList.length; i++) { + const registered = node._registeredObserverList[i]; + /** + * 3.1. Let options be registered’s options. + * 3.2. If none of the following are true + * - node is not target and options’s subtree is false + * - type is "attributes" and options’s attributes is not true + * - type is "attributes", options’s attributeFilter is present, and + * options’s attributeFilter does not contain name or namespace is + * non-null + * - type is "characterData" and options’s characterData is not true + * - type is "childList" and options’s childList is false + */ + const options = registered.options; + if (node !== target && !options.subtree) + continue; + if (type === "attributes" && !options.attributes) + continue; + if (type === "attributes" && options.attributeFilter && + (!options.attributeFilter.includes(name || '') || namespace !== null)) + continue; + if (type === "characterData" && !options.characterData) + continue; + if (type === "childList" && !options.childList) + continue; + /** + * then: + * 3.2.1. Let mo be registered’s observer. + * 3.2.2. If interestedObservers[mo] does not exist, then set + * interestedObservers[mo] to null. + * 3.2.3. If either type is "attributes" and options’s attributeOldValue + * is true, or type is "characterData" and options’s + * characterDataOldValue is true, then set interestedObservers[mo] + * to oldValue. + */ + const mo = registered.observer; + if (!interestedObservers.has(mo)) { + interestedObservers.set(mo, null); + } + if ((type === "attributes" && options.attributeOldValue) || + (type === "characterData" && options.characterDataOldValue)) { + interestedObservers.set(mo, oldValue); + } + } + node = TreeAlgorithm_1.tree_getNextAncestorNode(target, node, true); + } + /** + * 4. For each observer → mappedOldValue of interestedObservers: + */ + for (const [observer, mappedOldValue] of interestedObservers) { + /** + * 4.1. Let record be a new MutationRecord object with its type set to + * type, target set to target, attributeName set to name, + * attributeNamespace set to namespace, oldValue set to mappedOldValue, + * addedNodes set to addedNodes, removedNodes set to removedNodes, + * previousSibling set to previousSibling, and nextSibling set to + * nextSibling. + * 4.2. Enqueue record to observer’s record queue. + */ + const record = CreateAlgorithm_1.create_mutationRecord(type, target, CreateAlgorithm_1.create_nodeListStatic(target, addedNodes), CreateAlgorithm_1.create_nodeListStatic(target, removedNodes), previousSibling, nextSibling, name, namespace, mappedOldValue); + const queue = observer._recordQueue; + queue.push(record); + } + /** + * 5. Queue a mutation observer microtask. + */ + observer_queueAMutationObserverMicrotask(); +} +exports.observer_queueMutationRecord = observer_queueMutationRecord; +/** + * Queues a tree mutation record for target. + * + * @param target - target node + * @param addedNodes - a list od added nodes + * @param removedNodes - a list of removed nodes + * @param previousSibling - previous sibling of target before mutation + * @param nextSibling - next sibling of target before mutation + */ +function observer_queueTreeMutationRecord(target, addedNodes, removedNodes, previousSibling, nextSibling) { + /** + * To queue a tree mutation record for target with addedNodes, removedNodes, + * previousSibling, and nextSibling, queue a mutation record of "childList" + * for target with null, null, null, addedNodes, removedNodes, + * previousSibling, and nextSibling. + */ + observer_queueMutationRecord("childList", target, null, null, null, addedNodes, removedNodes, previousSibling, nextSibling); +} +exports.observer_queueTreeMutationRecord = observer_queueTreeMutationRecord; +/** + * Queues an attribute mutation record for target. + * + * @param target - target node + * @param name - name before mutation + * @param namespace - namespace before mutation + * @param oldValue - attribute value before mutation + */ +function observer_queueAttributeMutationRecord(target, name, namespace, oldValue) { + /** + * To queue an attribute mutation record for target with name, namespace, + * and oldValue, queue a mutation record of "attributes" for target with + * name, namespace, oldValue, « », « », null, and null. + */ + observer_queueMutationRecord("attributes", target, name, namespace, oldValue, [], [], null, null); +} +exports.observer_queueAttributeMutationRecord = observer_queueAttributeMutationRecord; +//# sourceMappingURL=MutationObserverAlgorithm.js.map + +/***/ }), + +/***/ 154: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const dom_1 = __webpack_require__(113); +const util_1 = __webpack_require__(918); +const DOMException_1 = __webpack_require__(35); +const CreateAlgorithm_1 = __webpack_require__(86); +const TreeAlgorithm_1 = __webpack_require__(873); +const CharacterDataAlgorithm_1 = __webpack_require__(27); +const MutationAlgorithm_1 = __webpack_require__(479); +/** + * Returns node with its adjacent text and cdata node siblings. + * + * @param node - a node + * @param self - whether to include node itself + */ +function text_contiguousTextNodes(node, self = false) { + /** + * The contiguous Text nodes of a node node are node, node’s previous + * sibling Text node, if any, and its contiguous Text nodes, and node’s next + * sibling Text node, if any, and its contiguous Text nodes, avoiding any + * duplicates. + */ + return { + [Symbol.iterator]() { + let currentNode = node; + while (currentNode && util_1.Guard.isTextNode(currentNode._previousSibling)) { + currentNode = currentNode._previousSibling; + } + return { + next() { + if (currentNode && (!self && currentNode === node)) { + if (util_1.Guard.isTextNode(currentNode._nextSibling)) { + currentNode = currentNode._nextSibling; + } + else { + currentNode = null; + } + } + if (currentNode === null) { + return { done: true, value: null }; + } + else { + const result = { done: false, value: currentNode }; + if (util_1.Guard.isTextNode(currentNode._nextSibling)) { + currentNode = currentNode._nextSibling; + } + else { + currentNode = null; + } + return result; + } + } + }; + } + }; +} +exports.text_contiguousTextNodes = text_contiguousTextNodes; +/** + * Returns node with its adjacent text node siblings. + * + * @param node - a node + * @param self - whether to include node itself + */ +function text_contiguousExclusiveTextNodes(node, self = false) { + /** + * The contiguous exclusive Text nodes of a node node are node, node’s + * previous sibling exclusive Text node, if any, and its contiguous + * exclusive Text nodes, and node’s next sibling exclusive Text node, + * if any, and its contiguous exclusive Text nodes, avoiding any duplicates. + */ + return { + [Symbol.iterator]() { + let currentNode = node; + while (currentNode && util_1.Guard.isExclusiveTextNode(currentNode._previousSibling)) { + currentNode = currentNode._previousSibling; + } + return { + next() { + if (currentNode && (!self && currentNode === node)) { + if (util_1.Guard.isExclusiveTextNode(currentNode._nextSibling)) { + currentNode = currentNode._nextSibling; + } + else { + currentNode = null; + } + } + if (currentNode === null) { + return { done: true, value: null }; + } + else { + const result = { done: false, value: currentNode }; + if (util_1.Guard.isExclusiveTextNode(currentNode._nextSibling)) { + currentNode = currentNode._nextSibling; + } + else { + currentNode = null; + } + return result; + } + } + }; + } + }; +} +exports.text_contiguousExclusiveTextNodes = text_contiguousExclusiveTextNodes; +/** + * Returns the concatenation of the data of all the Text node descendants of + * node, in tree order. + * + * @param node - a node + */ +function text_descendantTextContent(node) { + /** + * The descendant text content of a node node is the concatenation of the + * data of all the Text node descendants of node, in tree order. + */ + let contents = ''; + let text = TreeAlgorithm_1.tree_getFirstDescendantNode(node, false, false, (e) => util_1.Guard.isTextNode(e)); + while (text !== null) { + contents += text._data; + text = TreeAlgorithm_1.tree_getNextDescendantNode(node, text, false, false, (e) => util_1.Guard.isTextNode(e)); + } + return contents; +} +exports.text_descendantTextContent = text_descendantTextContent; +/** + * Splits data at the given offset and returns the remainder as a text + * node. + * + * @param node - a text node + * @param offset - the offset at which to split the nodes. + */ +function text_split(node, offset) { + /** + * 1. Let length be node’s length. + * 2. If offset is greater than length, then throw an "IndexSizeError" + * DOMException. + */ + const length = node._data.length; + if (offset > length) { + throw new DOMException_1.IndexSizeError(); + } + /** + * 3. Let count be length minus offset. + * 4. Let new data be the result of substringing data with node node, + * offset offset, and count count. + * 5. Let new node be a new Text node, with the same node document as node. + * Set new node’s data to new data. + * 6. Let parent be node’s parent. + * 7. If parent is not null, then: + */ + const count = length - offset; + const newData = CharacterDataAlgorithm_1.characterData_substringData(node, offset, count); + const newNode = CreateAlgorithm_1.create_text(node._nodeDocument, newData); + const parent = node._parent; + if (parent !== null) { + /** + * 7.1. Insert new node into parent before node’s next sibling. + */ + MutationAlgorithm_1.mutation_insert(newNode, parent, node._nextSibling); + /** + * 7.2. For each live range whose start node is node and start offset is + * greater than offset, set its start node to new node and decrease its + * start offset by offset. + * 7.3. For each live range whose end node is node and end offset is greater + * than offset, set its end node to new node and decrease its end offset + * by offset. + * 7.4. For each live range whose start node is parent and start offset is + * equal to the index of node plus 1, increase its start offset by 1. + * 7.5. For each live range whose end node is parent and end offset is equal + * to the index of node plus 1, increase its end offset by 1. + */ + for (const range of dom_1.dom.rangeList) { + if (range._start[0] === node && range._start[1] > offset) { + range._start[0] = newNode; + range._start[1] -= offset; + } + if (range._end[0] === node && range._end[1] > offset) { + range._end[0] = newNode; + range._end[1] -= offset; + } + const index = TreeAlgorithm_1.tree_index(node); + if (range._start[0] === parent && range._start[1] === index + 1) { + range._start[1]++; + } + if (range._end[0] === parent && range._end[1] === index + 1) { + range._end[1]++; + } + } + } + /** + * 8. Replace data with node node, offset offset, count count, and data + * the empty string. + * 9. Return new node. + */ + CharacterDataAlgorithm_1.characterData_replaceData(node, offset, count, ''); + return newNode; +} +exports.text_split = text_split; +//# sourceMappingURL=TextAlgorithm.js.map + +/***/ }), + +/***/ 162: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const ElementAlgorithm_1 = __webpack_require__(33); +/** + * Changes the value of an existing attribute. + * + * @param attribute - an attribute node + * @param value - attribute value + */ +function attr_setAnExistingAttributeValue(attribute, value) { + /** + * 1. If attribute’s element is null, then set attribute’s value to value. + * 2. Otherwise, change attribute from attribute’s element to value. + */ + if (attribute._element === null) { + attribute._value = value; + } + else { + ElementAlgorithm_1.element_change(attribute, attribute._element, value); + } +} +exports.attr_setAnExistingAttributeValue = attr_setAnExistingAttributeValue; +//# sourceMappingURL=AttrAlgorithm.js.map + +/***/ }), + +/***/ 163: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +function __export(m) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; +} +Object.defineProperty(exports, "__esModule", { value: true }); +__export(__webpack_require__(710)); +__export(__webpack_require__(162)); +__export(__webpack_require__(350)); +__export(__webpack_require__(27)); +__export(__webpack_require__(86)); +__export(__webpack_require__(344)); +__export(__webpack_require__(493)); +__export(__webpack_require__(304)); +__export(__webpack_require__(54)); +__export(__webpack_require__(33)); +__export(__webpack_require__(108)); +__export(__webpack_require__(106)); +__export(__webpack_require__(479)); +__export(__webpack_require__(151)); +__export(__webpack_require__(664)); +__export(__webpack_require__(541)); +__export(__webpack_require__(272)); +__export(__webpack_require__(146)); +__export(__webpack_require__(60)); +__export(__webpack_require__(22)); +__export(__webpack_require__(483)); +__export(__webpack_require__(180)); +__export(__webpack_require__(154)); +__export(__webpack_require__(464)); +__export(__webpack_require__(873)); +__export(__webpack_require__(705)); +__export(__webpack_require__(495)); +__export(__webpack_require__(442)); +//# sourceMappingURL=index.js.map + +/***/ }), + +/***/ 164: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const EventImpl_1 = __webpack_require__(427); +const algorithm_1 = __webpack_require__(163); +/** + * Represents and event that carries custom data. + */ +class CustomEventImpl extends EventImpl_1.EventImpl { + /** + * Initializes a new instance of `CustomEvent`. + */ + constructor(type, eventInit) { + super(type, eventInit); + this._detail = null; + this._detail = (eventInit && eventInit.detail) || null; + } + /** @inheritdoc */ + get detail() { return this._detail; } + /** @inheritdoc */ + initCustomEvent(type, bubbles = false, cancelable = false, detail = null) { + /** + * 1. If the context object’s dispatch flag is set, then return. + */ + if (this._dispatchFlag) + return; + /** + * 2. Initialize the context object with type, bubbles, and cancelable. + */ + algorithm_1.event_initialize(this, type, bubbles, cancelable); + /** + * 3. Set the context object’s detail attribute to detail. + */ + this._detail = detail; + } +} +exports.CustomEventImpl = CustomEventImpl; +//# sourceMappingURL=CustomEventImpl.js.map + +/***/ }), + +/***/ 172: +/***/ (function(__unusedmodule, exports) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * Defines the type of a token. + */ +var TokenType; +(function (TokenType) { + TokenType[TokenType["EOF"] = 0] = "EOF"; + TokenType[TokenType["Declaration"] = 1] = "Declaration"; + TokenType[TokenType["DocType"] = 2] = "DocType"; + TokenType[TokenType["Element"] = 3] = "Element"; + TokenType[TokenType["Text"] = 4] = "Text"; + TokenType[TokenType["CDATA"] = 5] = "CDATA"; + TokenType[TokenType["PI"] = 6] = "PI"; + TokenType[TokenType["Comment"] = 7] = "Comment"; + TokenType[TokenType["ClosingTag"] = 8] = "ClosingTag"; +})(TokenType = exports.TokenType || (exports.TokenType = {})); +//# sourceMappingURL=interfaces.js.map + +/***/ }), + +/***/ 174: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const util_1 = __webpack_require__(42); +/** + * Adds the given item to the end of the list. + * + * @param list - a list + * @param item - an item + */ +function append(list, item) { + list.push(item); +} +exports.append = append; +/** + * Extends a list by appending all items from another list. + * + * @param listA - a list to extend + * @param listB - a list containing items to append to `listA` + */ +function extend(listA, listB) { + listA.push(...listB); +} +exports.extend = extend; +/** + * Inserts the given item to the start of the list. + * + * @param list - a list + * @param item - an item + */ +function prepend(list, item) { + list.unshift(item); +} +exports.prepend = prepend; +/** + * Replaces the given item or all items matching condition with a new item. + * + * @param list - a list + * @param conditionOrItem - an item to replace or a condition matching items + * to replace + * @param item - an item + */ +function replace(list, conditionOrItem, newItem) { + let i = 0; + for (const oldItem of list) { + if (util_1.isFunction(conditionOrItem)) { + if (!!conditionOrItem.call(null, oldItem)) { + list[i] = newItem; + } + } + else if (oldItem === conditionOrItem) { + list[i] = newItem; + return; + } + i++; + } +} +exports.replace = replace; +/** + * Inserts the given item before the given index. + * + * @param list - a list + * @param item - an item + */ +function insert(list, item, index) { + list.splice(index, 0, item); +} +exports.insert = insert; +/** + * Removes the given item or all items matching condition. + * + * @param list - a list + * @param conditionOrItem - an item to remove or a condition matching items + * to remove + */ +function remove(list, conditionOrItem) { + let i = list.length; + while (i--) { + const oldItem = list[i]; + if (util_1.isFunction(conditionOrItem)) { + if (!!conditionOrItem.call(null, oldItem)) { + list.splice(i, 1); + } + } + else if (oldItem === conditionOrItem) { + list.splice(i, 1); + return; + } + } +} +exports.remove = remove; +/** + * Removes all items from the list. + */ +function empty(list) { + list.length = 0; +} +exports.empty = empty; +/** + * Determines if the list contains the given item or any items matching + * condition. + * + * @param list - a list + * @param conditionOrItem - an item to a condition to match + */ +function contains(list, conditionOrItem) { + for (const oldItem of list) { + if (util_1.isFunction(conditionOrItem)) { + if (!!conditionOrItem.call(null, oldItem)) { + return true; + } + } + else if (oldItem === conditionOrItem) { + return true; + } + } + return false; +} +exports.contains = contains; +/** + * Returns the count of items in the list matching the given condition. + * + * @param list - a list + * @param condition - an optional condition to match + */ +function size(list, condition) { + if (condition === undefined) { + return list.length; + } + else { + let count = 0; + for (const item of list) { + if (!!condition.call(null, item)) { + count++; + } + } + return count; + } +} +exports.size = size; +/** + * Determines if the list is empty. + * + * @param list - a list + */ +function isEmpty(list) { + return list.length === 0; +} +exports.isEmpty = isEmpty; +/** + * Returns an iterator for the items of the list. + * + * @param list - a list + * @param condition - an optional condition to match + */ +function* forEach(list, condition) { + if (condition === undefined) { + yield* list; + } + else { + for (const item of list) { + if (!!condition.call(null, item)) { + yield item; + } + } + } +} +exports.forEach = forEach; +/** + * Creates and returns a shallow clone of list. + * + * @param list - a list + */ +function clone(list) { + return new Array(...list); +} +exports.clone = clone; +/** + * Returns a new list containing items from the list sorted in ascending + * order. + * + * @param list - a list + * @param lessThanAlgo - a function that returns `true` if its first argument + * is less than its second argument, and `false` otherwise. + */ +function sortInAscendingOrder(list, lessThanAlgo) { + return list.sort((itemA, itemB) => lessThanAlgo.call(null, itemA, itemB) ? -1 : 1); +} +exports.sortInAscendingOrder = sortInAscendingOrder; +/** + * Returns a new list containing items from the list sorted in descending + * order. + * + * @param list - a list + * @param lessThanAlgo - a function that returns `true` if its first argument + * is less than its second argument, and `false` otherwise. + */ +function sortInDescendingOrder(list, lessThanAlgo) { + return list.sort((itemA, itemB) => lessThanAlgo.call(null, itemA, itemB) ? 1 : -1); +} +exports.sortInDescendingOrder = sortInDescendingOrder; +//# sourceMappingURL=List.js.map + +/***/ }), + +/***/ 175: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const _1 = __webpack_require__(113); +const util_1 = __webpack_require__(918); +const infra_1 = __webpack_require__(23); +/** + * Represents an object that can be used to observe mutations to the tree of + * nodes. + */ +class MutationObserverImpl { + /** + * Initializes a new instance of `MutationObserver`. + * + * @param callback - the callback function + */ + constructor(callback) { + this._nodeList = []; + this._recordQueue = []; + /** + * 1. Let mo be a new MutationObserver object whose callback is callback. + * 2. Append mo to mo’s relevant agent’s mutation observers. + * 3. Return mo. + */ + this._callback = callback; + const window = _1.dom.window; + infra_1.set.append(window._mutationObservers, this); + } + /** @inheritdoc */ + observe(target, options) { + options = options || { + childList: false, + subtree: false + }; + /** + * 1. If either options’s attributeOldValue or attributeFilter is present + * and options’s attributes is omitted, then set options’s attributes + * to true. + * 2. If options’s characterDataOldValue is present and options’s + * characterData is omitted, then set options’s characterData to true. + * 3. If none of options’s childList, attributes, and characterData is + * true, then throw a TypeError. + * 4. If options’s attributeOldValue is true and options’s attributes is + * false, then throw a TypeError. + * 5. If options’s attributeFilter is present and options’s attributes is + * false, then throw a TypeError. + * 6. If options’s characterDataOldValue is true and options’s characterData + * is false, then throw a TypeError. + */ + if ((options.attributeOldValue !== undefined || options.attributeFilter !== undefined) && + options.attributes === undefined) { + options.attributes = true; + } + if (options.characterDataOldValue !== undefined && options.characterData === undefined) { + options.characterData = true; + } + if (!options.childList && !options.attributes && !options.characterData) { + throw new TypeError(); + } + if (options.attributeOldValue && !options.attributes) { + throw new TypeError(); + } + if (options.attributeFilter !== undefined && !options.attributes) { + throw new TypeError(); + } + if (options.characterDataOldValue && !options.characterData) { + throw new TypeError(); + } + /** + * 7. For each registered of target’s registered observer list, if + * registered’s observer is the context object: + */ + let isRegistered = false; + const coptions = options; + for (const registered of target._registeredObserverList) { + if (registered.observer === this) { + isRegistered = true; + /** + * 7.1. For each node of the context object’s node list, remove all + * transient registered observers whose source is registered from node’s + * registered observer list. + */ + for (const node of this._nodeList) { + infra_1.list.remove(node._registeredObserverList, (ob) => util_1.Guard.isTransientRegisteredObserver(ob) && ob.source === registered); + } + /** + * 7.2. Set registered’s options to options. + */ + registered.options = coptions; + } + } + /** + * 8. Otherwise: + * 8.1. Append a new registered observer whose observer is the context + * object and options is options to target’s registered observer list. + * 8.2. Append target to the context object’s node list. + */ + if (!isRegistered) { + target._registeredObserverList.push({ observer: this, options: options }); + this._nodeList.push(target); + } + } + /** @inheritdoc */ + disconnect() { + /** + * 1. For each node of the context object’s node list, remove any + * registered observer from node’s registered observer list for which the + * context object is the observer. + */ + for (const node of this._nodeList) { + infra_1.list.remove((node)._registeredObserverList, (ob) => ob.observer === this); + } + /** + * 2. Empty the context object’s record queue. + */ + this._recordQueue = []; + } + /** @inheritdoc */ + takeRecords() { + /** + * 1. Let records be a clone of the context object’s record queue. + * 2. Empty the context object’s record queue. + * 3. Return records. + */ + const records = this._recordQueue; + this._recordQueue = []; + return records; + } +} +exports.MutationObserverImpl = MutationObserverImpl; +//# sourceMappingURL=MutationObserverImpl.js.map + +/***/ }), + +/***/ 180: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const dom_1 = __webpack_require__(113); +const util_1 = __webpack_require__(918); +const util_2 = __webpack_require__(337); +const TreeAlgorithm_1 = __webpack_require__(873); +const MutationObserverAlgorithm_1 = __webpack_require__(151); +/** + * Signals a slot change to the given slot. + * + * @param slot - a slot + */ +function shadowTree_signalASlotChange(slot) { + /** + * 1. Append slot to slot’s relevant agent’s signal slots. + * 2. Queue a mutation observer microtask. + */ + const window = dom_1.dom.window; + window._signalSlots.add(slot); + MutationObserverAlgorithm_1.observer_queueAMutationObserverMicrotask(); +} +exports.shadowTree_signalASlotChange = shadowTree_signalASlotChange; +/** + * Determines whether a the shadow tree of the given element node is + * connected to a document node. + * + * @param element - an element node of the shadow tree + */ +function shadowTree_isConnected(element) { + /** + * An element is connected if its shadow-including root is a document. + */ + return util_1.Guard.isDocumentNode(TreeAlgorithm_1.tree_rootNode(element, true)); +} +exports.shadowTree_isConnected = shadowTree_isConnected; +/** + * Determines whether a slotable is assigned. + * + * @param slotable - a slotable + */ +function shadowTree_isAssigned(slotable) { + /** + * A slotable is assigned if its assigned slot is non-null. + */ + return (slotable._assignedSlot !== null); +} +exports.shadowTree_isAssigned = shadowTree_isAssigned; +/** + * Finds a slot for the given slotable. + * + * @param slotable - a slotable + * @param openFlag - `true` to search open shadow tree's only + */ +function shadowTree_findASlot(slotable, openFlag = false) { + /** + * 1. If slotable’s parent is null, then return null. + * 2. Let shadow be slotable’s parent’s shadow root. + * 3. If shadow is null, then return null. + * 4. If the open flag is set and shadow’s mode is not "open", then + * return null. + * 5. Return the first slot in tree order in shadow’s descendants whose name + * is slotable’s name, if any, and null otherwise. + */ + const node = util_1.Cast.asNode(slotable); + const parent = node._parent; + if (parent === null) + return null; + const shadow = parent._shadowRoot || null; + if (shadow === null) + return null; + if (openFlag && shadow._mode !== "open") + return null; + let child = TreeAlgorithm_1.tree_getFirstDescendantNode(shadow, false, true, (e) => util_1.Guard.isSlot(e)); + while (child !== null) { + if (child._name === slotable._name) + return child; + child = TreeAlgorithm_1.tree_getNextDescendantNode(shadow, child, false, true, (e) => util_1.Guard.isSlot(e)); + } + return null; +} +exports.shadowTree_findASlot = shadowTree_findASlot; +/** + * Finds slotables for the given slot. + * + * @param slot - a slot + */ +function shadowTree_findSlotables(slot) { + /** + * 1. Let result be an empty list. + * 2. If slot’s root is not a shadow root, then return result. + */ + const result = []; + const root = TreeAlgorithm_1.tree_rootNode(slot); + if (!util_1.Guard.isShadowRoot(root)) + return result; + /** + * 3. Let host be slot’s root’s host. + * 4. For each slotable child of host, slotable, in tree order: + */ + const host = root._host; + for (const slotable of host._children) { + if (util_1.Guard.isSlotable(slotable)) { + /** + * 4.1. Let foundSlot be the result of finding a slot given slotable. + * 4.2. If foundSlot is slot, then append slotable to result. + */ + const foundSlot = shadowTree_findASlot(slotable); + if (foundSlot === slot) { + result.push(slotable); + } + } + } + /** + * 5. Return result. + */ + return result; +} +exports.shadowTree_findSlotables = shadowTree_findSlotables; +/** + * Finds slotables for the given slot. + * + * @param slot - a slot + */ +function shadowTree_findFlattenedSlotables(slot) { + /** + * 1. Let result be an empty list. + * 2. If slot’s root is not a shadow root, then return result. + */ + const result = []; + const root = TreeAlgorithm_1.tree_rootNode(slot); + if (!util_1.Guard.isShadowRoot(root)) + return result; + /** + * 3. Let slotables be the result of finding slotables given slot. + * 4. If slotables is the empty list, then append each slotable child of + * slot, in tree order, to slotables. + */ + const slotables = shadowTree_findSlotables(slot); + if (util_2.isEmpty(slotables)) { + for (const slotable of slot._children) { + if (util_1.Guard.isSlotable(slotable)) { + slotables.push(slotable); + } + } + } + /** + * 5. For each node in slotables: + */ + for (const node of slotables) { + /** + * 5.1. If node is a slot whose root is a shadow root, then: + */ + if (util_1.Guard.isSlot(node) && util_1.Guard.isShadowRoot(TreeAlgorithm_1.tree_rootNode(node))) { + /** + * 5.1.1. Let temporaryResult be the result of finding flattened slotables given node. + * 5.1.2. Append each slotable in temporaryResult, in order, to result. + */ + const temporaryResult = shadowTree_findFlattenedSlotables(node); + result.push(...temporaryResult); + } + else { + /** + * 5.2. Otherwise, append node to result. + */ + result.push(node); + } + } + /** + * 6. Return result. + */ + return result; +} +exports.shadowTree_findFlattenedSlotables = shadowTree_findFlattenedSlotables; +/** + * Assigns slotables to the given slot. + * + * @param slot - a slot + */ +function shadowTree_assignSlotables(slot) { + /** + * 1. Let slotables be the result of finding slotables for slot. + * 2. If slotables and slot’s assigned nodes are not identical, then run + * signal a slot change for slot. + */ + const slotables = shadowTree_findSlotables(slot); + if (slotables.length === slot._assignedNodes.length) { + let nodesIdentical = true; + for (let i = 0; i < slotables.length; i++) { + if (slotables[i] !== slot._assignedNodes[i]) { + nodesIdentical = false; + break; + } + } + if (!nodesIdentical) { + shadowTree_signalASlotChange(slot); + } + } + /** + * 3. Set slot’s assigned nodes to slotables. + * 4. For each slotable in slotables, set slotable’s assigned slot to slot. + */ + slot._assignedNodes = slotables; + for (const slotable of slotables) { + slotable._assignedSlot = slot; + } +} +exports.shadowTree_assignSlotables = shadowTree_assignSlotables; +/** + * Assigns slotables to all nodes of a tree. + * + * @param root - root node + */ +function shadowTree_assignSlotablesForATree(root) { + /** + * To assign slotables for a tree, given a node root, run assign slotables + * for each slot slot in root’s inclusive descendants, in tree order. + */ + let descendant = TreeAlgorithm_1.tree_getFirstDescendantNode(root, true, false, (e) => util_1.Guard.isSlot(e)); + while (descendant !== null) { + shadowTree_assignSlotables(descendant); + descendant = TreeAlgorithm_1.tree_getNextDescendantNode(root, descendant, true, false, (e) => util_1.Guard.isSlot(e)); + } +} +exports.shadowTree_assignSlotablesForATree = shadowTree_assignSlotablesForATree; +/** + * Assigns a slot to a slotables. + * + * @param slotable - a slotable + */ +function shadowTree_assignASlot(slotable) { + /** + * 1. Let slot be the result of finding a slot with slotable. + * 2. If slot is non-null, then run assign slotables for slot. + */ + const slot = shadowTree_findASlot(slotable); + if (slot !== null) { + shadowTree_assignSlotables(slot); + } +} +exports.shadowTree_assignASlot = shadowTree_assignASlot; +//# sourceMappingURL=ShadowTreeAlgorithm.js.map + +/***/ }), + +/***/ 183: +/***/ (function(__unusedmodule, exports) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * Pushes the given item to the stack. + * + * @param list - a list + * @param item - an item + */ +function push(list, item) { + list.push(item); +} +exports.push = push; +/** + * Pops and returns an item from the stack. + * + * @param list - a list + */ +function pop(list) { + return list.pop() || null; +} +exports.pop = pop; +//# sourceMappingURL=Stack.js.map + +/***/ }), + +/***/ 190: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const BaseCBWriter_1 = __webpack_require__(512); +/** + * Serializes XML nodes. + */ +class XMLCBWriter extends BaseCBWriter_1.BaseCBWriter { + /** + * Initializes a new instance of `BaseCBWriter`. + * + * @param builderOptions - XML builder options + */ + constructor(builderOptions) { + super(builderOptions); + this._lineLength = 0; + } + /** @inheritdoc */ + declaration(version, encoding, standalone) { + let markup = this._beginLine() + ""; + return markup; + } + /** @inheritdoc */ + docType(name, publicId, systemId) { + let markup = this._beginLine(); + if (publicId && systemId) { + markup += ""; + } + else if (publicId) { + markup += ""; + } + else if (systemId) { + markup += ""; + } + else { + markup += ""; + } + return markup; + } + /** @inheritdoc */ + comment(data) { + return this._beginLine() + ""; + } + /** @inheritdoc */ + text(data) { + return this._beginLine() + data; + } + /** @inheritdoc */ + instruction(target, data) { + if (data) { + return this._beginLine() + ""; + } + else { + return this._beginLine() + ""; + } + } + /** @inheritdoc */ + cdata(data) { + return this._beginLine() + ""; + } + /** @inheritdoc */ + openTagBegin(name) { + this._lineLength += 1 + name.length; + return this._beginLine() + "<" + name; + } + /** @inheritdoc */ + openTagEnd(name, selfClosing, voidElement) { + if (voidElement) { + return " />"; + } + else if (selfClosing) { + if (this._writerOptions.allowEmptyTags) { + return ">"; + } + else if (this._writerOptions.spaceBeforeSlash) { + return " />"; + } + else { + return "/>"; + } + } + else { + return ">"; + } + } + /** @inheritdoc */ + closeTag(name) { + return this._beginLine() + ""; + } + /** @inheritdoc */ + attribute(name, value) { + let str = name + "=\"" + value + "\""; + if (this._writerOptions.prettyPrint && this._writerOptions.width > 0 && + this._lineLength + 1 + str.length > this._writerOptions.width) { + str = this._beginLine() + this._indent(1) + str; + this._lineLength = str.length; + return str; + } + else { + this._lineLength += 1 + str.length; + return " " + str; + } + } + /** @inheritdoc */ + beginElement(name) { } + /** @inheritdoc */ + endElement(name) { } + /** + * Produces characters to be prepended to a line of string in pretty-print + * mode. + */ + _beginLine() { + if (this._writerOptions.prettyPrint) { + const str = (this.hasData ? this._writerOptions.newline : "") + + this._indent(this._writerOptions.offset + this.level); + this._lineLength = str.length; + return str; + } + else { + return ""; + } + } + /** + * Produces an indentation string. + * + * @param level - depth of the tree + */ + _indent(level) { + if (level <= 0) { + return ""; + } + else { + return this._writerOptions.indent.repeat(level); + } + } +} +exports.XMLCBWriter = XMLCBWriter; +//# sourceMappingURL=XMLCBWriter.js.map + +/***/ }), + +/***/ 204: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const infra_1 = __webpack_require__(23); +const algorithm_1 = __webpack_require__(163); +const util_1 = __webpack_require__(918); +const util_2 = __webpack_require__(337); +/** + * Represents a collection of elements. + */ +class HTMLCollectionImpl { + /** + * Initializes a new instance of `HTMLCollection`. + * + * @param root - root node + * @param filter - node filter + */ + constructor(root, filter) { + this._live = true; + this._root = root; + this._filter = filter; + return new Proxy(this, this); + } + /** @inheritdoc */ + get length() { + /** + * The length attribute’s getter must return the number of nodes + * represented by the collection. + */ + let count = 0; + let node = algorithm_1.tree_getFirstDescendantNode(this._root, false, false, (e) => util_1.Guard.isElementNode(e) && this._filter(e)); + while (node !== null) { + count++; + node = algorithm_1.tree_getNextDescendantNode(this._root, node, false, false, (e) => util_1.Guard.isElementNode(e) && this._filter(e)); + } + return count; + } + /** @inheritdoc */ + item(index) { + /** + * The item(index) method, when invoked, must return the indexth element + * in the collection. If there is no indexth element in the collection, + * then the method must return null. + */ + let i = 0; + let node = algorithm_1.tree_getFirstDescendantNode(this._root, false, false, (e) => util_1.Guard.isElementNode(e) && this._filter(e)); + while (node !== null) { + if (i === index) + return node; + else + i++; + node = algorithm_1.tree_getNextDescendantNode(this._root, node, false, false, (e) => util_1.Guard.isElementNode(e) && this._filter(e)); + } + return null; + } + /** @inheritdoc */ + namedItem(key) { + /** + * 1. If key is the empty string, return null. + * 2. Return the first element in the collection for which at least one of + * the following is true: + * - it has an ID which is key; + * - it is in the HTML namespace and has a name attribute whose value is key; + * or null if there is no such element. + */ + if (key === '') + return null; + let ele = algorithm_1.tree_getFirstDescendantNode(this._root, false, false, (e) => util_1.Guard.isElementNode(e) && this._filter(e)); + while (ele != null) { + if (ele._uniqueIdentifier === key) { + return ele; + } + else if (ele._namespace === infra_1.namespace.HTML) { + for (let i = 0; i < ele._attributeList.length; i++) { + const attr = ele._attributeList[i]; + if (attr._localName === "name" && attr._namespace === null && + attr._namespacePrefix === null && attr._value === key) + return ele; + } + } + ele = algorithm_1.tree_getNextDescendantNode(this._root, ele, false, false, (e) => util_1.Guard.isElementNode(e) && this._filter(e)); + } + return null; + } + /** @inheritdoc */ + [Symbol.iterator]() { + const root = this._root; + const filter = this._filter; + let currentNode = algorithm_1.tree_getFirstDescendantNode(root, false, false, (e) => util_1.Guard.isElementNode(e) && filter(e)); + return { + next() { + if (currentNode === null) { + return { done: true, value: null }; + } + else { + const result = { done: false, value: currentNode }; + currentNode = algorithm_1.tree_getNextDescendantNode(root, currentNode, false, false, (e) => util_1.Guard.isElementNode(e) && filter(e)); + return result; + } + } + }; + } + /** + * Implements a proxy get trap to provide array-like access. + */ + get(target, key, receiver) { + if (!util_2.isString(key) || HTMLCollectionImpl.reservedNames.indexOf(key) !== -1) { + return Reflect.get(target, key, receiver); + } + const index = Number(key); + if (isNaN(index)) { + return target.namedItem(key) || undefined; + } + else { + return target.item(index) || undefined; + } + } + /** + * Implements a proxy set trap to provide array-like access. + */ + set(target, key, value, receiver) { + if (!util_2.isString(key) || HTMLCollectionImpl.reservedNames.indexOf(key) !== -1) { + return Reflect.set(target, key, value, receiver); + } + const index = Number(key); + const node = isNaN(index) ? + target.namedItem(key) || undefined : target.item(index) || undefined; + if (node && node._parent) { + algorithm_1.mutation_replace(node, value, node._parent); + return true; + } + else { + return false; + } + } + /** + * Creates a new `HTMLCollection`. + * + * @param root - root node + * @param filter - node filter + */ + static _create(root, filter = (() => true)) { + return new HTMLCollectionImpl(root, filter); + } +} +exports.HTMLCollectionImpl = HTMLCollectionImpl; +HTMLCollectionImpl.reservedNames = ['_root', '_live', '_filter', 'length', + 'item', 'namedItem', 'get', 'set']; +//# sourceMappingURL=HTMLCollectionImpl.js.map + +/***/ }), + +/***/ 211: +/***/ (function(module) { + +module.exports = require("https"); + +/***/ }), + +/***/ 212: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +// Export classes +var DOMParserImpl_1 = __webpack_require__(642); +exports.DOMParser = DOMParserImpl_1.DOMParserImpl; +//# sourceMappingURL=index.js.map + +/***/ }), + +/***/ 247: +/***/ (function(__unusedmodule, exports) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * Represents a mixin for an interface to be used to share APIs between + * documents and shadow roots. This mixin is implemented by + * {@link Document} and {@link ShadowRoot}. + * + * _Note:_ The DocumentOrShadowRoot mixin is expected to be used by other + * standards that want to define APIs shared between documents and shadow roots. + */ +class DocumentOrShadowRootImpl { +} +exports.DocumentOrShadowRootImpl = DocumentOrShadowRootImpl; +//# sourceMappingURL=DocumentOrShadowRootImpl.js.map + +/***/ }), + +/***/ 252: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const dom_1 = __webpack_require__(113); +dom_1.dom.setFeatures(true); +var dom_2 = __webpack_require__(113); +exports.DOMImplementation = dom_2.DOMImplementation; +var parser_1 = __webpack_require__(212); +exports.DOMParser = parser_1.DOMParser; +var serializer_1 = __webpack_require__(686); +exports.XMLSerializer = serializer_1.XMLSerializer; +//# sourceMappingURL=index.js.map + +/***/ }), + +/***/ 255: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const interfaces_1 = __webpack_require__(625); +const util_1 = __webpack_require__(592); +const util_2 = __webpack_require__(918); +const builder_1 = __webpack_require__(535); +const dom_1 = __webpack_require__(743); +const util_3 = __webpack_require__(669); +const builder_2 = __webpack_require__(535); +/** @inheritdoc */ +function builder(p1, p2) { + const options = formatBuilderOptions(isXMLBuilderCreateOptions(p1) ? p1 : interfaces_1.DefaultBuilderOptions); + const nodes = util_2.Guard.isNode(p1) || util_3.isArray(p1) ? p1 : p2; + if (nodes === undefined) { + throw new Error("Invalid arguments."); + } + if (util_3.isArray(nodes)) { + const builders = []; + for (let i = 0; i < nodes.length; i++) { + const builder = new builder_1.XMLBuilderImpl(nodes[i]); + builder.set(options); + builders.push(builder); + } + return builders; + } + else { + const builder = new builder_1.XMLBuilderImpl(nodes); + builder.set(options); + return builder; + } +} +exports.builder = builder; +/** @inheritdoc */ +function create(p1, p2) { + const options = formatBuilderOptions(p1 === undefined || isXMLBuilderCreateOptions(p1) ? + p1 : interfaces_1.DefaultBuilderOptions); + const contents = isXMLBuilderCreateOptions(p1) ? p2 : p1; + let builder; + if (contents === undefined) { + // empty document + const doc = dom_1.createDocument(); + builder = new builder_1.XMLBuilderImpl(doc); + setOptions(doc, options); + } + else if (util_1.isObject(contents)) { + // JS object + const doc = dom_1.createDocument(); + builder = new builder_1.XMLBuilderImpl(doc); + setOptions(doc, options); + builder.ele(contents); + } + else if (/^\s*" + + dom_1.sanitizeInput(contents, options.invalidCharReplacement) + "", "text/xml"); + dom_1.throwIfParserError(doc); + setOptions(doc, options, true); + /* istanbul ignore next */ + if (doc.documentElement === null) { + throw new Error("Document element is null."); + } + const frag = doc.createDocumentFragment(); + for (const child of doc.documentElement.childNodes) { + const newChild = doc.importNode(child, true); + frag.appendChild(newChild); + } + builder = new builder_1.XMLBuilderImpl(frag); + } + else { + // JSON + const doc = dom_1.createDocument(); + setOptions(doc, options, true); + builder = new builder_1.XMLBuilderImpl(doc.createDocumentFragment()); + const obj = JSON.parse(contents); + builder.ele(obj); + } + return builder; +} +exports.fragment = fragment; +/** @inheritdoc */ +function convert(p1, p2, p3) { + let builderOptions; + let contents; + let convertOptions; + if (isXMLBuilderCreateOptions(p1) && p2 !== undefined) { + builderOptions = p1; + contents = p2; + convertOptions = p3; + } + else { + builderOptions = interfaces_1.DefaultBuilderOptions; + contents = p1; + convertOptions = p2 || undefined; + } + return create(builderOptions, contents).end(convertOptions); +} +exports.convert = convert; +/** + * Creates an XML builder which serializes the document in chunks. + * + * @param options - callback builder options + * + * @returns callback builder + */ +function createCB(options) { + return new builder_2.XMLBuilderCBImpl(options); +} +exports.createCB = createCB; +/** + * Creates an XML builder which serializes the fragment in chunks. + * + * @param options - callback builder options + * + * @returns callback builder + */ +function fragmentCB(options) { + return new builder_2.XMLBuilderCBImpl(options, true); +} +exports.fragmentCB = fragmentCB; +function isXMLBuilderCreateOptions(obj) { + if (!util_1.isPlainObject(obj)) + return false; + for (const key in obj) { + /* istanbul ignore else */ + if (obj.hasOwnProperty(key)) { + if (!interfaces_1.XMLBuilderOptionKeys.has(key)) + return false; + } + } + return true; +} +function formatBuilderOptions(createOptions = {}) { + const options = util_1.applyDefaults(createOptions, interfaces_1.DefaultBuilderOptions); + if (options.convert.att.length === 0 || + options.convert.ins.length === 0 || + options.convert.text.length === 0 || + options.convert.cdata.length === 0 || + options.convert.comment.length === 0) { + throw new Error("JS object converter strings cannot be zero length."); + } + return options; +} +function setOptions(doc, options, isFragment) { + const docWithSettings = doc; + docWithSettings._xmlBuilderOptions = options; + docWithSettings._isFragment = isFragment; +} +//# sourceMappingURL=index.js.map + +/***/ }), + +/***/ 260: +/***/ (function(__unusedmodule, exports) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * Walks through the code points of a string. + */ +class StringWalker { + /** + * Initializes a new `StringWalker`. + * + * @param input - input string + */ + constructor(input) { + this._pointer = 0; + this._chars = Array.from(input); + this._length = this._chars.length; + } + /** + * Determines if the current position is beyond the end of string. + */ + get eof() { return this._pointer >= this._length; } + /** + * Returns the number of code points in the input string. + */ + get length() { return this._length; } + /** + * Returns the current code point. Returns `-1` if the position is beyond + * the end of string. + */ + codePoint() { + if (this._codePoint === undefined) { + if (this.eof) { + this._codePoint = -1; + } + else { + const cp = this._chars[this._pointer].codePointAt(0); + /* istanbul ignore else */ + if (cp !== undefined) { + this._codePoint = cp; + } + else { + this._codePoint = -1; + } + } + } + return this._codePoint; + } + /** + * Returns the current character. Returns an empty string if the position is + * beyond the end of string. + */ + c() { + if (this._c === undefined) { + this._c = (this.eof ? "" : this._chars[this._pointer]); + } + return this._c; + } + /** + * Returns the remaining string. + */ + remaining() { + if (this._remaining === undefined) { + this._remaining = (this.eof ? + "" : this._chars.slice(this._pointer + 1).join('')); + } + return this._remaining; + } + /** + * Returns the substring from the current character to the end of string. + */ + substring() { + if (this._substring === undefined) { + this._substring = (this.eof ? + "" : this._chars.slice(this._pointer).join('')); + } + return this._substring; + } + /** + * Gets or sets the current position. + */ + get pointer() { return this._pointer; } + set pointer(val) { + if (val === this._pointer) + return; + this._pointer = val; + this._codePoint = undefined; + this._c = undefined; + this._remaining = undefined; + this._substring = undefined; + } +} +exports.StringWalker = StringWalker; +//# sourceMappingURL=StringWalker.js.map + +/***/ }), + +/***/ 263: +/***/ (function(__unusedmodule, exports) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * Returns the count of bytes in a sequence. + * + * @param list - a byte sequence + */ +function length(list) { + /** + * A byte sequence’s length is the number of bytes it contains. + */ + return list.length; +} +exports.length = length; +/** + * Converts each byte to lowercase. + * + * @param list - a byte sequence + */ +function byteLowercase(list) { + /** + * To byte-lowercase a byte sequence, increase each byte it contains, in the + * range 0x41 (A) to 0x5A (Z), inclusive, by 0x20. + */ + for (let i = 0; i < list.length; i++) { + const c = list[i]; + if (c >= 0x41 && c <= 0x5A) { + list[i] = c + 0x20; + } + } +} +exports.byteLowercase = byteLowercase; +/** + * Converts each byte to uppercase. + * + * @param list - a byte sequence + */ +function byteUppercase(list) { + /** + * To byte-uppercase a byte sequence, subtract each byte it contains, in the + * range 0x61 (a) to 0x7A (z), inclusive, by 0x20. + */ + for (let i = 0; i < list.length; i++) { + const c = list[i]; + if (c >= 0x61 && c <= 0x7A) { + list[i] = c - 0x20; + } + } +} +exports.byteUppercase = byteUppercase; +/** + * Compares two byte sequences. + * + * @param listA - a byte sequence + * @param listB - a byte sequence + */ +function byteCaseInsensitiveMatch(listA, listB) { + /** + * A byte sequence A is a byte-case-insensitive match for a byte sequence B, + * if the byte-lowercase of A is the byte-lowercase of B. + */ + if (listA.length !== listB.length) + return false; + for (let i = 0; i < listA.length; i++) { + let a = listA[i]; + let b = listB[i]; + if (a >= 0x41 && a <= 0x5A) + a += 0x20; + if (b >= 0x41 && b <= 0x5A) + b += 0x20; + if (a !== b) + return false; + } + return true; +} +exports.byteCaseInsensitiveMatch = byteCaseInsensitiveMatch; +/** + * Determines if `listA` starts with `listB`. + * + * @param listA - a byte sequence + * @param listB - a byte sequence + */ +function startsWith(listA, listB) { + /** + * 1. Let i be 0. + * 2. While true: + * 2.1. Let aByte be the ith byte of a if i is less than a’s length; otherwise null. + * 2.3. Let bByte be the ith byte of b if i is less than b’s length; otherwise null. + * 2.4. If bByte is null, then return true. + * 2.5. Return false if aByte is not bByte. + * 2.6. Set i to i + 1. + */ + let i = 0; + while (true) { + if (i >= listA.length) + return false; + if (i >= listB.length) + return true; + if (listA[i] !== listB[i]) + return false; + i++; + } +} +exports.startsWith = startsWith; +/** + * Determines if `listA` is less than `listB`. + * + * @param listA - a byte sequence + * @param listB - a byte sequence + */ +function byteLessThan(listA, listB) { + /** + * 1. If b starts with a, then return false. + * 2. If a starts with b, then return true. + * 3. Let n be the smallest index such that the nth byte of a is different + * from the nth byte of b. (There has to be such an index, since neither byte + * sequence starts with the other.) + * 4. If the nth byte of a is less than the nth byte of b, then return true. + * 5. Return false. + */ + let i = 0; + while (true) { + if (i >= listA.length) + return false; + if (i >= listB.length) + return true; + const a = listA[i]; + const b = listB[i]; + if (a < b) + return true; + else if (a > b) + return false; + i++; + } +} +exports.byteLessThan = byteLessThan; +/** + * Decodes a byte sequence into a string. + * + * @param list - a byte sequence + */ +function isomorphicDecode(list) { + /** + * To isomorphic decode a byte sequence input, return a string whose length is + * equal to input’s length and whose code points have the same values as + * input’s bytes, in the same order. + */ + return String.fromCodePoint(...list); +} +exports.isomorphicDecode = isomorphicDecode; +//# sourceMappingURL=ByteSequence.js.map + +/***/ }), + +/***/ 266: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const _1 = __webpack_require__(113); +const util_1 = __webpack_require__(337); +/** + * Represents an ordered list of nodes. + * This is a static implementation of `NodeList`. + */ +class NodeListStaticImpl { + /** + * Initializes a new instance of `NodeList`. + * + * @param root - root node + */ + constructor(root) { + this._live = false; + this._items = []; + this._length = 0; + this._root = root; + this._items = []; + this._filter = function (node) { return true; }; + return new Proxy(this, this); + } + /** @inheritdoc */ + get length() { + /** + * The length attribute must return the number of nodes represented by + * the collection. + */ + return this._items.length; + } + /** @inheritdoc */ + item(index) { + /** + * The item(index) method must return the indexth node in the collection. + * If there is no indexth node in the collection, then the method must + * return null. + */ + if (index < 0 || index > this.length - 1) + return null; + return this._items[index]; + } + /** @inheritdoc */ + keys() { + return { + [Symbol.iterator]: function () { + let index = 0; + return { + next: function () { + if (index === this.length) { + return { done: true, value: null }; + } + else { + return { done: false, value: index++ }; + } + }.bind(this) + }; + }.bind(this) + }; + } + /** @inheritdoc */ + values() { + return { + [Symbol.iterator]: function () { + const it = this[Symbol.iterator](); + return { + next() { + return it.next(); + } + }; + }.bind(this) + }; + } + /** @inheritdoc */ + entries() { + return { + [Symbol.iterator]: function () { + const it = this[Symbol.iterator](); + let index = 0; + return { + next() { + const itResult = it.next(); + if (itResult.done) { + return { done: true, value: null }; + } + else { + return { done: false, value: [index++, itResult.value] }; + } + } + }; + }.bind(this) + }; + } + /** @inheritdoc */ + [Symbol.iterator]() { + const it = this._items[Symbol.iterator](); + return { + next() { + return it.next(); + } + }; + } + /** @inheritdoc */ + forEach(callback, thisArg) { + if (thisArg === undefined) { + thisArg = _1.dom.window; + } + let index = 0; + for (const node of this._items) { + callback.call(thisArg, node, index++, this); + } + } + /** + * Implements a proxy get trap to provide array-like access. + */ + get(target, key, receiver) { + if (!util_1.isString(key)) { + return Reflect.get(target, key, receiver); + } + const index = Number(key); + if (isNaN(index)) { + return Reflect.get(target, key, receiver); + } + return target._items[index] || undefined; + } + /** + * Implements a proxy set trap to provide array-like access. + */ + set(target, key, value, receiver) { + if (!util_1.isString(key)) { + return Reflect.set(target, key, value, receiver); + } + const index = Number(key); + if (isNaN(index)) { + return Reflect.set(target, key, value, receiver); + } + if (index >= 0 && index < target._items.length) { + target._items[index] = value; + return true; + } + else { + return false; + } + } + /** + * Creates a new `NodeList`. + * + * @param root - root node + * @param items - a list of items to initialize the list + */ + static _create(root, items) { + const list = new NodeListStaticImpl(root); + list._items = items; + return list; + } +} +exports.NodeListStaticImpl = NodeListStaticImpl; +//# sourceMappingURL=NodeListStaticImpl.js.map + +/***/ }), + +/***/ 271: +/***/ (function(__unusedmodule, exports) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * Represents an object with lazy initialization. + */ +class Lazy { + /** + * Initializes a new instance of `Lazy`. + * + * @param initFunc - initializer function + */ + constructor(initFunc) { + this._initialized = false; + this._value = undefined; + this._initFunc = initFunc; + } + /** + * Gets the value of the object. + */ + get value() { + if (!this._initialized) { + this._value = this._initFunc(); + this._initialized = true; + } + return this._value; + } +} +exports.Lazy = Lazy; +//# sourceMappingURL=Lazy.js.map + +/***/ }), + +/***/ 272: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const dom_1 = __webpack_require__(113); +const interfaces_1 = __webpack_require__(970); +const TraversalAlgorithm_1 = __webpack_require__(464); +const TreeAlgorithm_1 = __webpack_require__(873); +/** + * Returns the next or previous node in the subtree, or `null` if + * there are none. + * + * @param iterator - the `NodeIterator` instance + * @param forward- `true` to return the next node, or `false` to + * return the previous node. + */ +function nodeIterator_traverse(iterator, forward) { + /** + * 1. Let node be iterator’s reference. + * 2. Let beforeNode be iterator’s pointer before reference. + */ + let node = iterator._reference; + let beforeNode = iterator._pointerBeforeReference; + /** + * 3. While true: + */ + while (true) { + /** + * 3.1. Branch on direction: + */ + if (forward) { + /** + * - next + */ + if (!beforeNode) { + /** + * If beforeNode is false, then set node to the first node following + * node in iterator’s iterator collection. If there is no such node, + * then return null. + */ + const nextNode = TreeAlgorithm_1.tree_getFollowingNode(iterator._root, node); + if (nextNode) { + node = nextNode; + } + else { + return null; + } + } + else { + /** + * If beforeNode is true, then set it to false. + */ + beforeNode = false; + } + } + else { + /** + * - previous + */ + if (beforeNode) { + /** + * If beforeNode is true, then set node to the first node preceding + * node in iterator’s iterator collection. If there is no such node, + * then return null. + */ + const prevNode = TreeAlgorithm_1.tree_getPrecedingNode(iterator.root, node); + if (prevNode) { + node = prevNode; + } + else { + return null; + } + } + else { + /** + * If beforeNode is false, then set it to true. + */ + beforeNode = true; + } + } + /** + * 3.2. Let result be the result of filtering node within iterator. + * 3.3. If result is FILTER_ACCEPT, then break. + */ + const result = TraversalAlgorithm_1.traversal_filter(iterator, node); + if (result === interfaces_1.FilterResult.Accept) { + break; + } + } + /** + * 4. Set iterator’s reference to node. + * 5. Set iterator’s pointer before reference to beforeNode. + * 6. Return node. + */ + iterator._reference = node; + iterator._pointerBeforeReference = beforeNode; + return node; +} +exports.nodeIterator_traverse = nodeIterator_traverse; +/** + * Gets the global iterator list. + */ +function nodeIterator_iteratorList() { + return dom_1.dom.window._iteratorList; +} +exports.nodeIterator_iteratorList = nodeIterator_iteratorList; +//# sourceMappingURL=NodeIteratorAlgorithm.js.map + +/***/ }), + +/***/ 279: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const util_1 = __webpack_require__(68); +/** + * Gets the value corresponding to the given key. + * + * @param map - a map + * @param key - a key + */ +function get(map, key) { + return map.get(key); +} +exports.get = get; +/** + * Sets the value corresponding to the given key. + * + * @param map - a map + * @param key - a key + * @param val - a value + */ +function set(map, key, val) { + map.set(key, val); +} +exports.set = set; +/** + * Removes the item with the given key or all items matching condition. + * + * @param map - a map + * @param conditionOrItem - the key of an item to remove or a condition matching + * items to remove + */ +function remove(map, conditionOrItem) { + if (!util_1.isFunction(conditionOrItem)) { + map.delete(conditionOrItem); + } + else { + const toRemove = []; + for (const item of map) { + if (!!conditionOrItem.call(null, item)) { + toRemove.push(item[0]); + } + } + for (const key of toRemove) { + map.delete(key); + } + } +} +exports.remove = remove; +/** + * Determines if the map contains a value with the given key. + * + * @param map - a map + * @param conditionOrItem - the key of an item to match or a condition matching + * items + */ +function contains(map, conditionOrItem) { + if (!util_1.isFunction(conditionOrItem)) { + return map.has(conditionOrItem); + } + else { + for (const item of map) { + if (!!conditionOrItem.call(null, item)) { + return true; + } + } + return false; + } +} +exports.contains = contains; +/** + * Gets the keys of the map. + * + * @param map - a map + */ +function keys(map) { + return new Set(map.keys()); +} +exports.keys = keys; +/** + * Gets the values of the map. + * + * @param map - a map + */ +function values(map) { + return [...map.values()]; +} +exports.values = values; +/** + * Gets the size of the map. + * + * @param map - a map + * @param condition - an optional condition to match + */ +function size(map, condition) { + if (condition === undefined) { + return map.size; + } + else { + let count = 0; + for (const item of map) { + if (!!condition.call(null, item)) { + count++; + } + } + return count; + } +} +exports.size = size; +/** + * Determines if the map is empty. + * + * @param map - a map + */ +function isEmpty(map) { + return map.size === 0; +} +exports.isEmpty = isEmpty; +/** + * Returns an iterator for the items of the map. + * + * @param map - a map + * @param condition - an optional condition to match + */ +function* forEach(map, condition) { + if (condition === undefined) { + yield* map; + } + else { + for (const item of map) { + if (!!condition.call(null, item)) { + yield item; + } + } + } +} +exports.forEach = forEach; +/** + * Creates and returns a shallow clone of map. + * + * @param map - a map + */ +function clone(map) { + return new Map(map); +} +exports.clone = clone; +/** + * Returns a new map containing items from the map sorted in ascending + * order. + * + * @param map - a map + * @param lessThanAlgo - a function that returns `true` if its first argument + * is less than its second argument, and `false` otherwise. + */ +function sortInAscendingOrder(map, lessThanAlgo) { + const list = new Array(...map); + list.sort((itemA, itemB) => lessThanAlgo.call(null, itemA, itemB) ? -1 : 1); + return new Map(list); +} +exports.sortInAscendingOrder = sortInAscendingOrder; +/** + * Returns a new map containing items from the map sorted in descending + * order. + * + * @param map - a map + * @param lessThanAlgo - a function that returns `true` if its first argument + * is less than its second argument, and `false` otherwise. + */ +function sortInDescendingOrder(map, lessThanAlgo) { + const list = new Array(...map); + list.sort((itemA, itemB) => lessThanAlgo.call(null, itemA, itemB) ? 1 : -1); + return new Map(list); +} +exports.sortInDescendingOrder = sortInDescendingOrder; +//# sourceMappingURL=Map.js.map + +/***/ }), + +/***/ 280: +/***/ (function(module, exports) { + +exports = module.exports = SemVer + +var debug +/* istanbul ignore next */ +if (typeof process === 'object' && + process.env && + process.env.NODE_DEBUG && + /\bsemver\b/i.test(process.env.NODE_DEBUG)) { + debug = function () { + var args = Array.prototype.slice.call(arguments, 0) + args.unshift('SEMVER') + console.log.apply(console, args) + } +} else { + debug = function () {} +} + +// Note: this is the semver.org version of the spec that it implements +// Not necessarily the package version of this code. +exports.SEMVER_SPEC_VERSION = '2.0.0' + +var MAX_LENGTH = 256 +var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || + /* istanbul ignore next */ 9007199254740991 + +// Max safe segment length for coercion. +var MAX_SAFE_COMPONENT_LENGTH = 16 + +// The actual regexps go on exports.re +var re = exports.re = [] +var src = exports.src = [] +var t = exports.tokens = {} +var R = 0 + +function tok (n) { + t[n] = R++ +} + +// The following Regular Expressions can be used for tokenizing, +// validating, and parsing SemVer version strings. + +// ## Numeric Identifier +// A single `0`, or a non-zero digit followed by zero or more digits. + +tok('NUMERICIDENTIFIER') +src[t.NUMERICIDENTIFIER] = '0|[1-9]\\d*' +tok('NUMERICIDENTIFIERLOOSE') +src[t.NUMERICIDENTIFIERLOOSE] = '[0-9]+' + +// ## Non-numeric Identifier +// Zero or more digits, followed by a letter or hyphen, and then zero or +// more letters, digits, or hyphens. + +tok('NONNUMERICIDENTIFIER') +src[t.NONNUMERICIDENTIFIER] = '\\d*[a-zA-Z-][a-zA-Z0-9-]*' + +// ## Main Version +// Three dot-separated numeric identifiers. + +tok('MAINVERSION') +src[t.MAINVERSION] = '(' + src[t.NUMERICIDENTIFIER] + ')\\.' + + '(' + src[t.NUMERICIDENTIFIER] + ')\\.' + + '(' + src[t.NUMERICIDENTIFIER] + ')' + +tok('MAINVERSIONLOOSE') +src[t.MAINVERSIONLOOSE] = '(' + src[t.NUMERICIDENTIFIERLOOSE] + ')\\.' + + '(' + src[t.NUMERICIDENTIFIERLOOSE] + ')\\.' + + '(' + src[t.NUMERICIDENTIFIERLOOSE] + ')' + +// ## Pre-release Version Identifier +// A numeric identifier, or a non-numeric identifier. + +tok('PRERELEASEIDENTIFIER') +src[t.PRERELEASEIDENTIFIER] = '(?:' + src[t.NUMERICIDENTIFIER] + + '|' + src[t.NONNUMERICIDENTIFIER] + ')' + +tok('PRERELEASEIDENTIFIERLOOSE') +src[t.PRERELEASEIDENTIFIERLOOSE] = '(?:' + src[t.NUMERICIDENTIFIERLOOSE] + + '|' + src[t.NONNUMERICIDENTIFIER] + ')' + +// ## Pre-release Version +// Hyphen, followed by one or more dot-separated pre-release version +// identifiers. + +tok('PRERELEASE') +src[t.PRERELEASE] = '(?:-(' + src[t.PRERELEASEIDENTIFIER] + + '(?:\\.' + src[t.PRERELEASEIDENTIFIER] + ')*))' + +tok('PRERELEASELOOSE') +src[t.PRERELEASELOOSE] = '(?:-?(' + src[t.PRERELEASEIDENTIFIERLOOSE] + + '(?:\\.' + src[t.PRERELEASEIDENTIFIERLOOSE] + ')*))' + +// ## Build Metadata Identifier +// Any combination of digits, letters, or hyphens. + +tok('BUILDIDENTIFIER') +src[t.BUILDIDENTIFIER] = '[0-9A-Za-z-]+' + +// ## Build Metadata +// Plus sign, followed by one or more period-separated build metadata +// identifiers. + +tok('BUILD') +src[t.BUILD] = '(?:\\+(' + src[t.BUILDIDENTIFIER] + + '(?:\\.' + src[t.BUILDIDENTIFIER] + ')*))' + +// ## Full Version String +// A main version, followed optionally by a pre-release version and +// build metadata. + +// Note that the only major, minor, patch, and pre-release sections of +// the version string are capturing groups. The build metadata is not a +// capturing group, because it should not ever be used in version +// comparison. + +tok('FULL') +tok('FULLPLAIN') +src[t.FULLPLAIN] = 'v?' + src[t.MAINVERSION] + + src[t.PRERELEASE] + '?' + + src[t.BUILD] + '?' + +src[t.FULL] = '^' + src[t.FULLPLAIN] + '$' + +// like full, but allows v1.2.3 and =1.2.3, which people do sometimes. +// also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty +// common in the npm registry. +tok('LOOSEPLAIN') +src[t.LOOSEPLAIN] = '[v=\\s]*' + src[t.MAINVERSIONLOOSE] + + src[t.PRERELEASELOOSE] + '?' + + src[t.BUILD] + '?' + +tok('LOOSE') +src[t.LOOSE] = '^' + src[t.LOOSEPLAIN] + '$' + +tok('GTLT') +src[t.GTLT] = '((?:<|>)?=?)' + +// Something like "2.*" or "1.2.x". +// Note that "x.x" is a valid xRange identifer, meaning "any version" +// Only the first item is strictly required. +tok('XRANGEIDENTIFIERLOOSE') +src[t.XRANGEIDENTIFIERLOOSE] = src[t.NUMERICIDENTIFIERLOOSE] + '|x|X|\\*' +tok('XRANGEIDENTIFIER') +src[t.XRANGEIDENTIFIER] = src[t.NUMERICIDENTIFIER] + '|x|X|\\*' + +tok('XRANGEPLAIN') +src[t.XRANGEPLAIN] = '[v=\\s]*(' + src[t.XRANGEIDENTIFIER] + ')' + + '(?:\\.(' + src[t.XRANGEIDENTIFIER] + ')' + + '(?:\\.(' + src[t.XRANGEIDENTIFIER] + ')' + + '(?:' + src[t.PRERELEASE] + ')?' + + src[t.BUILD] + '?' + + ')?)?' + +tok('XRANGEPLAINLOOSE') +src[t.XRANGEPLAINLOOSE] = '[v=\\s]*(' + src[t.XRANGEIDENTIFIERLOOSE] + ')' + + '(?:\\.(' + src[t.XRANGEIDENTIFIERLOOSE] + ')' + + '(?:\\.(' + src[t.XRANGEIDENTIFIERLOOSE] + ')' + + '(?:' + src[t.PRERELEASELOOSE] + ')?' + + src[t.BUILD] + '?' + + ')?)?' + +tok('XRANGE') +src[t.XRANGE] = '^' + src[t.GTLT] + '\\s*' + src[t.XRANGEPLAIN] + '$' +tok('XRANGELOOSE') +src[t.XRANGELOOSE] = '^' + src[t.GTLT] + '\\s*' + src[t.XRANGEPLAINLOOSE] + '$' + +// Coercion. +// Extract anything that could conceivably be a part of a valid semver +tok('COERCE') +src[t.COERCE] = '(^|[^\\d])' + + '(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '})' + + '(?:\\.(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '}))?' + + '(?:\\.(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '}))?' + + '(?:$|[^\\d])' +tok('COERCERTL') +re[t.COERCERTL] = new RegExp(src[t.COERCE], 'g') + +// Tilde ranges. +// Meaning is "reasonably at or greater than" +tok('LONETILDE') +src[t.LONETILDE] = '(?:~>?)' + +tok('TILDETRIM') +src[t.TILDETRIM] = '(\\s*)' + src[t.LONETILDE] + '\\s+' +re[t.TILDETRIM] = new RegExp(src[t.TILDETRIM], 'g') +var tildeTrimReplace = '$1~' + +tok('TILDE') +src[t.TILDE] = '^' + src[t.LONETILDE] + src[t.XRANGEPLAIN] + '$' +tok('TILDELOOSE') +src[t.TILDELOOSE] = '^' + src[t.LONETILDE] + src[t.XRANGEPLAINLOOSE] + '$' + +// Caret ranges. +// Meaning is "at least and backwards compatible with" +tok('LONECARET') +src[t.LONECARET] = '(?:\\^)' + +tok('CARETTRIM') +src[t.CARETTRIM] = '(\\s*)' + src[t.LONECARET] + '\\s+' +re[t.CARETTRIM] = new RegExp(src[t.CARETTRIM], 'g') +var caretTrimReplace = '$1^' + +tok('CARET') +src[t.CARET] = '^' + src[t.LONECARET] + src[t.XRANGEPLAIN] + '$' +tok('CARETLOOSE') +src[t.CARETLOOSE] = '^' + src[t.LONECARET] + src[t.XRANGEPLAINLOOSE] + '$' + +// A simple gt/lt/eq thing, or just "" to indicate "any version" +tok('COMPARATORLOOSE') +src[t.COMPARATORLOOSE] = '^' + src[t.GTLT] + '\\s*(' + src[t.LOOSEPLAIN] + ')$|^$' +tok('COMPARATOR') +src[t.COMPARATOR] = '^' + src[t.GTLT] + '\\s*(' + src[t.FULLPLAIN] + ')$|^$' + +// An expression to strip any whitespace between the gtlt and the thing +// it modifies, so that `> 1.2.3` ==> `>1.2.3` +tok('COMPARATORTRIM') +src[t.COMPARATORTRIM] = '(\\s*)' + src[t.GTLT] + + '\\s*(' + src[t.LOOSEPLAIN] + '|' + src[t.XRANGEPLAIN] + ')' + +// this one has to use the /g flag +re[t.COMPARATORTRIM] = new RegExp(src[t.COMPARATORTRIM], 'g') +var comparatorTrimReplace = '$1$2$3' + +// Something like `1.2.3 - 1.2.4` +// Note that these all use the loose form, because they'll be +// checked against either the strict or loose comparator form +// later. +tok('HYPHENRANGE') +src[t.HYPHENRANGE] = '^\\s*(' + src[t.XRANGEPLAIN] + ')' + + '\\s+-\\s+' + + '(' + src[t.XRANGEPLAIN] + ')' + + '\\s*$' + +tok('HYPHENRANGELOOSE') +src[t.HYPHENRANGELOOSE] = '^\\s*(' + src[t.XRANGEPLAINLOOSE] + ')' + + '\\s+-\\s+' + + '(' + src[t.XRANGEPLAINLOOSE] + ')' + + '\\s*$' + +// Star ranges basically just allow anything at all. +tok('STAR') +src[t.STAR] = '(<|>)?=?\\s*\\*' + +// Compile to actual regexp objects. +// All are flag-free, unless they were created above with a flag. +for (var i = 0; i < R; i++) { + debug(i, src[i]) + if (!re[i]) { + re[i] = new RegExp(src[i]) + } +} + +exports.parse = parse +function parse (version, options) { + if (!options || typeof options !== 'object') { + options = { + loose: !!options, + includePrerelease: false + } + } + + if (version instanceof SemVer) { + return version + } + + if (typeof version !== 'string') { + return null + } + + if (version.length > MAX_LENGTH) { + return null + } + + var r = options.loose ? re[t.LOOSE] : re[t.FULL] + if (!r.test(version)) { + return null + } + + try { + return new SemVer(version, options) + } catch (er) { + return null + } +} + +exports.valid = valid +function valid (version, options) { + var v = parse(version, options) + return v ? v.version : null +} + +exports.clean = clean +function clean (version, options) { + var s = parse(version.trim().replace(/^[=v]+/, ''), options) + return s ? s.version : null +} + +exports.SemVer = SemVer + +function SemVer (version, options) { + if (!options || typeof options !== 'object') { + options = { + loose: !!options, + includePrerelease: false + } + } + if (version instanceof SemVer) { + if (version.loose === options.loose) { + return version + } else { + version = version.version + } + } else if (typeof version !== 'string') { + throw new TypeError('Invalid Version: ' + version) + } + + if (version.length > MAX_LENGTH) { + throw new TypeError('version is longer than ' + MAX_LENGTH + ' characters') + } + + if (!(this instanceof SemVer)) { + return new SemVer(version, options) + } + + debug('SemVer', version, options) + this.options = options + this.loose = !!options.loose + + var m = version.trim().match(options.loose ? re[t.LOOSE] : re[t.FULL]) + + if (!m) { + throw new TypeError('Invalid Version: ' + version) + } + + this.raw = version + + // these are actually numbers + this.major = +m[1] + this.minor = +m[2] + this.patch = +m[3] + + if (this.major > MAX_SAFE_INTEGER || this.major < 0) { + throw new TypeError('Invalid major version') + } + + if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) { + throw new TypeError('Invalid minor version') + } + + if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) { + throw new TypeError('Invalid patch version') + } + + // numberify any prerelease numeric ids + if (!m[4]) { + this.prerelease = [] + } else { + this.prerelease = m[4].split('.').map(function (id) { + if (/^[0-9]+$/.test(id)) { + var num = +id + if (num >= 0 && num < MAX_SAFE_INTEGER) { + return num + } + } + return id + }) + } + + this.build = m[5] ? m[5].split('.') : [] + this.format() +} + +SemVer.prototype.format = function () { + this.version = this.major + '.' + this.minor + '.' + this.patch + if (this.prerelease.length) { + this.version += '-' + this.prerelease.join('.') + } + return this.version +} + +SemVer.prototype.toString = function () { + return this.version +} + +SemVer.prototype.compare = function (other) { + debug('SemVer.compare', this.version, this.options, other) + if (!(other instanceof SemVer)) { + other = new SemVer(other, this.options) + } + + return this.compareMain(other) || this.comparePre(other) +} + +SemVer.prototype.compareMain = function (other) { + if (!(other instanceof SemVer)) { + other = new SemVer(other, this.options) + } + + return compareIdentifiers(this.major, other.major) || + compareIdentifiers(this.minor, other.minor) || + compareIdentifiers(this.patch, other.patch) +} + +SemVer.prototype.comparePre = function (other) { + if (!(other instanceof SemVer)) { + other = new SemVer(other, this.options) + } + + // NOT having a prerelease is > having one + if (this.prerelease.length && !other.prerelease.length) { + return -1 + } else if (!this.prerelease.length && other.prerelease.length) { + return 1 + } else if (!this.prerelease.length && !other.prerelease.length) { + return 0 + } + + var i = 0 + do { + var a = this.prerelease[i] + var b = other.prerelease[i] + debug('prerelease compare', i, a, b) + if (a === undefined && b === undefined) { + return 0 + } else if (b === undefined) { + return 1 + } else if (a === undefined) { + return -1 + } else if (a === b) { + continue + } else { + return compareIdentifiers(a, b) + } + } while (++i) +} + +SemVer.prototype.compareBuild = function (other) { + if (!(other instanceof SemVer)) { + other = new SemVer(other, this.options) + } + + var i = 0 + do { + var a = this.build[i] + var b = other.build[i] + debug('prerelease compare', i, a, b) + if (a === undefined && b === undefined) { + return 0 + } else if (b === undefined) { + return 1 + } else if (a === undefined) { + return -1 + } else if (a === b) { + continue + } else { + return compareIdentifiers(a, b) + } + } while (++i) +} + +// preminor will bump the version up to the next minor release, and immediately +// down to pre-release. premajor and prepatch work the same way. +SemVer.prototype.inc = function (release, identifier) { + switch (release) { + case 'premajor': + this.prerelease.length = 0 + this.patch = 0 + this.minor = 0 + this.major++ + this.inc('pre', identifier) + break + case 'preminor': + this.prerelease.length = 0 + this.patch = 0 + this.minor++ + this.inc('pre', identifier) + break + case 'prepatch': + // If this is already a prerelease, it will bump to the next version + // drop any prereleases that might already exist, since they are not + // relevant at this point. + this.prerelease.length = 0 + this.inc('patch', identifier) + this.inc('pre', identifier) + break + // If the input is a non-prerelease version, this acts the same as + // prepatch. + case 'prerelease': + if (this.prerelease.length === 0) { + this.inc('patch', identifier) + } + this.inc('pre', identifier) + break + + case 'major': + // If this is a pre-major version, bump up to the same major version. + // Otherwise increment major. + // 1.0.0-5 bumps to 1.0.0 + // 1.1.0 bumps to 2.0.0 + if (this.minor !== 0 || + this.patch !== 0 || + this.prerelease.length === 0) { + this.major++ + } + this.minor = 0 + this.patch = 0 + this.prerelease = [] + break + case 'minor': + // If this is a pre-minor version, bump up to the same minor version. + // Otherwise increment minor. + // 1.2.0-5 bumps to 1.2.0 + // 1.2.1 bumps to 1.3.0 + if (this.patch !== 0 || this.prerelease.length === 0) { + this.minor++ + } + this.patch = 0 + this.prerelease = [] + break + case 'patch': + // If this is not a pre-release version, it will increment the patch. + // If it is a pre-release it will bump up to the same patch version. + // 1.2.0-5 patches to 1.2.0 + // 1.2.0 patches to 1.2.1 + if (this.prerelease.length === 0) { + this.patch++ + } + this.prerelease = [] + break + // This probably shouldn't be used publicly. + // 1.0.0 "pre" would become 1.0.0-0 which is the wrong direction. + case 'pre': + if (this.prerelease.length === 0) { + this.prerelease = [0] + } else { + var i = this.prerelease.length + while (--i >= 0) { + if (typeof this.prerelease[i] === 'number') { + this.prerelease[i]++ + i = -2 + } + } + if (i === -1) { + // didn't increment anything + this.prerelease.push(0) + } + } + if (identifier) { + // 1.2.0-beta.1 bumps to 1.2.0-beta.2, + // 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0 + if (this.prerelease[0] === identifier) { + if (isNaN(this.prerelease[1])) { + this.prerelease = [identifier, 0] + } + } else { + this.prerelease = [identifier, 0] + } + } + break + + default: + throw new Error('invalid increment argument: ' + release) + } + this.format() + this.raw = this.version + return this +} + +exports.inc = inc +function inc (version, release, loose, identifier) { + if (typeof (loose) === 'string') { + identifier = loose + loose = undefined + } + + try { + return new SemVer(version, loose).inc(release, identifier).version + } catch (er) { + return null + } +} + +exports.diff = diff +function diff (version1, version2) { + if (eq(version1, version2)) { + return null + } else { + var v1 = parse(version1) + var v2 = parse(version2) + var prefix = '' + if (v1.prerelease.length || v2.prerelease.length) { + prefix = 'pre' + var defaultResult = 'prerelease' + } + for (var key in v1) { + if (key === 'major' || key === 'minor' || key === 'patch') { + if (v1[key] !== v2[key]) { + return prefix + key + } + } + } + return defaultResult // may be undefined + } +} + +exports.compareIdentifiers = compareIdentifiers + +var numeric = /^[0-9]+$/ +function compareIdentifiers (a, b) { + var anum = numeric.test(a) + var bnum = numeric.test(b) + + if (anum && bnum) { + a = +a + b = +b + } + + return a === b ? 0 + : (anum && !bnum) ? -1 + : (bnum && !anum) ? 1 + : a < b ? -1 + : 1 +} + +exports.rcompareIdentifiers = rcompareIdentifiers +function rcompareIdentifiers (a, b) { + return compareIdentifiers(b, a) +} + +exports.major = major +function major (a, loose) { + return new SemVer(a, loose).major +} + +exports.minor = minor +function minor (a, loose) { + return new SemVer(a, loose).minor +} + +exports.patch = patch +function patch (a, loose) { + return new SemVer(a, loose).patch +} + +exports.compare = compare +function compare (a, b, loose) { + return new SemVer(a, loose).compare(new SemVer(b, loose)) +} + +exports.compareLoose = compareLoose +function compareLoose (a, b) { + return compare(a, b, true) +} + +exports.compareBuild = compareBuild +function compareBuild (a, b, loose) { + var versionA = new SemVer(a, loose) + var versionB = new SemVer(b, loose) + return versionA.compare(versionB) || versionA.compareBuild(versionB) +} + +exports.rcompare = rcompare +function rcompare (a, b, loose) { + return compare(b, a, loose) +} + +exports.sort = sort +function sort (list, loose) { + return list.sort(function (a, b) { + return exports.compareBuild(a, b, loose) + }) +} + +exports.rsort = rsort +function rsort (list, loose) { + return list.sort(function (a, b) { + return exports.compareBuild(b, a, loose) + }) +} + +exports.gt = gt +function gt (a, b, loose) { + return compare(a, b, loose) > 0 +} + +exports.lt = lt +function lt (a, b, loose) { + return compare(a, b, loose) < 0 +} + +exports.eq = eq +function eq (a, b, loose) { + return compare(a, b, loose) === 0 +} + +exports.neq = neq +function neq (a, b, loose) { + return compare(a, b, loose) !== 0 +} + +exports.gte = gte +function gte (a, b, loose) { + return compare(a, b, loose) >= 0 +} + +exports.lte = lte +function lte (a, b, loose) { + return compare(a, b, loose) <= 0 +} + +exports.cmp = cmp +function cmp (a, op, b, loose) { + switch (op) { + case '===': + if (typeof a === 'object') + a = a.version + if (typeof b === 'object') + b = b.version + return a === b + + case '!==': + if (typeof a === 'object') + a = a.version + if (typeof b === 'object') + b = b.version + return a !== b + + case '': + case '=': + case '==': + return eq(a, b, loose) + + case '!=': + return neq(a, b, loose) + + case '>': + return gt(a, b, loose) + + case '>=': + return gte(a, b, loose) + + case '<': + return lt(a, b, loose) + + case '<=': + return lte(a, b, loose) + + default: + throw new TypeError('Invalid operator: ' + op) + } +} + +exports.Comparator = Comparator +function Comparator (comp, options) { + if (!options || typeof options !== 'object') { + options = { + loose: !!options, + includePrerelease: false + } + } + + if (comp instanceof Comparator) { + if (comp.loose === !!options.loose) { + return comp + } else { + comp = comp.value + } + } + + if (!(this instanceof Comparator)) { + return new Comparator(comp, options) + } + + debug('comparator', comp, options) + this.options = options + this.loose = !!options.loose + this.parse(comp) + + if (this.semver === ANY) { + this.value = '' + } else { + this.value = this.operator + this.semver.version + } + + debug('comp', this) +} + +var ANY = {} +Comparator.prototype.parse = function (comp) { + var r = this.options.loose ? re[t.COMPARATORLOOSE] : re[t.COMPARATOR] + var m = comp.match(r) + + if (!m) { + throw new TypeError('Invalid comparator: ' + comp) + } + + this.operator = m[1] !== undefined ? m[1] : '' + if (this.operator === '=') { + this.operator = '' + } + + // if it literally is just '>' or '' then allow anything. + if (!m[2]) { + this.semver = ANY + } else { + this.semver = new SemVer(m[2], this.options.loose) + } +} + +Comparator.prototype.toString = function () { + return this.value +} + +Comparator.prototype.test = function (version) { + debug('Comparator.test', version, this.options.loose) + + if (this.semver === ANY || version === ANY) { + return true + } + + if (typeof version === 'string') { + try { + version = new SemVer(version, this.options) + } catch (er) { + return false + } + } + + return cmp(version, this.operator, this.semver, this.options) +} + +Comparator.prototype.intersects = function (comp, options) { + if (!(comp instanceof Comparator)) { + throw new TypeError('a Comparator is required') + } + + if (!options || typeof options !== 'object') { + options = { + loose: !!options, + includePrerelease: false + } + } + + var rangeTmp + + if (this.operator === '') { + if (this.value === '') { + return true + } + rangeTmp = new Range(comp.value, options) + return satisfies(this.value, rangeTmp, options) + } else if (comp.operator === '') { + if (comp.value === '') { + return true + } + rangeTmp = new Range(this.value, options) + return satisfies(comp.semver, rangeTmp, options) + } + + var sameDirectionIncreasing = + (this.operator === '>=' || this.operator === '>') && + (comp.operator === '>=' || comp.operator === '>') + var sameDirectionDecreasing = + (this.operator === '<=' || this.operator === '<') && + (comp.operator === '<=' || comp.operator === '<') + var sameSemVer = this.semver.version === comp.semver.version + var differentDirectionsInclusive = + (this.operator === '>=' || this.operator === '<=') && + (comp.operator === '>=' || comp.operator === '<=') + var oppositeDirectionsLessThan = + cmp(this.semver, '<', comp.semver, options) && + ((this.operator === '>=' || this.operator === '>') && + (comp.operator === '<=' || comp.operator === '<')) + var oppositeDirectionsGreaterThan = + cmp(this.semver, '>', comp.semver, options) && + ((this.operator === '<=' || this.operator === '<') && + (comp.operator === '>=' || comp.operator === '>')) + + return sameDirectionIncreasing || sameDirectionDecreasing || + (sameSemVer && differentDirectionsInclusive) || + oppositeDirectionsLessThan || oppositeDirectionsGreaterThan +} + +exports.Range = Range +function Range (range, options) { + if (!options || typeof options !== 'object') { + options = { + loose: !!options, + includePrerelease: false + } + } + + if (range instanceof Range) { + if (range.loose === !!options.loose && + range.includePrerelease === !!options.includePrerelease) { + return range + } else { + return new Range(range.raw, options) + } + } + + if (range instanceof Comparator) { + return new Range(range.value, options) + } + + if (!(this instanceof Range)) { + return new Range(range, options) + } + + this.options = options + this.loose = !!options.loose + this.includePrerelease = !!options.includePrerelease + + // First, split based on boolean or || + this.raw = range + this.set = range.split(/\s*\|\|\s*/).map(function (range) { + return this.parseRange(range.trim()) + }, this).filter(function (c) { + // throw out any that are not relevant for whatever reason + return c.length + }) + + if (!this.set.length) { + throw new TypeError('Invalid SemVer Range: ' + range) + } + + this.format() +} + +Range.prototype.format = function () { + this.range = this.set.map(function (comps) { + return comps.join(' ').trim() + }).join('||').trim() + return this.range +} + +Range.prototype.toString = function () { + return this.range +} + +Range.prototype.parseRange = function (range) { + var loose = this.options.loose + range = range.trim() + // `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4` + var hr = loose ? re[t.HYPHENRANGELOOSE] : re[t.HYPHENRANGE] + range = range.replace(hr, hyphenReplace) + debug('hyphen replace', range) + // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5` + range = range.replace(re[t.COMPARATORTRIM], comparatorTrimReplace) + debug('comparator trim', range, re[t.COMPARATORTRIM]) + + // `~ 1.2.3` => `~1.2.3` + range = range.replace(re[t.TILDETRIM], tildeTrimReplace) + + // `^ 1.2.3` => `^1.2.3` + range = range.replace(re[t.CARETTRIM], caretTrimReplace) + + // normalize spaces + range = range.split(/\s+/).join(' ') + + // At this point, the range is completely trimmed and + // ready to be split into comparators. + + var compRe = loose ? re[t.COMPARATORLOOSE] : re[t.COMPARATOR] + var set = range.split(' ').map(function (comp) { + return parseComparator(comp, this.options) + }, this).join(' ').split(/\s+/) + if (this.options.loose) { + // in loose mode, throw out any that are not valid comparators + set = set.filter(function (comp) { + return !!comp.match(compRe) + }) + } + set = set.map(function (comp) { + return new Comparator(comp, this.options) + }, this) + + return set +} + +Range.prototype.intersects = function (range, options) { + if (!(range instanceof Range)) { + throw new TypeError('a Range is required') + } + + return this.set.some(function (thisComparators) { + return ( + isSatisfiable(thisComparators, options) && + range.set.some(function (rangeComparators) { + return ( + isSatisfiable(rangeComparators, options) && + thisComparators.every(function (thisComparator) { + return rangeComparators.every(function (rangeComparator) { + return thisComparator.intersects(rangeComparator, options) + }) + }) + ) + }) + ) + }) +} + +// take a set of comparators and determine whether there +// exists a version which can satisfy it +function isSatisfiable (comparators, options) { + var result = true + var remainingComparators = comparators.slice() + var testComparator = remainingComparators.pop() + + while (result && remainingComparators.length) { + result = remainingComparators.every(function (otherComparator) { + return testComparator.intersects(otherComparator, options) + }) + + testComparator = remainingComparators.pop() + } + + return result +} + +// Mostly just for testing and legacy API reasons +exports.toComparators = toComparators +function toComparators (range, options) { + return new Range(range, options).set.map(function (comp) { + return comp.map(function (c) { + return c.value + }).join(' ').trim().split(' ') + }) +} + +// comprised of xranges, tildes, stars, and gtlt's at this point. +// already replaced the hyphen ranges +// turn into a set of JUST comparators. +function parseComparator (comp, options) { + debug('comp', comp, options) + comp = replaceCarets(comp, options) + debug('caret', comp) + comp = replaceTildes(comp, options) + debug('tildes', comp) + comp = replaceXRanges(comp, options) + debug('xrange', comp) + comp = replaceStars(comp, options) + debug('stars', comp) + return comp +} + +function isX (id) { + return !id || id.toLowerCase() === 'x' || id === '*' +} + +// ~, ~> --> * (any, kinda silly) +// ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.0 +// ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0 +// ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0 +// ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0 +// ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0 +function replaceTildes (comp, options) { + return comp.trim().split(/\s+/).map(function (comp) { + return replaceTilde(comp, options) + }).join(' ') +} + +function replaceTilde (comp, options) { + var r = options.loose ? re[t.TILDELOOSE] : re[t.TILDE] + return comp.replace(r, function (_, M, m, p, pr) { + debug('tilde', comp, _, M, m, p, pr) + var ret + + if (isX(M)) { + ret = '' + } else if (isX(m)) { + ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0' + } else if (isX(p)) { + // ~1.2 == >=1.2.0 <1.3.0 + ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0' + } else if (pr) { + debug('replaceTilde pr', pr) + ret = '>=' + M + '.' + m + '.' + p + '-' + pr + + ' <' + M + '.' + (+m + 1) + '.0' + } else { + // ~1.2.3 == >=1.2.3 <1.3.0 + ret = '>=' + M + '.' + m + '.' + p + + ' <' + M + '.' + (+m + 1) + '.0' + } + + debug('tilde return', ret) + return ret + }) +} + +// ^ --> * (any, kinda silly) +// ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0 +// ^2.0, ^2.0.x --> >=2.0.0 <3.0.0 +// ^1.2, ^1.2.x --> >=1.2.0 <2.0.0 +// ^1.2.3 --> >=1.2.3 <2.0.0 +// ^1.2.0 --> >=1.2.0 <2.0.0 +function replaceCarets (comp, options) { + return comp.trim().split(/\s+/).map(function (comp) { + return replaceCaret(comp, options) + }).join(' ') +} + +function replaceCaret (comp, options) { + debug('caret', comp, options) + var r = options.loose ? re[t.CARETLOOSE] : re[t.CARET] + return comp.replace(r, function (_, M, m, p, pr) { + debug('caret', comp, _, M, m, p, pr) + var ret + + if (isX(M)) { + ret = '' + } else if (isX(m)) { + ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0' + } else if (isX(p)) { + if (M === '0') { + ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0' + } else { + ret = '>=' + M + '.' + m + '.0 <' + (+M + 1) + '.0.0' + } + } else if (pr) { + debug('replaceCaret pr', pr) + if (M === '0') { + if (m === '0') { + ret = '>=' + M + '.' + m + '.' + p + '-' + pr + + ' <' + M + '.' + m + '.' + (+p + 1) + } else { + ret = '>=' + M + '.' + m + '.' + p + '-' + pr + + ' <' + M + '.' + (+m + 1) + '.0' + } + } else { + ret = '>=' + M + '.' + m + '.' + p + '-' + pr + + ' <' + (+M + 1) + '.0.0' + } + } else { + debug('no pr') + if (M === '0') { + if (m === '0') { + ret = '>=' + M + '.' + m + '.' + p + + ' <' + M + '.' + m + '.' + (+p + 1) + } else { + ret = '>=' + M + '.' + m + '.' + p + + ' <' + M + '.' + (+m + 1) + '.0' + } + } else { + ret = '>=' + M + '.' + m + '.' + p + + ' <' + (+M + 1) + '.0.0' + } + } + + debug('caret return', ret) + return ret + }) +} + +function replaceXRanges (comp, options) { + debug('replaceXRanges', comp, options) + return comp.split(/\s+/).map(function (comp) { + return replaceXRange(comp, options) + }).join(' ') +} + +function replaceXRange (comp, options) { + comp = comp.trim() + var r = options.loose ? re[t.XRANGELOOSE] : re[t.XRANGE] + return comp.replace(r, function (ret, gtlt, M, m, p, pr) { + debug('xRange', comp, ret, gtlt, M, m, p, pr) + var xM = isX(M) + var xm = xM || isX(m) + var xp = xm || isX(p) + var anyX = xp + + if (gtlt === '=' && anyX) { + gtlt = '' + } + + // if we're including prereleases in the match, then we need + // to fix this to -0, the lowest possible prerelease value + pr = options.includePrerelease ? '-0' : '' + + if (xM) { + if (gtlt === '>' || gtlt === '<') { + // nothing is allowed + ret = '<0.0.0-0' + } else { + // nothing is forbidden + ret = '*' + } + } else if (gtlt && anyX) { + // we know patch is an x, because we have any x at all. + // replace X with 0 + if (xm) { + m = 0 + } + p = 0 + + if (gtlt === '>') { + // >1 => >=2.0.0 + // >1.2 => >=1.3.0 + // >1.2.3 => >= 1.2.4 + gtlt = '>=' + if (xm) { + M = +M + 1 + m = 0 + p = 0 + } else { + m = +m + 1 + p = 0 + } + } else if (gtlt === '<=') { + // <=0.7.x is actually <0.8.0, since any 0.7.x should + // pass. Similarly, <=7.x is actually <8.0.0, etc. + gtlt = '<' + if (xm) { + M = +M + 1 + } else { + m = +m + 1 + } + } + + ret = gtlt + M + '.' + m + '.' + p + pr + } else if (xm) { + ret = '>=' + M + '.0.0' + pr + ' <' + (+M + 1) + '.0.0' + pr + } else if (xp) { + ret = '>=' + M + '.' + m + '.0' + pr + + ' <' + M + '.' + (+m + 1) + '.0' + pr + } + + debug('xRange return', ret) + + return ret + }) +} + +// Because * is AND-ed with everything else in the comparator, +// and '' means "any version", just remove the *s entirely. +function replaceStars (comp, options) { + debug('replaceStars', comp, options) + // Looseness is ignored here. star is always as loose as it gets! + return comp.trim().replace(re[t.STAR], '') +} + +// This function is passed to string.replace(re[t.HYPHENRANGE]) +// M, m, patch, prerelease, build +// 1.2 - 3.4.5 => >=1.2.0 <=3.4.5 +// 1.2.3 - 3.4 => >=1.2.0 <3.5.0 Any 3.4.x will do +// 1.2 - 3.4 => >=1.2.0 <3.5.0 +function hyphenReplace ($0, + from, fM, fm, fp, fpr, fb, + to, tM, tm, tp, tpr, tb) { + if (isX(fM)) { + from = '' + } else if (isX(fm)) { + from = '>=' + fM + '.0.0' + } else if (isX(fp)) { + from = '>=' + fM + '.' + fm + '.0' + } else { + from = '>=' + from + } + + if (isX(tM)) { + to = '' + } else if (isX(tm)) { + to = '<' + (+tM + 1) + '.0.0' + } else if (isX(tp)) { + to = '<' + tM + '.' + (+tm + 1) + '.0' + } else if (tpr) { + to = '<=' + tM + '.' + tm + '.' + tp + '-' + tpr + } else { + to = '<=' + to + } + + return (from + ' ' + to).trim() +} + +// if ANY of the sets match ALL of its comparators, then pass +Range.prototype.test = function (version) { + if (!version) { + return false + } + + if (typeof version === 'string') { + try { + version = new SemVer(version, this.options) + } catch (er) { + return false + } + } + + for (var i = 0; i < this.set.length; i++) { + if (testSet(this.set[i], version, this.options)) { + return true + } + } + return false +} + +function testSet (set, version, options) { + for (var i = 0; i < set.length; i++) { + if (!set[i].test(version)) { + return false + } + } + + if (version.prerelease.length && !options.includePrerelease) { + // Find the set of versions that are allowed to have prereleases + // For example, ^1.2.3-pr.1 desugars to >=1.2.3-pr.1 <2.0.0 + // That should allow `1.2.3-pr.2` to pass. + // However, `1.2.4-alpha.notready` should NOT be allowed, + // even though it's within the range set by the comparators. + for (i = 0; i < set.length; i++) { + debug(set[i].semver) + if (set[i].semver === ANY) { + continue + } + + if (set[i].semver.prerelease.length > 0) { + var allowed = set[i].semver + if (allowed.major === version.major && + allowed.minor === version.minor && + allowed.patch === version.patch) { + return true + } + } + } + + // Version has a -pre, but it's not one of the ones we like. + return false + } + + return true +} + +exports.satisfies = satisfies +function satisfies (version, range, options) { + try { + range = new Range(range, options) + } catch (er) { + return false + } + return range.test(version) +} + +exports.maxSatisfying = maxSatisfying +function maxSatisfying (versions, range, options) { + var max = null + var maxSV = null + try { + var rangeObj = new Range(range, options) + } catch (er) { + return null + } + versions.forEach(function (v) { + if (rangeObj.test(v)) { + // satisfies(v, range, options) + if (!max || maxSV.compare(v) === -1) { + // compare(max, v, true) + max = v + maxSV = new SemVer(max, options) + } + } + }) + return max +} + +exports.minSatisfying = minSatisfying +function minSatisfying (versions, range, options) { + var min = null + var minSV = null + try { + var rangeObj = new Range(range, options) + } catch (er) { + return null + } + versions.forEach(function (v) { + if (rangeObj.test(v)) { + // satisfies(v, range, options) + if (!min || minSV.compare(v) === 1) { + // compare(min, v, true) + min = v + minSV = new SemVer(min, options) + } + } + }) + return min +} + +exports.minVersion = minVersion +function minVersion (range, loose) { + range = new Range(range, loose) + + var minver = new SemVer('0.0.0') + if (range.test(minver)) { + return minver + } + + minver = new SemVer('0.0.0-0') + if (range.test(minver)) { + return minver + } + + minver = null + for (var i = 0; i < range.set.length; ++i) { + var comparators = range.set[i] + + comparators.forEach(function (comparator) { + // Clone to avoid manipulating the comparator's semver object. + var compver = new SemVer(comparator.semver.version) + switch (comparator.operator) { + case '>': + if (compver.prerelease.length === 0) { + compver.patch++ + } else { + compver.prerelease.push(0) + } + compver.raw = compver.format() + /* fallthrough */ + case '': + case '>=': + if (!minver || gt(minver, compver)) { + minver = compver + } + break + case '<': + case '<=': + /* Ignore maximum versions */ + break + /* istanbul ignore next */ + default: + throw new Error('Unexpected operation: ' + comparator.operator) + } + }) + } + + if (minver && range.test(minver)) { + return minver + } + + return null +} + +exports.validRange = validRange +function validRange (range, options) { + try { + // Return '*' instead of '' so that truthiness works. + // This will throw if it's invalid anyway + return new Range(range, options).range || '*' + } catch (er) { + return null + } +} + +// Determine if version is less than all the versions possible in the range +exports.ltr = ltr +function ltr (version, range, options) { + return outside(version, range, '<', options) +} + +// Determine if version is greater than all the versions possible in the range. +exports.gtr = gtr +function gtr (version, range, options) { + return outside(version, range, '>', options) +} + +exports.outside = outside +function outside (version, range, hilo, options) { + version = new SemVer(version, options) + range = new Range(range, options) + + var gtfn, ltefn, ltfn, comp, ecomp + switch (hilo) { + case '>': + gtfn = gt + ltefn = lte + ltfn = lt + comp = '>' + ecomp = '>=' + break + case '<': + gtfn = lt + ltefn = gte + ltfn = gt + comp = '<' + ecomp = '<=' + break + default: + throw new TypeError('Must provide a hilo val of "<" or ">"') + } + + // If it satisifes the range it is not outside + if (satisfies(version, range, options)) { + return false + } + + // From now on, variable terms are as if we're in "gtr" mode. + // but note that everything is flipped for the "ltr" function. + + for (var i = 0; i < range.set.length; ++i) { + var comparators = range.set[i] + + var high = null + var low = null + + comparators.forEach(function (comparator) { + if (comparator.semver === ANY) { + comparator = new Comparator('>=0.0.0') + } + high = high || comparator + low = low || comparator + if (gtfn(comparator.semver, high.semver, options)) { + high = comparator + } else if (ltfn(comparator.semver, low.semver, options)) { + low = comparator + } + }) + + // If the edge version comparator has a operator then our version + // isn't outside it + if (high.operator === comp || high.operator === ecomp) { + return false + } + + // If the lowest version comparator has an operator and our version + // is less than it then it isn't higher than the range + if ((!low.operator || low.operator === comp) && + ltefn(version, low.semver)) { + return false + } else if (low.operator === ecomp && ltfn(version, low.semver)) { + return false + } + } + return true +} + +exports.prerelease = prerelease +function prerelease (version, options) { + var parsed = parse(version, options) + return (parsed && parsed.prerelease.length) ? parsed.prerelease : null +} + +exports.intersects = intersects +function intersects (r1, r2, options) { + r1 = new Range(r1, options) + r2 = new Range(r2, options) + return r1.intersects(r2) +} + +exports.coerce = coerce +function coerce (version, options) { + if (version instanceof SemVer) { + return version + } + + if (typeof version === 'number') { + version = String(version) + } + + if (typeof version !== 'string') { + return null + } + + options = options || {} + + var match = null + if (!options.rtl) { + match = version.match(re[t.COERCE]) + } else { + // Find the right-most coercible string that does not share + // a terminus with a more left-ward coercible string. + // Eg, '1.2.3.4' wants to coerce '2.3.4', not '3.4' or '4' + // + // Walk through the string checking with a /g regexp + // Manually set the index so as to pick up overlapping matches. + // Stop when we get a match that ends at the string end, since no + // coercible string can be more right-ward without the same terminus. + var next + while ((next = re[t.COERCERTL].exec(version)) && + (!match || match.index + match[0].length !== version.length) + ) { + if (!match || + next.index + next[0].length !== match.index + match[0].length) { + match = next + } + re[t.COERCERTL].lastIndex = next.index + next[1].length + next[2].length + } + // leave it in a clean state + re[t.COERCERTL].lastIndex = -1 + } + + if (match === null) { + return null + } + + return parse(match[2] + + '.' + (match[3] || '0') + + '.' + (match[4] || '0'), options) +} + + +/***/ }), + +/***/ 286: +/***/ (function(__unusedmodule, exports) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * Represents the state of the URL parser. + */ +var ParserState; +(function (ParserState) { + ParserState[ParserState["SchemeStart"] = 0] = "SchemeStart"; + ParserState[ParserState["Scheme"] = 1] = "Scheme"; + ParserState[ParserState["NoScheme"] = 2] = "NoScheme"; + ParserState[ParserState["SpecialRelativeOrAuthority"] = 3] = "SpecialRelativeOrAuthority"; + ParserState[ParserState["PathOrAuthority"] = 4] = "PathOrAuthority"; + ParserState[ParserState["Relative"] = 5] = "Relative"; + ParserState[ParserState["RelativeSlash"] = 6] = "RelativeSlash"; + ParserState[ParserState["SpecialAuthoritySlashes"] = 7] = "SpecialAuthoritySlashes"; + ParserState[ParserState["SpecialAuthorityIgnoreSlashes"] = 8] = "SpecialAuthorityIgnoreSlashes"; + ParserState[ParserState["Authority"] = 9] = "Authority"; + ParserState[ParserState["Host"] = 10] = "Host"; + ParserState[ParserState["Hostname"] = 11] = "Hostname"; + ParserState[ParserState["Port"] = 12] = "Port"; + ParserState[ParserState["File"] = 13] = "File"; + ParserState[ParserState["FileSlash"] = 14] = "FileSlash"; + ParserState[ParserState["FileHost"] = 15] = "FileHost"; + ParserState[ParserState["PathStart"] = 16] = "PathStart"; + ParserState[ParserState["Path"] = 17] = "Path"; + ParserState[ParserState["CannotBeABaseURLPath"] = 18] = "CannotBeABaseURLPath"; + ParserState[ParserState["Query"] = 19] = "Query"; + ParserState[ParserState["Fragment"] = 20] = "Fragment"; +})(ParserState = exports.ParserState || (exports.ParserState = {})); +exports.OpaqueOrigin = ["", "", null, null]; +//# sourceMappingURL=interfaces.js.map + +/***/ }), + +/***/ 290: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const _1 = __webpack_require__(113); +const infra_1 = __webpack_require__(23); +const algorithm_1 = __webpack_require__(163); +const WebIDLAlgorithm_1 = __webpack_require__(495); +/** + * Represents an object providing methods which are not dependent on + * any particular document. + */ +class DOMImplementationImpl { + /** + * Initializes a new instance of `DOMImplementation`. + * + * @param document - the associated document + */ + constructor(document) { + this._associatedDocument = document || _1.dom.window.document; + } + /** @inheritdoc */ + createDocumentType(qualifiedName, publicId, systemId) { + /** + * 1. Validate qualifiedName. + * 2. Return a new doctype, with qualifiedName as its name, publicId as its + * public ID, and systemId as its system ID, and with its node document set + * to the associated document of the context object. + */ + algorithm_1.namespace_validate(qualifiedName); + return algorithm_1.create_documentType(this._associatedDocument, qualifiedName, publicId, systemId); + } + /** @inheritdoc */ + createDocument(namespace, qualifiedName, doctype = null) { + /** + * 1. Let document be a new XMLDocument. + */ + const document = algorithm_1.create_xmlDocument(); + /** + * 2. Let element be null. + * 3. If qualifiedName is not the empty string, then set element to + * the result of running the internal createElementNS steps, given document, + * namespace, qualifiedName, and an empty dictionary. + */ + let element = null; + if (qualifiedName) { + element = algorithm_1.document_internalCreateElementNS(document, namespace, qualifiedName); + } + /** + * 4. If doctype is non-null, append doctype to document. + * 5. If element is non-null, append element to document. + */ + if (doctype) + document.appendChild(doctype); + if (element) + document.appendChild(element); + /** + * 6. document’s origin is context object’s associated document’s origin. + */ + document._origin = this._associatedDocument._origin; + /** + * 7. document’s content type is determined by namespace: + * - HTML namespace + * application/xhtml+xml + * - SVG namespace + * image/svg+xml + * - Any other namespace + * application/xml + */ + if (namespace === infra_1.namespace.HTML) + document._contentType = "application/xhtml+xml"; + else if (namespace === infra_1.namespace.SVG) + document._contentType = "image/svg+xml"; + else + document._contentType = "application/xml"; + /** + * 8. Return document. + */ + return document; + } + /** @inheritdoc */ + createHTMLDocument(title) { + /** + * 1. Let doc be a new document that is an HTML document. + * 2. Set doc’s content type to "text/html". + */ + const doc = algorithm_1.create_document(); + doc._type = "html"; + doc._contentType = "text/html"; + /** + * 3. Append a new doctype, with "html" as its name and with its node + * document set to doc, to doc. + */ + doc.appendChild(algorithm_1.create_documentType(doc, "html", "", "")); + /** + * 4. Append the result of creating an element given doc, html, and the + * HTML namespace, to doc. + */ + const htmlElement = algorithm_1.element_createAnElement(doc, "html", infra_1.namespace.HTML); + doc.appendChild(htmlElement); + /** + * 5. Append the result of creating an element given doc, head, and the + * HTML namespace, to the html element created earlier. + */ + const headElement = algorithm_1.element_createAnElement(doc, "head", infra_1.namespace.HTML); + htmlElement.appendChild(headElement); + /** + * 6. If title is given: + * 6.1. Append the result of creating an element given doc, title, and + * the HTML namespace, to the head element created earlier. + * 6.2. Append a new Text node, with its data set to title (which could + * be the empty string) and its node document set to doc, to the title + * element created earlier. + */ + if (title !== undefined) { + const titleElement = algorithm_1.element_createAnElement(doc, "title", infra_1.namespace.HTML); + headElement.appendChild(titleElement); + const textElement = algorithm_1.create_text(doc, title); + titleElement.appendChild(textElement); + } + /** + * 7. Append the result of creating an element given doc, body, and the + * HTML namespace, to the html element created earlier. + */ + const bodyElement = algorithm_1.element_createAnElement(doc, "body", infra_1.namespace.HTML); + htmlElement.appendChild(bodyElement); + /** + * 8. doc’s origin is context object’s associated document’s origin. + */ + doc._origin = this._associatedDocument._origin; + /** + * 9. Return doc. + */ + return doc; + } + /** @inheritdoc */ + hasFeature() { return true; } + /** + * Creates a new `DOMImplementation`. + * + * @param document - owner document + */ + static _create(document) { + return new DOMImplementationImpl(document); + } +} +exports.DOMImplementationImpl = DOMImplementationImpl; +WebIDLAlgorithm_1.idl_defineConst(DOMImplementationImpl.prototype, "_ID", "@oozcitak/dom"); +//# sourceMappingURL=DOMImplementationImpl.js.map + +/***/ }), + +/***/ 304: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const dom_1 = __webpack_require__(113); +const TreeAlgorithm_1 = __webpack_require__(873); +const util_1 = __webpack_require__(918); +const ShadowTreeAlgorithm_1 = __webpack_require__(180); +const supportedTokens = new Map(); +/** + * Runs removing steps for node. + * + * @param removedNode - removed node + * @param oldParent - old parent node + */ +function dom_runRemovingSteps(removedNode, oldParent) { + // No steps defined +} +exports.dom_runRemovingSteps = dom_runRemovingSteps; +/** + * Runs cloning steps for node. + * + * @param copy - node clone + * @param node - node + * @param document - document to own the cloned node + * @param cloneChildrenFlag - whether child nodes are cloned + */ +function dom_runCloningSteps(copy, node, document, cloneChildrenFlag) { + // No steps defined +} +exports.dom_runCloningSteps = dom_runCloningSteps; +/** + * Runs adopting steps for node. + * + * @param node - node + * @param oldDocument - old document + */ +function dom_runAdoptingSteps(node, oldDocument) { + // No steps defined +} +exports.dom_runAdoptingSteps = dom_runAdoptingSteps; +/** + * Runs attribute change steps for an element node. + * + * @param element - element node owning the attribute + * @param localName - attribute's local name + * @param oldValue - attribute's old value + * @param value - attribute's new value + * @param namespace - attribute's namespace + */ +function dom_runAttributeChangeSteps(element, localName, oldValue, value, namespace) { + // run default steps + if (dom_1.dom.features.slots) { + updateASlotablesName.call(element, element, localName, oldValue, value, namespace); + updateASlotsName.call(element, element, localName, oldValue, value, namespace); + } + updateAnElementID.call(element, element, localName, value, namespace); + // run custom steps + for (const step of element._attributeChangeSteps) { + step.call(element, element, localName, oldValue, value, namespace); + } +} +exports.dom_runAttributeChangeSteps = dom_runAttributeChangeSteps; +/** + * Runs insertion steps for a node. + * + * @param insertedNode - inserted node + */ +function dom_runInsertionSteps(insertedNode) { + // No steps defined +} +exports.dom_runInsertionSteps = dom_runInsertionSteps; +/** + * Runs pre-removing steps for a node iterator and node. + * + * @param nodeIterator - a node iterator + * @param toBeRemoved - node to be removed + */ +function dom_runNodeIteratorPreRemovingSteps(nodeIterator, toBeRemoved) { + removeNodeIterator.call(nodeIterator, nodeIterator, toBeRemoved); +} +exports.dom_runNodeIteratorPreRemovingSteps = dom_runNodeIteratorPreRemovingSteps; +/** + * Determines if there are any supported tokens defined for the given + * attribute name. + * + * @param attributeName - an attribute name + */ +function dom_hasSupportedTokens(attributeName) { + return supportedTokens.has(attributeName); +} +exports.dom_hasSupportedTokens = dom_hasSupportedTokens; +/** + * Returns the set of supported tokens defined for the given attribute name. + * + * @param attributeName - an attribute name + */ +function dom_getSupportedTokens(attributeName) { + return supportedTokens.get(attributeName) || new Set(); +} +exports.dom_getSupportedTokens = dom_getSupportedTokens; +/** + * Runs event construction steps. + * + * @param event - an event + */ +function dom_runEventConstructingSteps(event) { + // No steps defined +} +exports.dom_runEventConstructingSteps = dom_runEventConstructingSteps; +/** + * Runs child text content change steps for a parent node. + * + * @param parent - parent node with text node child nodes + */ +function dom_runChildTextContentChangeSteps(parent) { + // No steps defined +} +exports.dom_runChildTextContentChangeSteps = dom_runChildTextContentChangeSteps; +/** + * Defines pre-removing steps for a node iterator. + */ +function removeNodeIterator(nodeIterator, toBeRemovedNode) { + /** + * 1. If toBeRemovedNode is not an inclusive ancestor of nodeIterator’s + * reference, or toBeRemovedNode is nodeIterator’s root, then return. + */ + if (toBeRemovedNode === nodeIterator._root || + !TreeAlgorithm_1.tree_isAncestorOf(nodeIterator._reference, toBeRemovedNode, true)) { + return; + } + /** + * 2. If nodeIterator’s pointer before reference is true, then: + */ + if (nodeIterator._pointerBeforeReference) { + /** + * 2.1. Let next be toBeRemovedNode’s first following node that is an + * inclusive descendant of nodeIterator’s root and is not an inclusive + * descendant of toBeRemovedNode, and null if there is no such node. + */ + while (true) { + const nextNode = TreeAlgorithm_1.tree_getFollowingNode(nodeIterator._root, toBeRemovedNode); + if (nextNode !== null && + TreeAlgorithm_1.tree_isDescendantOf(nodeIterator._root, nextNode, true) && + !TreeAlgorithm_1.tree_isDescendantOf(toBeRemovedNode, nextNode, true)) { + /** + * 2.2. If next is non-null, then set nodeIterator’s reference to next + * and return. + */ + nodeIterator._reference = nextNode; + return; + } + else if (nextNode === null) { + /** + * 2.3. Otherwise, set nodeIterator’s pointer before reference to false. + */ + nodeIterator._pointerBeforeReference = false; + return; + } + } + } + /** + * 3. Set nodeIterator’s reference to toBeRemovedNode’s parent, if + * toBeRemovedNode’s previous sibling is null, and to the inclusive + * descendant of toBeRemovedNode’s previous sibling that appears last in + * tree order otherwise. + */ + if (toBeRemovedNode._previousSibling === null) { + if (toBeRemovedNode._parent !== null) { + nodeIterator._reference = toBeRemovedNode._parent; + } + } + else { + let referenceNode = toBeRemovedNode._previousSibling; + let childNode = TreeAlgorithm_1.tree_getFirstDescendantNode(toBeRemovedNode._previousSibling, true, false); + while (childNode !== null) { + if (childNode !== null) { + referenceNode = childNode; + } + // loop through to get the last descendant node + childNode = TreeAlgorithm_1.tree_getNextDescendantNode(toBeRemovedNode._previousSibling, childNode, true, false); + } + nodeIterator._reference = referenceNode; + } +} +/** + * Defines attribute change steps to update a slot’s name. + */ +function updateASlotsName(element, localName, oldValue, value, namespace) { + /** + * 1. If element is a slot, localName is name, and namespace is null, then: + * 1.1. If value is oldValue, then return. + * 1.2. If value is null and oldValue is the empty string, then return. + * 1.3. If value is the empty string and oldValue is null, then return. + * 1.4. If value is null or the empty string, then set element’s name to the + * empty string. + * 1.5. Otherwise, set element’s name to value. + * 1.6. Run assign slotables for a tree with element’s root. + */ + if (util_1.Guard.isSlot(element) && localName === "name" && namespace === null) { + if (value === oldValue) + return; + if (value === null && oldValue === '') + return; + if (value === '' && oldValue === null) + return; + if ((value === null || value === '')) { + element._name = ''; + } + else { + element._name = value; + } + ShadowTreeAlgorithm_1.shadowTree_assignSlotablesForATree(TreeAlgorithm_1.tree_rootNode(element)); + } +} +/** + * Defines attribute change steps to update a slotable’s name. + */ +function updateASlotablesName(element, localName, oldValue, value, namespace) { + /** + * 1. If localName is slot and namespace is null, then: + * 1.1. If value is oldValue, then return. + * 1.2. If value is null and oldValue is the empty string, then return. + * 1.3. If value is the empty string and oldValue is null, then return. + * 1.4. If value is null or the empty string, then set element’s name to + * the empty string. + * 1.5. Otherwise, set element’s name to value. + * 1.6. If element is assigned, then run assign slotables for element’s + * assigned slot. + * 1.7. Run assign a slot for element. + */ + if (util_1.Guard.isSlotable(element) && localName === "slot" && namespace === null) { + if (value === oldValue) + return; + if (value === null && oldValue === '') + return; + if (value === '' && oldValue === null) + return; + if ((value === null || value === '')) { + element._name = ''; + } + else { + element._name = value; + } + if (ShadowTreeAlgorithm_1.shadowTree_isAssigned(element)) { + ShadowTreeAlgorithm_1.shadowTree_assignSlotables(element._assignedSlot); + } + ShadowTreeAlgorithm_1.shadowTree_assignASlot(element); + } +} +/** + * Defines attribute change steps to update an element's ID. + */ +function updateAnElementID(element, localName, value, namespace) { + /** + * 1. If localName is id, namespace is null, and value is null or the empty + * string, then unset element’s ID. + * 2. Otherwise, if localName is id, namespace is null, then set element’s + * ID to value. + */ + if (localName === "id" && namespace === null) { + if (!value) + element._uniqueIdentifier = undefined; + else + element._uniqueIdentifier = value; + } +} +//# sourceMappingURL=DOMAlgorithm.js.map + +/***/ }), + +/***/ 307: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result["default"] = mod; + return result; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const base64 = __importStar(__webpack_require__(347)); +exports.base64 = base64; +const byte = __importStar(__webpack_require__(15)); +exports.byte = byte; +const byteSequence = __importStar(__webpack_require__(425)); +exports.byteSequence = byteSequence; +const codePoint = __importStar(__webpack_require__(780)); +exports.codePoint = codePoint; +const json = __importStar(__webpack_require__(859)); +exports.json = json; +const list = __importStar(__webpack_require__(174)); +exports.list = list; +const map = __importStar(__webpack_require__(486)); +exports.map = map; +const namespace = __importStar(__webpack_require__(609)); +exports.namespace = namespace; +const queue = __importStar(__webpack_require__(429)); +exports.queue = queue; +const set = __importStar(__webpack_require__(693)); +exports.set = set; +const stack = __importStar(__webpack_require__(183)); +exports.stack = stack; +const string = __importStar(__webpack_require__(665)); +exports.string = string; +//# sourceMappingURL=index.js.map + +/***/ }), + +/***/ 319: +/***/ (function(__unusedmodule, exports) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * Represents a set of objects with a size limit. + */ +class FixedSizeSet { + /** + * Initializes a new instance of `FixedSizeSet`. + * + * @param limit - maximum number of items to keep in the set. When the limit + * is exceeded the first item is removed from the set. + */ + constructor(limit = 1000) { + this._items = new Set(); + this._limit = limit; + } + /** + * Adds a new item to the set. + * + * @param item - an item + */ + add(item) { + this._items.add(item); + if (this._items.size > this._limit) { + const it = this._items.values().next(); + /* istanbul ignore else */ + if (!it.done) { + this._items.delete(it.value); + } + } + return this; + } + /** + * Removes an item from the set. + * + * @param item - an item + */ + delete(item) { + return this._items.delete(item); + } + /** + * Determines if an item is in the set. + * + * @param item - an item + */ + has(item) { + return this._items.has(item); + } + /** + * Removes all items from the set. + */ + clear() { + this._items.clear(); + } + /** + * Gets the number of items in the set. + */ + get size() { return this._items.size; } + /** + * Applies the given callback function to all elements of the set. + */ + forEach(callback, thisArg) { + this._items.forEach(e => callback.call(thisArg, e, e, this)); + } + /** + * Iterates through the items in the set. + */ + *keys() { + yield* this._items.keys(); + } + /** + * Iterates through the items in the set. + */ + *values() { + yield* this._items.values(); + } + /** + * Iterates through the items in the set. + */ + *entries() { + yield* this._items.entries(); + } + /** + * Iterates through the items in the set. + */ + *[Symbol.iterator]() { + yield* this._items; + } + /** + * Returns the string tag of the set. + */ + get [Symbol.toStringTag]() { + return "FixedSizeSet"; + } +} +exports.FixedSizeSet = FixedSizeSet; +//# sourceMappingURL=FixedSizeSet.js.map + +/***/ }), + +/***/ 322: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result["default"] = mod; + return result; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const path = __importStar(__webpack_require__(622)); +function getTempDir() { + let tempDirectory = process.env.RUNNER_TEMP; + if (tempDirectory === undefined) { + let baseLocation; + if (isWindows()) { + // On windows use the USERPROFILE env variable + baseLocation = process.env['USERPROFILE'] + ? process.env['USERPROFILE'] + : 'C:\\'; + } + else { + if (process.platform === 'darwin') { + baseLocation = '/Users'; + } + else { + baseLocation = '/home'; + } + } + tempDirectory = path.join(baseLocation, 'actions', 'temp'); + } + return tempDirectory; +} +exports.getTempDir = getTempDir; +function isWindows() { + return process.platform === 'win32'; +} +exports.isWindows = isWindows; + + +/***/ }), + +/***/ 326: +/***/ (function(__unusedmodule, exports) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * Represents an object cache with a size limit. + */ +class ObjectCache { + /** + * Initializes a new instance of `ObjectCache`. + * + * @param limit - maximum number of items to keep in the cache. When the limit + * is exceeded the first item is removed from the cache. + */ + constructor(limit = 1000) { + this._items = new Set(); + this._limit = limit; + } + /** + * Adds a new item to the cache. + * + * @param item - an item + */ + add(item) { + this._items.add(item); + if (this._items.size > this._limit) { + const it = this._items.values().next(); + /* istanbul ignore else */ + if (!it.done) { + this._items.delete(it.value); + } + } + } + /** + * Removes an item from the cache. + * + * @param item - an item + */ + remove(item) { + this._items.delete(item); + } + /** + * Removes all items from the cache. + */ + clear() { + this._items.clear(); + } + /** + * Gets the number of items in the cache. + */ + get length() { return this._items.size; } + /** + * Iterates through the items in the cache. + */ + *entries() { + yield* this; + } + /** + * Iterates through the items in the cache. + */ + *[Symbol.iterator]() { + yield* this._items; + } +} +exports.ObjectCache = ObjectCache; +//# sourceMappingURL=ObjectCache.js.map + +/***/ }), + +/***/ 331: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result["default"] = mod; + return result; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const fs = __importStar(__webpack_require__(747)); +const os = __importStar(__webpack_require__(87)); +const path = __importStar(__webpack_require__(622)); +const core = __importStar(__webpack_require__(470)); +const io = __importStar(__webpack_require__(1)); +const xmlbuilder2_1 = __webpack_require__(255); +exports.M2_DIR = '.m2'; +exports.SETTINGS_FILE = 'settings.xml'; +function configAuthentication(id, username, password, gpgPassphrase = undefined) { + return __awaiter(this, void 0, void 0, function* () { + console.log(`creating ${exports.SETTINGS_FILE} with server-id: ${id};`, 'environment variables:', `username=\$${username},`, `password=\$${password},`, `and gpg-passphrase=${gpgPassphrase ? '$' + gpgPassphrase : null}`); + // when an alternate m2 location is specified use only that location (no .m2 directory) + // otherwise use the home/.m2/ path + const settingsDirectory = path.join(core.getInput('settings-path') || os.homedir(), core.getInput('settings-path') ? '' : exports.M2_DIR); + yield io.mkdirP(settingsDirectory); + core.debug(`created directory ${settingsDirectory}`); + yield write(settingsDirectory, generate(id, username, password, gpgPassphrase)); + }); +} +exports.configAuthentication = configAuthentication; +// only exported for testing purposes +function generate(id, username, password, gpgPassphrase = undefined) { + const xmlObj = { + settings: { + '@xmlns': 'http://maven.apache.org/SETTINGS/1.0.0', + '@xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance', + '@xsi:schemaLocation': 'http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd', + servers: { + server: [ + { + id: id, + username: `\${env.${username}}`, + password: `\${env.${password}}` + } + ] + } + } + }; + if (gpgPassphrase) { + const gpgServer = { + id: 'gpg.passphrase', + passphrase: `\${env.${gpgPassphrase}}` + }; + xmlObj.settings.servers.server.push(gpgServer); + } + return xmlbuilder2_1.create(xmlObj).end({ headless: true, prettyPrint: true, width: 80 }); +} +exports.generate = generate; +function write(directory, settings) { + return __awaiter(this, void 0, void 0, function* () { + const location = path.join(directory, exports.SETTINGS_FILE); + if (fs.existsSync(location)) { + console.warn(`overwriting existing file ${location}`); + } + else { + console.log(`writing ${location}`); + } + return fs.writeFileSync(location, settings, { + encoding: 'utf-8', + flag: 'w' + }); + }); +} + + +/***/ }), + +/***/ 337: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +var FixedSizeSet_1 = __webpack_require__(844); +exports.FixedSizeSet = FixedSizeSet_1.FixedSizeSet; +var ObjectCache_1 = __webpack_require__(995); +exports.ObjectCache = ObjectCache_1.ObjectCache; +var CompareCache_1 = __webpack_require__(879); +exports.CompareCache = CompareCache_1.CompareCache; +var Lazy_1 = __webpack_require__(798); +exports.Lazy = Lazy_1.Lazy; +/** + * Applies the mixin to a given class. + * + * @param baseClass - class to receive the mixin + * @param mixinClass - mixin class + * @param overrides - an array with names of function overrides. Base class + * functions whose names are in this array will be kept by prepending an + * underscore to their names. + */ +function applyMixin(baseClass, mixinClass, ...overrides) { + Object.getOwnPropertyNames(mixinClass.prototype).forEach(name => { + if (overrides.includes(name)) { + const orgPropDesc = Object.getOwnPropertyDescriptor(baseClass.prototype, name); + /* istanbul ignore else */ + if (orgPropDesc) { + Object.defineProperty(baseClass.prototype, "_" + name, orgPropDesc); + } + } + const propDesc = Object.getOwnPropertyDescriptor(mixinClass.prototype, name); + /* istanbul ignore else */ + if (propDesc) { + Object.defineProperty(baseClass.prototype, name, propDesc); + } + }); +} +exports.applyMixin = applyMixin; +/** + * Applies default values to the given object. + * + * @param obj - an object + * @param defaults - an object with default values + * @param overwrite - if set to `true` defaults object always overwrites object + * values, whether they are `undefined` or not. + */ +function applyDefaults(obj, defaults, overwrite = false) { + const result = clone(obj || {}); + forEachObject(defaults, (key, val) => { + if (isObject(val)) { + result[key] = applyDefaults(result[key], val); + } + else if (overwrite || result[key] === undefined) { + result[key] = val; + } + }); + return result; +} +exports.applyDefaults = applyDefaults; +/** + * Iterates over items of an array or set. + * + * @param arr - array or set to iterate + * @param callback - a callback function which receives each array item as its + * single argument + * @param thisArg - the value of this inside callback + */ +function forEachArray(arr, callback, thisArg) { + arr.forEach(callback, thisArg); +} +exports.forEachArray = forEachArray; +/** + * Iterates over key/value pairs of a map or object. + * + * @param obj - map or object to iterate + * @param callback - a callback function which receives object key as its first + * argument and object value as its second argument + * @param thisArg - the value of this inside callback + */ +function forEachObject(obj, callback, thisArg) { + if (isMap(obj)) { + obj.forEach((value, key) => callback.call(thisArg, key, value)); + } + else { + for (const key in obj) { + /* istanbul ignore else */ + if (obj.hasOwnProperty(key)) { + callback.call(thisArg, key, obj[key]); + } + } + } +} +exports.forEachObject = forEachObject; +/** + * Returns the number of entries in an array or set. + * + * @param arr - array or set + */ +function arrayLength(obj) { + if (isSet(obj)) { + return obj.size; + } + else { + return obj.length; + } +} +exports.arrayLength = arrayLength; +/** + * Returns the number of entries in a map or object. + * + * @param obj - map or object + */ +function objectLength(obj) { + if (isMap(obj)) { + return obj.size; + } + else { + return Object.keys(obj).length; + } +} +exports.objectLength = objectLength; +/** + * Gets the value of a key from a map or object. + * + * @param obj - map or object + * @param key - the key to retrieve + */ +function getObjectValue(obj, key) { + if (isMap(obj)) { + return obj.get(key); + } + else { + return obj[key]; + } +} +exports.getObjectValue = getObjectValue; +/** + * Removes a property from a map or object. + * + * @param obj - map or object + * @param key - the key to remove + */ +function removeObjectValue(obj, key) { + if (isMap(obj)) { + obj.delete(key); + } + else { + delete obj[key]; + } +} +exports.removeObjectValue = removeObjectValue; +/** + * Deep clones the given object. + * + * @param obj - an object + */ +function clone(obj) { + if (isFunction(obj)) { + return obj; + } + else if (isArray(obj)) { + const result = []; + for (const item of obj) { + result.push(clone(item)); + } + return result; + } + else if (isObject(obj)) { + const result = {}; + for (const key in obj) { + /* istanbul ignore next */ + if (obj.hasOwnProperty(key)) { + const val = obj[key]; + result[key] = clone(val); + } + } + return result; + } + else { + return obj; + } +} +exports.clone = clone; +/** + * Type guard for boolean types + * + * @param x - a variable to type check + */ +function isBoolean(x) { + return typeof x === "boolean"; +} +exports.isBoolean = isBoolean; +/** + * Type guard for numeric types + * + * @param x - a variable to type check + */ +function isNumber(x) { + return typeof x === "number"; +} +exports.isNumber = isNumber; +/** + * Type guard for strings + * + * @param x - a variable to type check + */ +function isString(x) { + return typeof x === "string"; +} +exports.isString = isString; +/** + * Type guard for function objects + * + * @param x - a variable to type check + */ +function isFunction(x) { + return !!x && Object.prototype.toString.call(x) === '[object Function]'; +} +exports.isFunction = isFunction; +/** + * Type guard for JS objects + * + * _Note:_ Functions are objects too + * + * @param x - a variable to type check + */ +function isObject(x) { + const type = typeof x; + return !!x && (type === 'function' || type === 'object'); +} +exports.isObject = isObject; +/** + * Type guard for arrays + * + * @param x - a variable to type check + */ +function isArray(x) { + return Array.isArray(x); +} +exports.isArray = isArray; +/** + * Type guard for sets. + * + * @param x - a variable to check + */ +function isSet(x) { + return x instanceof Set; +} +exports.isSet = isSet; +/** + * Type guard for maps. + * + * @param x - a variable to check + */ +function isMap(x) { + return x instanceof Map; +} +exports.isMap = isMap; +/** + * Determines if `x` is an empty Array or an Object with no own properties. + * + * @param x - a variable to check + */ +function isEmpty(x) { + if (isArray(x)) { + return !x.length; + } + else if (isSet(x)) { + return !x.size; + } + else if (isMap(x)) { + return !x.size; + } + else if (isObject(x)) { + for (const key in x) { + if (x.hasOwnProperty(key)) { + return false; + } + } + return true; + } + return false; +} +exports.isEmpty = isEmpty; +/** + * Determines if `x` is a plain Object. + * + * @param x - a variable to check + */ +function isPlainObject(x) { + if (isObject(x)) { + const proto = Object.getPrototypeOf(x); + const ctor = proto.constructor; + return proto && ctor && + (typeof ctor === 'function') && (ctor instanceof ctor) && + (Function.prototype.toString.call(ctor) === Function.prototype.toString.call(Object)); + } + return false; +} +exports.isPlainObject = isPlainObject; +/** + * Determines if `x` is an iterable Object. + * + * @param x - a variable to check + */ +function isIterable(x) { + return x && (typeof x[Symbol.iterator] === 'function'); +} +exports.isIterable = isIterable; +/** + * Gets the primitive value of an object. + */ +function getValue(obj) { + if (isFunction(obj.valueOf)) { + return obj.valueOf(); + } + else { + return obj; + } +} +exports.getValue = getValue; +/** + * UTF-8 encodes the given string. + * + * @param input - a string + */ +function utf8Encode(input) { + const bytes = new Uint8Array(input.length * 4); + let byteIndex = 0; + for (let i = 0; i < input.length; i++) { + let char = input.charCodeAt(i); + if (char < 128) { + bytes[byteIndex++] = char; + continue; + } + else if (char < 2048) { + bytes[byteIndex++] = char >> 6 | 192; + } + else { + if (char > 0xd7ff && char < 0xdc00) { + if (++i >= input.length) { + throw new Error("Incomplete surrogate pair."); + } + const c2 = input.charCodeAt(i); + if (c2 < 0xdc00 || c2 > 0xdfff) { + throw new Error("Invalid surrogate character."); + } + char = 0x10000 + ((char & 0x03ff) << 10) + (c2 & 0x03ff); + bytes[byteIndex++] = char >> 18 | 240; + bytes[byteIndex++] = char >> 12 & 63 | 128; + } + else { + bytes[byteIndex++] = char >> 12 | 224; + } + bytes[byteIndex++] = char >> 6 & 63 | 128; + } + bytes[byteIndex++] = char & 63 | 128; + } + return bytes.subarray(0, byteIndex); +} +exports.utf8Encode = utf8Encode; +/** + * UTF-8 decodes the given byte sequence into a string. + * + * @param bytes - a byte sequence + */ +function utf8Decode(bytes) { + let result = ""; + let i = 0; + while (i < bytes.length) { + var c = bytes[i++]; + if (c > 127) { + if (c > 191 && c < 224) { + if (i >= bytes.length) { + throw new Error("Incomplete 2-byte sequence."); + } + c = (c & 31) << 6 | bytes[i++] & 63; + } + else if (c > 223 && c < 240) { + if (i + 1 >= bytes.length) { + throw new Error("Incomplete 3-byte sequence."); + } + c = (c & 15) << 12 | (bytes[i++] & 63) << 6 | bytes[i++] & 63; + } + else if (c > 239 && c < 248) { + if (i + 2 >= bytes.length) { + throw new Error("Incomplete 4-byte sequence."); + } + c = (c & 7) << 18 | (bytes[i++] & 63) << 12 | (bytes[i++] & 63) << 6 | bytes[i++] & 63; + } + else { + throw new Error("Unknown multi-byte start."); + } + } + if (c <= 0xffff) { + result += String.fromCharCode(c); + } + else if (c <= 0x10ffff) { + c -= 0x10000; + result += String.fromCharCode(c >> 10 | 0xd800); + result += String.fromCharCode(c & 0x3FF | 0xdc00); + } + else { + throw new Error("Code point exceeds UTF-16 limit."); + } + } + return result; +} +exports.utf8Decode = utf8Decode; +//# sourceMappingURL=index.js.map + +/***/ }), + +/***/ 344: +/***/ (function(__unusedmodule, exports) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const PotentialCustomElementName = /[a-z]([\0-\t\x2D\._a-z\xB7\xC0-\xD6\xD8-\xF6\xF8-\u037D\u037F-\u1FFF\u200C\u200D\u203F\u2040\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]|[\uD800-\uDB7F][\uDC00-\uDFFF])*-([\0-\t\x2D\._a-z\xB7\xC0-\xD6\xD8-\xF6\xF8-\u037D\u037F-\u1FFF\u200C\u200D\u203F\u2040\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]|[\uD800-\uDB7F][\uDC00-\uDFFF])*/; +const NamesWithHyphen = new Set(['annotation-xml', 'color-profile', + 'font-face', 'font-face-src', 'font-face-uri', 'font-face-format', + 'font-face-name', 'missing-glyph']); +const ElementNames = new Set(['article', 'aside', 'blockquote', + 'body', 'div', 'footer', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', + 'header', 'main', 'nav', 'p', 'section', 'span']); +const VoidElementNames = new Set(['area', 'base', 'basefont', + 'bgsound', 'br', 'col', 'embed', 'frame', 'hr', 'img', 'input', 'keygen', + 'link', 'menuitem', 'meta', 'param', 'source', 'track', 'wbr']); +const ShadowHostNames = new Set(['article', 'aside', 'blockquote', 'body', + 'div', 'footer', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'main', + 'nav', 'p', 'section', 'span']); +/** + * Determines if the given string is a valid custom element name. + * + * @param name - a name string + */ +function customElement_isValidCustomElementName(name) { + if (!PotentialCustomElementName.test(name)) + return false; + if (NamesWithHyphen.has(name)) + return false; + return true; +} +exports.customElement_isValidCustomElementName = customElement_isValidCustomElementName; +/** + * Determines if the given string is a valid element name. + * + * @param name - a name string + */ +function customElement_isValidElementName(name) { + return (ElementNames.has(name)); +} +exports.customElement_isValidElementName = customElement_isValidElementName; +/** + * Determines if the given string is a void element name. + * + * @param name - a name string + */ +function customElement_isVoidElementName(name) { + return (VoidElementNames.has(name)); +} +exports.customElement_isVoidElementName = customElement_isVoidElementName; +/** + * Determines if the given string is a valid shadow host element name. + * + * @param name - a name string + */ +function customElement_isValidShadowHostName(name) { + return (ShadowHostNames.has(name)); +} +exports.customElement_isValidShadowHostName = customElement_isValidShadowHostName; +/** + * Enqueues an upgrade reaction for a custom element. + * + * @param element - a custom element + * @param definition - a custom element definition + */ +function customElement_enqueueACustomElementUpgradeReaction(element, definition) { + // TODO: Implement in HTML DOM +} +exports.customElement_enqueueACustomElementUpgradeReaction = customElement_enqueueACustomElementUpgradeReaction; +/** + * Enqueues a callback reaction for a custom element. + * + * @param element - a custom element + * @param callbackName - name of the callback + * @param args - callback arguments + */ +function customElement_enqueueACustomElementCallbackReaction(element, callbackName, args) { + // TODO: Implement in HTML DOM +} +exports.customElement_enqueueACustomElementCallbackReaction = customElement_enqueueACustomElementCallbackReaction; +/** + * Upgrade a custom element. + * + * @param element - a custom element + */ +function customElement_upgrade(definition, element) { + // TODO: Implement in HTML DOM +} +exports.customElement_upgrade = customElement_upgrade; +/** + * Tries to upgrade a custom element. + * + * @param element - a custom element + */ +function customElement_tryToUpgrade(element) { + // TODO: Implement in HTML DOM +} +exports.customElement_tryToUpgrade = customElement_tryToUpgrade; +/** + * Looks up a custom element definition. + * + * @param document - a document + * @param namespace - element namespace + * @param localName - element local name + * @param is - an `is` value + */ +function customElement_lookUpACustomElementDefinition(document, namespace, localName, is) { + // TODO: Implement in HTML DOM + return null; +} +exports.customElement_lookUpACustomElementDefinition = customElement_lookUpACustomElementDefinition; +//# sourceMappingURL=CustomElementAlgorithm.js.map + +/***/ }), + +/***/ 347: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const CodePoints_1 = __webpack_require__(780); +/** + * Base-64 encodes the given string. + * + * @param input - a string + */ +function forgivingBase64Encode(input) { + /** + * To forgiving-base64 encode given a byte sequence data, apply the base64 + * algorithm defined in section 4 of RFC 4648 to data and return the result. + * [RFC4648] + */ + return Buffer.from(input).toString('base64'); +} +exports.forgivingBase64Encode = forgivingBase64Encode; +/** + * Decodes a base-64 string. + * + * @param input - a string + */ +function forgivingBase64Decode(input) { + if (input === "") + return ""; + /** + * 1. Remove all ASCII whitespace from data. + */ + input = input.replace(CodePoints_1.ASCIIWhiteSpace, ''); + /** + * 2. If data’s length divides by 4 leaving no remainder, then: + * 2.1. If data ends with one or two U+003D (=) code points, then remove them from data. + */ + if (input.length % 4 === 0) { + if (input.endsWith("==")) { + input = input.substr(0, input.length - 2); + } + else if (input.endsWith("=")) { + input = input.substr(0, input.length - 1); + } + } + /** + * 3. If data’s length divides by 4 leaving a remainder of 1, then return failure. + */ + if (input.length % 4 === 1) + return null; + /** + * 4. If data contains a code point that is not one of + * - U+002B (+) + * - U+002F (/) + * - ASCII alphanumeric + * then return failure. + */ + if (!/[0-9A-Za-z+/]/.test(input)) + return null; + /** + * 5. Let output be an empty byte sequence. + * 6. Let buffer be an empty buffer that can have bits appended to it. + * 7. Let position be a position variable for data, initially pointing at the + * start of data. + * 8. While position does not point past the end of data: + * 8.1. Find the code point pointed to by position in the second column of + * Table 1: The Base 64 Alphabet of RFC 4648. Let n be the number given in the + * first cell of the same row. [RFC4648] + * 8.2. Append the six bits corresponding to n, most significant bit first, + * to buffer. + * 8.3. If buffer has accumulated 24 bits, interpret them as three 8-bit + * big-endian numbers. Append three bytes with values equal to those numbers + * to output, in the same order, and then empty buffer. + * 8.4. Advance position by 1. + * 9. If buffer is not empty, it contains either 12 or 18 bits. If it contains + * 12 bits, then discard the last four and interpret the remaining eight as an + * 8-bit big-endian number. If it contains 18 bits, then discard the last two + * and interpret the remaining 16 as two 8-bit big-endian numbers. Append the + * one or two bytes with values equal to those one or two numbers to output, + * in the same order. + * 10. Return output. + */ + return Buffer.from(input, 'base64').toString('utf8'); +} +exports.forgivingBase64Decode = forgivingBase64Decode; +//# sourceMappingURL=Base64.js.map + +/***/ }), + +/***/ 350: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const interfaces_1 = __webpack_require__(970); +const TreeAlgorithm_1 = __webpack_require__(873); +/** + * Defines the position of a boundary point relative to another. + * + * @param bp - a boundary point + * @param relativeTo - a boundary point to compare to + */ +function boundaryPoint_position(bp, relativeTo) { + const nodeA = bp[0]; + const offsetA = bp[1]; + const nodeB = relativeTo[0]; + const offsetB = relativeTo[1]; + /** + * 1. Assert: nodeA and nodeB have the same root. + */ + console.assert(TreeAlgorithm_1.tree_rootNode(nodeA) === TreeAlgorithm_1.tree_rootNode(nodeB), "Boundary points must share the same root node."); + /** + * 2. If nodeA is nodeB, then return equal if offsetA is offsetB, before + * if offsetA is less than offsetB, and after if offsetA is greater than + * offsetB. + */ + if (nodeA === nodeB) { + if (offsetA === offsetB) { + return interfaces_1.BoundaryPosition.Equal; + } + else if (offsetA < offsetB) { + return interfaces_1.BoundaryPosition.Before; + } + else { + return interfaces_1.BoundaryPosition.After; + } + } + /** + * 3. If nodeA is following nodeB, then if the position of (nodeB, offsetB) + * relative to (nodeA, offsetA) is before, return after, and if it is after, + * return before. + */ + if (TreeAlgorithm_1.tree_isFollowing(nodeB, nodeA)) { + const pos = boundaryPoint_position([nodeB, offsetB], [nodeA, offsetA]); + if (pos === interfaces_1.BoundaryPosition.Before) { + return interfaces_1.BoundaryPosition.After; + } + else if (pos === interfaces_1.BoundaryPosition.After) { + return interfaces_1.BoundaryPosition.Before; + } + } + /** + * 4. If nodeA is an ancestor of nodeB: + */ + if (TreeAlgorithm_1.tree_isAncestorOf(nodeB, nodeA)) { + /** + * 4.1. Let child be nodeB. + * 4.2. While child is not a child of nodeA, set child to its parent. + * 4.3. If child’s index is less than offsetA, then return after. + */ + let child = nodeB; + while (!TreeAlgorithm_1.tree_isChildOf(nodeA, child)) { + /* istanbul ignore else */ + if (child._parent !== null) { + child = child._parent; + } + } + if (TreeAlgorithm_1.tree_index(child) < offsetA) { + return interfaces_1.BoundaryPosition.After; + } + } + /** + * 5. Return before. + */ + return interfaces_1.BoundaryPosition.Before; +} +exports.boundaryPoint_position = boundaryPoint_position; +//# sourceMappingURL=BoundaryPointAlgorithm.js.map + +/***/ }), + +/***/ 357: +/***/ (function(module) { + +module.exports = require("assert"); + +/***/ }), + +/***/ 392: +/***/ (function(__unusedmodule, exports) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * A namespace prefix map is a map that associates namespaceURI and namespace + * prefix lists, where namespaceURI values are the map's unique keys (which can + * include the null value representing no namespace), and ordered lists of + * associated prefix values are the map's key values. The namespace prefix map + * will be populated by previously seen namespaceURIs and all their previously + * encountered prefix associations for a given node and its ancestors. + * + * _Note:_ The last seen prefix for a given namespaceURI is at the end of its + * respective list. The list is searched to find potentially matching prefixes, + * and if no matches are found for the given namespaceURI, then the last prefix + * in the list is used. See copy a namespace prefix map and retrieve a preferred + * prefix string for additional details. + * + * See: https://w3c.github.io/DOM-Parsing/#the-namespace-prefix-map + */ +class NamespacePrefixMap { + constructor() { + this._items = {}; + this._nullItems = []; + } + /** + * Creates a copy of the map. + */ + copy() { + /** + * To copy a namespace prefix map map means to copy the map's keys into a + * new empty namespace prefix map, and to copy each of the values in the + * namespace prefix list associated with each keys' value into a new list + * which should be associated with the respective key in the new map. + */ + const mapCopy = new NamespacePrefixMap(); + for (const key in this._items) { + mapCopy._items[key] = this._items[key].slice(0); + } + mapCopy._nullItems = this._nullItems.slice(0); + return mapCopy; + } + /** + * Retrieves a preferred prefix string from the namespace prefix map. + * + * @param preferredPrefix - preferred prefix string + * @param ns - namespace + */ + get(preferredPrefix, ns) { + /** + * 1. Let candidates list be the result of retrieving a list from map where + * there exists a key in map that matches the value of ns or if there is no + * such key, then stop running these steps, and return the null value. + */ + const candidatesList = ns === null ? this._nullItems : (this._items[ns] || null); + if (candidatesList === null) { + return null; + } + /** + * 2. Otherwise, for each prefix value prefix in candidates list, iterating + * from beginning to end: + * + * _Note:_ There will always be at least one prefix value in the list. + */ + let prefix = null; + for (let i = 0; i < candidatesList.length; i++) { + prefix = candidatesList[i]; + /** + * 2.1. If prefix matches preferred prefix, then stop running these steps + * and return prefix. + */ + if (prefix === preferredPrefix) { + return prefix; + } + } + /** + * 2.2. If prefix is the last item in the candidates list, then stop + * running these steps and return prefix. + */ + return prefix; + } + /** + * Checks if a prefix string is found in the namespace prefix map associated + * with the given namespace. + * + * @param prefix - prefix string + * @param ns - namespace + */ + has(prefix, ns) { + /** + * 1. Let candidates list be the result of retrieving a list from map where + * there exists a key in map that matches the value of ns or if there is + * no such key, then stop running these steps, and return false. + */ + const candidatesList = ns === null ? this._nullItems : (this._items[ns] || null); + if (candidatesList === null) { + return false; + } + /** + * 2. If the value of prefix occurs at least once in candidates list, + * return true, otherwise return false. + */ + return (candidatesList.indexOf(prefix) !== -1); + } + /** + * Checks if a prefix string is found in the namespace prefix map. + * + * @param prefix - prefix string + */ + hasPrefix(prefix) { + if (this._nullItems.indexOf(prefix) !== -1) + return true; + for (const key in this._items) { + if (this._items[key].indexOf(prefix) !== -1) + return true; + } + return false; + } + /** + * Adds a prefix string associated with a namespace to the prefix map. + * + * @param prefix - prefix string + * @param ns - namespace + */ + set(prefix, ns) { + /** + * 1. Let candidates list be the result of retrieving a list from map where + * there exists a key in map that matches the value of ns or if there is + * no such key, then let candidates list be null. + */ + const candidatesList = ns === null ? this._nullItems : (this._items[ns] || null); + /** + * 2. If candidates list is null, then create a new list with prefix as the + * only item in the list, and associate that list with a new key ns in map. + * 3. Otherwise, append prefix to the end of candidates list. + * + * _Note:_ The steps in retrieve a preferred prefix string use the list to + * track the most recently used (MRU) prefix associated with a given + * namespace, which will be the prefix at the end of the list. This list + * may contain duplicates of the same prefix value seen earlier + * (and that's OK). + */ + if (ns !== null && candidatesList === null) { + this._items[ns] = [prefix]; + } + else { + candidatesList.push(prefix); + } + } +} +exports.NamespacePrefixMap = NamespacePrefixMap; +//# sourceMappingURL=NamespacePrefixMap.js.map + +/***/ }), + +/***/ 413: +/***/ (function(module, __unusedexports, __webpack_require__) { + +module.exports = __webpack_require__(141); + + +/***/ }), + +/***/ 417: +/***/ (function(module) { + +module.exports = require("crypto"); + +/***/ }), + +/***/ 419: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const util_1 = __webpack_require__(592); +const interfaces_1 = __webpack_require__(970); +const BaseWriter_1 = __webpack_require__(462); +/** + * Serializes XML nodes into objects and arrays. + */ +class ObjectWriter extends BaseWriter_1.BaseWriter { + /** + * Produces an XML serialization of the given node. + * + * @param node - node to serialize + * @param writerOptions - serialization options + */ + serialize(node, writerOptions) { + const options = util_1.applyDefaults(writerOptions, { + format: "object", + wellFormed: false, + noDoubleEncoding: false, + group: false + }); + this._currentList = []; + this._currentIndex = 0; + this._listRegister = [this._currentList]; + /** + * First pass, serialize nodes + * This creates a list of nodes grouped under node types while preserving + * insertion order. For example: + * [ + * root: [ + * node: [ + * { "@" : { "att1": "val1", "att2": "val2" } + * { "#": "node text" } + * { childNode: [] } + * { "#": "more text" } + * ], + * node: [ + * { "@" : { "att": "val" } + * { "#": [ "text line1", "text line2" ] } + * ] + * ] + * ] + */ + this.serializeNode(node, options.wellFormed, options.noDoubleEncoding); + /** + * Second pass, process node lists. Above example becomes: + * { + * root: { + * node: [ + * { + * "@att1": "val1", + * "@att2": "val2", + * "#1": "node text", + * childNode: {}, + * "#2": "more text" + * }, + * { + * "@att": "val", + * "#": [ "text line1", "text line2" ] + * } + * ] + * } + * } + */ + return this._process(this._currentList, options); + } + _process(items, options) { + if (items.length === 0) + return {}; + // determine if there are non-unique element names + const namesSeen = {}; + let hasNonUniqueNames = false; + let textCount = 0; + let commentCount = 0; + let instructionCount = 0; + let cdataCount = 0; + for (let i = 0; i < items.length; i++) { + const item = items[i]; + const key = Object.keys(item)[0]; + switch (key) { + case "@": + continue; + case "#": + textCount++; + break; + case "!": + commentCount++; + break; + case "?": + instructionCount++; + break; + case "$": + cdataCount++; + break; + default: + if (namesSeen[key]) { + hasNonUniqueNames = true; + } + else { + namesSeen[key] = true; + } + break; + } + } + const defAttrKey = this._getAttrKey(); + const defTextKey = this._getNodeKey(interfaces_1.NodeType.Text); + const defCommentKey = this._getNodeKey(interfaces_1.NodeType.Comment); + const defInstructionKey = this._getNodeKey(interfaces_1.NodeType.ProcessingInstruction); + const defCdataKey = this._getNodeKey(interfaces_1.NodeType.CData); + if (textCount === 1 && items.length === 1 && util_1.isString(items[0]["#"])) { + // special case of an element node with a single text node + return items[0]["#"]; + } + else if (hasNonUniqueNames) { + // list contains element nodes with non-unique names + // return an array with mixed content notation + const result = []; + const obj = { [defTextKey]: result }; + for (let i = 0; i < items.length; i++) { + const item = items[i]; + const key = Object.keys(item)[0]; + switch (key) { + case "@": + const attrs = item["@"]; + const attrKeys = Object.keys(attrs); + if (attrKeys.length === 1) { + result.push({ [defAttrKey + attrKeys[0]]: attrs[attrKeys[0]] }); + } + else { + result.push({ [defAttrKey]: item["@"] }); + } + break; + case "#": + result.push({ [defTextKey]: item["#"] }); + break; + case "!": + result.push({ [defCommentKey]: item["!"] }); + break; + case "?": + result.push({ [defInstructionKey]: item["?"] }); + break; + case "$": + result.push({ [defCdataKey]: item["$"] }); + break; + default: + // element node + const ele = item; + if (ele[key].length !== 0 && util_1.isArray(ele[key][0])) { + // group of element nodes + const eleGroup = []; + const listOfLists = ele[key]; + for (let i = 0; i < listOfLists.length; i++) { + eleGroup.push(this._process(listOfLists[i], options)); + } + result.push({ [key]: eleGroup }); + } + else { + // single element node + result.push({ [key]: this._process(ele[key], options) }); + } + break; + } + } + return obj; + } + else { + // all element nodes have unique names + // return an object while prefixing data node keys + let textId = 1; + let commentId = 1; + let instructionId = 1; + let cdataId = 1; + const obj = {}; + for (let i = 0; i < items.length; i++) { + const item = items[i]; + const key = Object.keys(item)[0]; + switch (key) { + case "@": + const attrs = item["@"]; + const attrKeys = Object.keys(attrs); + if (!options.group || attrKeys.length === 1) { + for (const attrName in attrs) { + obj[defAttrKey + attrName] = attrs[attrName]; + } + } + else { + obj[defAttrKey] = attrs; + } + break; + case "#": + textId = this._processSpecItem(item["#"], obj, options.group, defTextKey, textCount, textId); + break; + case "!": + commentId = this._processSpecItem(item["!"], obj, options.group, defCommentKey, commentCount, commentId); + break; + case "?": + instructionId = this._processSpecItem(item["?"], obj, options.group, defInstructionKey, instructionCount, instructionId); + break; + case "$": + cdataId = this._processSpecItem(item["$"], obj, options.group, defCdataKey, cdataCount, cdataId); + break; + default: + // element node + const ele = item; + if (ele[key].length !== 0 && util_1.isArray(ele[key][0])) { + // group of element nodes + const eleGroup = []; + const listOfLists = ele[key]; + for (let i = 0; i < listOfLists.length; i++) { + eleGroup.push(this._process(listOfLists[i], options)); + } + obj[key] = eleGroup; + } + else { + // single element node + obj[key] = this._process(ele[key], options); + } + break; + } + } + return obj; + } + } + _processSpecItem(item, obj, group, defKey, count, id) { + if (!group && util_1.isArray(item) && count + item.length > 2) { + for (const subItem of item) { + const key = defKey + (id++).toString(); + obj[key] = subItem; + } + } + else { + const key = count > 1 ? defKey + (id++).toString() : defKey; + obj[key] = item; + } + return id; + } + /** @inheritdoc */ + beginElement(name) { + const childItems = []; + if (this._currentList.length === 0) { + this._currentList.push({ [name]: childItems }); + } + else { + const lastItem = this._currentList[this._currentList.length - 1]; + if (this._isElementNode(lastItem, name)) { + if (lastItem[name].length !== 0 && util_1.isArray(lastItem[name][0])) { + const listOfLists = lastItem[name]; + listOfLists.push(childItems); + } + else { + lastItem[name] = [lastItem[name], childItems]; + } + } + else { + this._currentList.push({ [name]: childItems }); + } + } + this._currentIndex++; + if (this._listRegister.length > this._currentIndex) { + this._listRegister[this._currentIndex] = childItems; + } + else { + this._listRegister.push(childItems); + } + this._currentList = childItems; + } + /** @inheritdoc */ + endElement() { + this._currentList = this._listRegister[--this._currentIndex]; + } + /** @inheritdoc */ + attribute(name, value) { + if (this._currentList.length === 0) { + this._currentList.push({ "@": { [name]: value } }); + } + else { + const lastItem = this._currentList[this._currentList.length - 1]; + /* istanbul ignore else */ + if (this._isAttrNode(lastItem)) { + lastItem["@"][name] = value; + } + else { + this._currentList.push({ "@": { [name]: value } }); + } + } + } + /** @inheritdoc */ + comment(data) { + if (this._currentList.length === 0) { + this._currentList.push({ "!": data }); + } + else { + const lastItem = this._currentList[this._currentList.length - 1]; + if (this._isCommentNode(lastItem)) { + if (util_1.isArray(lastItem["!"])) { + lastItem["!"].push(data); + } + else { + lastItem["!"] = [lastItem["!"], data]; + } + } + else { + this._currentList.push({ "!": data }); + } + } + } + /** @inheritdoc */ + text(data) { + if (this._currentList.length === 0) { + this._currentList.push({ "#": data }); + } + else { + const lastItem = this._currentList[this._currentList.length - 1]; + if (this._isTextNode(lastItem)) { + if (util_1.isArray(lastItem["#"])) { + lastItem["#"].push(data); + } + else { + lastItem["#"] = [lastItem["#"], data]; + } + } + else { + this._currentList.push({ "#": data }); + } + } + } + /** @inheritdoc */ + instruction(target, data) { + const value = (data === "" ? target : target + " " + data); + if (this._currentList.length === 0) { + this._currentList.push({ "?": value }); + } + else { + const lastItem = this._currentList[this._currentList.length - 1]; + if (this._isInstructionNode(lastItem)) { + if (util_1.isArray(lastItem["?"])) { + lastItem["?"].push(value); + } + else { + lastItem["?"] = [lastItem["?"], value]; + } + } + else { + this._currentList.push({ "?": value }); + } + } + } + /** @inheritdoc */ + cdata(data) { + if (this._currentList.length === 0) { + this._currentList.push({ "$": data }); + } + else { + const lastItem = this._currentList[this._currentList.length - 1]; + if (this._isCDATANode(lastItem)) { + if (util_1.isArray(lastItem["$"])) { + lastItem["$"].push(data); + } + else { + lastItem["$"] = [lastItem["$"], data]; + } + } + else { + this._currentList.push({ "$": data }); + } + } + } + _isAttrNode(x) { + return "@" in x; + } + _isTextNode(x) { + return "#" in x; + } + _isCommentNode(x) { + return "!" in x; + } + _isInstructionNode(x) { + return "?" in x; + } + _isCDATANode(x) { + return "$" in x; + } + _isElementNode(x, name) { + return name in x; + } + /** + * Returns an object key for an attribute or namespace declaration. + */ + _getAttrKey() { + return this._builderOptions.convert.att; + } + /** + * Returns an object key for the given node type. + * + * @param nodeType - node type to get a key for + */ + _getNodeKey(nodeType) { + switch (nodeType) { + case interfaces_1.NodeType.Comment: + return this._builderOptions.convert.comment; + case interfaces_1.NodeType.Text: + return this._builderOptions.convert.text; + case interfaces_1.NodeType.ProcessingInstruction: + return this._builderOptions.convert.ins; + case interfaces_1.NodeType.CData: + return this._builderOptions.convert.cdata; + /* istanbul ignore next */ + default: + throw new Error("Invalid node type."); + } + } +} +exports.ObjectWriter = ObjectWriter; +//# sourceMappingURL=ObjectWriter.js.map + +/***/ }), + +/***/ 425: +/***/ (function(__unusedmodule, exports) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * Returns the count of bytes in a sequence. + * + * @param list - a byte sequence + */ +function length(list) { + /** + * A byte sequence’s length is the number of bytes it contains. + */ + return list.length; +} +exports.length = length; +/** + * Converts each byte to lowercase. + * + * @param list - a byte sequence + */ +function byteLowercase(list) { + /** + * To byte-lowercase a byte sequence, increase each byte it contains, in the + * range 0x41 (A) to 0x5A (Z), inclusive, by 0x20. + */ + for (let i = 0; i < list.length; i++) { + const c = list[i]; + if (c >= 0x41 && c <= 0x5A) { + list[i] = c + 0x20; + } + } +} +exports.byteLowercase = byteLowercase; +/** + * Converts each byte to uppercase. + * + * @param list - a byte sequence + */ +function byteUppercase(list) { + /** + * To byte-uppercase a byte sequence, subtract each byte it contains, in the + * range 0x61 (a) to 0x7A (z), inclusive, by 0x20. + */ + for (let i = 0; i < list.length; i++) { + const c = list[i]; + if (c >= 0x61 && c <= 0x7A) { + list[i] = c - 0x20; + } + } +} +exports.byteUppercase = byteUppercase; +/** + * Compares two byte sequences. + * + * @param listA - a byte sequence + * @param listB - a byte sequence + */ +function byteCaseInsensitiveMatch(listA, listB) { + /** + * A byte sequence A is a byte-case-insensitive match for a byte sequence B, + * if the byte-lowercase of A is the byte-lowercase of B. + */ + if (listA.length !== listB.length) + return false; + for (let i = 0; i < listA.length; i++) { + let a = listA[i]; + let b = listB[i]; + if (a >= 0x41 && a <= 0x5A) + a += 0x20; + if (b >= 0x41 && b <= 0x5A) + b += 0x20; + if (a !== b) + return false; + } + return true; +} +exports.byteCaseInsensitiveMatch = byteCaseInsensitiveMatch; +/** + * Determines if `listA` starts with `listB`. + * + * @param listA - a byte sequence + * @param listB - a byte sequence + */ +function startsWith(listA, listB) { + /** + * 1. Let i be 0. + * 2. While true: + * 2.1. Let aByte be the ith byte of a if i is less than a’s length; otherwise null. + * 2.3. Let bByte be the ith byte of b if i is less than b’s length; otherwise null. + * 2.4. If bByte is null, then return true. + * 2.5. Return false if aByte is not bByte. + * 2.6. Set i to i + 1. + */ + let i = 0; + while (true) { + if (i >= listA.length) + return false; + if (i >= listB.length) + return true; + if (listA[i] !== listB[i]) + return false; + i++; + } +} +exports.startsWith = startsWith; +/** + * Determines if `listA` is less than `listB`. + * + * @param listA - a byte sequence + * @param listB - a byte sequence + */ +function byteLessThan(listA, listB) { + /** + * 1. If b starts with a, then return false. + * 2. If a starts with b, then return true. + * 3. Let n be the smallest index such that the nth byte of a is different + * from the nth byte of b. (There has to be such an index, since neither byte + * sequence starts with the other.) + * 4. If the nth byte of a is less than the nth byte of b, then return true. + * 5. Return false. + */ + let i = 0; + while (true) { + if (i >= listA.length) + return false; + if (i >= listB.length) + return true; + const a = listA[i]; + const b = listB[i]; + if (a < b) + return true; + else if (a > b) + return false; + i++; + } +} +exports.byteLessThan = byteLessThan; +/** + * Decodes a byte sequence into a string. + * + * @param list - a byte sequence + */ +function isomorphicDecode(list) { + /** + * To isomorphic decode a byte sequence input, return a string whose length is + * equal to input’s length and whose code points have the same values as + * input’s bytes, in the same order. + */ + return String.fromCodePoint(...list); +} +exports.isomorphicDecode = isomorphicDecode; +//# sourceMappingURL=ByteSequence.js.map + +/***/ }), + +/***/ 427: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const interfaces_1 = __webpack_require__(970); +const algorithm_1 = __webpack_require__(163); +const WebIDLAlgorithm_1 = __webpack_require__(495); +/** + * Represents a DOM event. + */ +class EventImpl { + /** + * Initializes a new instance of `Event`. + */ + constructor(type, eventInit) { + this._target = null; + this._relatedTarget = null; + this._touchTargetList = []; + this._path = []; + this._currentTarget = null; + this._eventPhase = interfaces_1.EventPhase.None; + this._stopPropagationFlag = false; + this._stopImmediatePropagationFlag = false; + this._canceledFlag = false; + this._inPassiveListenerFlag = false; + this._composedFlag = false; + this._initializedFlag = false; + this._dispatchFlag = false; + this._isTrusted = false; + this._bubbles = false; + this._cancelable = false; + /** + * When a constructor of the Event interface, or of an interface that + * inherits from the Event interface, is invoked, these steps must be run, + * given the arguments type and eventInitDict: + * 1. Let event be the result of running the inner event creation steps with + * this interface, null, now, and eventInitDict. + * 2. Initialize event’s type attribute to type. + * 3. Return event. + */ + this._type = type; + if (eventInit) { + this._bubbles = eventInit.bubbles || false; + this._cancelable = eventInit.cancelable || false; + this._composedFlag = eventInit.composed || false; + } + this._initializedFlag = true; + this._timeStamp = new Date().getTime(); + } + /** @inheritdoc */ + get type() { return this._type; } + /** @inheritdoc */ + get target() { return this._target; } + /** @inheritdoc */ + get srcElement() { return this._target; } + /** @inheritdoc */ + get currentTarget() { return this._currentTarget; } + /** @inheritdoc */ + composedPath() { + /** + * 1. Let composedPath be an empty list. + * 2. Let path be the context object’s path. + * 3. If path is empty, then return composedPath. + * 4. Let currentTarget be the context object’s currentTarget attribute + * value. + * 5. Append currentTarget to composedPath. + * 6. Let currentTargetIndex be 0. + * 7. Let currentTargetHiddenSubtreeLevel be 0. + */ + const composedPath = []; + const path = this._path; + if (path.length === 0) + return composedPath; + const currentTarget = this._currentTarget; + if (currentTarget === null) { + throw new Error("Event currentTarget is null."); + } + composedPath.push(currentTarget); + let currentTargetIndex = 0; + let currentTargetHiddenSubtreeLevel = 0; + /** + * 8. Let index be path’s size − 1. + * 9. While index is greater than or equal to 0: + */ + let index = path.length - 1; + while (index >= 0) { + /** + * 9.1. If path[index]'s root-of-closed-tree is true, then increase + * currentTargetHiddenSubtreeLevel by 1. + * 9.2. If path[index]'s invocation target is currentTarget, then set + * currentTargetIndex to index and break. + * 9.3. If path[index]'s slot-in-closed-tree is true, then decrease + * currentTargetHiddenSubtreeLevel by 1. + * 9.4. Decrease index by 1. + */ + if (path[index].rootOfClosedTree) { + currentTargetHiddenSubtreeLevel++; + } + if (path[index].invocationTarget === currentTarget) { + currentTargetIndex = index; + break; + } + if (path[index].slotInClosedTree) { + currentTargetHiddenSubtreeLevel--; + } + index--; + } + /** + * 10. Let currentHiddenLevel and maxHiddenLevel be + * currentTargetHiddenSubtreeLevel. + */ + let currentHiddenLevel = currentTargetHiddenSubtreeLevel; + let maxHiddenLevel = currentTargetHiddenSubtreeLevel; + /** + * 11. Set index to currentTargetIndex − 1. + * 12. While index is greater than or equal to 0: + */ + index = currentTargetIndex - 1; + while (index >= 0) { + /** + * 12.1. If path[index]'s root-of-closed-tree is true, then increase + * currentHiddenLevel by 1. + * 12.2. If currentHiddenLevel is less than or equal to maxHiddenLevel, + * then prepend path[index]'s invocation target to composedPath. + */ + if (path[index].rootOfClosedTree) { + currentHiddenLevel++; + } + if (currentHiddenLevel <= maxHiddenLevel) { + composedPath.unshift(path[index].invocationTarget); + } + /** + * 12.3. If path[index]'s slot-in-closed-tree is true, then: + */ + if (path[index].slotInClosedTree) { + /** + * 12.3.1. Decrease currentHiddenLevel by 1. + * 12.3.2. If currentHiddenLevel is less than maxHiddenLevel, then set + * maxHiddenLevel to currentHiddenLevel. + */ + currentHiddenLevel--; + if (currentHiddenLevel < maxHiddenLevel) { + maxHiddenLevel = currentHiddenLevel; + } + } + /** + * 12.4. Decrease index by 1. + */ + index--; + } + /** + * 13. Set currentHiddenLevel and maxHiddenLevel to + * currentTargetHiddenSubtreeLevel. + */ + currentHiddenLevel = currentTargetHiddenSubtreeLevel; + maxHiddenLevel = currentTargetHiddenSubtreeLevel; + /** + * 14. Set index to currentTargetIndex + 1. + * 15. While index is less than path’s size: + */ + index = currentTargetIndex + 1; + while (index < path.length) { + /** + * 15.1. If path[index]'s slot-in-closed-tree is true, then increase + * currentHiddenLevel by 1. + * 15.2. If currentHiddenLevel is less than or equal to maxHiddenLevel, + * then append path[index]'s invocation target to composedPath. + */ + if (path[index].slotInClosedTree) { + currentHiddenLevel++; + } + if (currentHiddenLevel <= maxHiddenLevel) { + composedPath.push(path[index].invocationTarget); + } + /** + * 15.3. If path[index]'s root-of-closed-tree is true, then: + */ + if (path[index].rootOfClosedTree) { + /** + * 15.3.1. Decrease currentHiddenLevel by 1. + * 15.3.2. If currentHiddenLevel is less than maxHiddenLevel, then set + * maxHiddenLevel to currentHiddenLevel. + */ + currentHiddenLevel--; + if (currentHiddenLevel < maxHiddenLevel) { + maxHiddenLevel = currentHiddenLevel; + } + } + /** + * 15.4. Increase index by 1. + */ + index++; + } + /** + * 16. Return composedPath. + */ + return composedPath; + } + /** @inheritdoc */ + get eventPhase() { return this._eventPhase; } + /** @inheritdoc */ + stopPropagation() { this._stopPropagationFlag = true; } + /** @inheritdoc */ + get cancelBubble() { return this._stopPropagationFlag; } + set cancelBubble(value) { if (value) + this.stopPropagation(); } + /** @inheritdoc */ + stopImmediatePropagation() { + this._stopPropagationFlag = true; + this._stopImmediatePropagationFlag = true; + } + /** @inheritdoc */ + get bubbles() { return this._bubbles; } + /** @inheritdoc */ + get cancelable() { return this._cancelable; } + /** @inheritdoc */ + get returnValue() { return !this._canceledFlag; } + set returnValue(value) { + if (!value) { + algorithm_1.event_setTheCanceledFlag(this); + } + } + /** @inheritdoc */ + preventDefault() { + algorithm_1.event_setTheCanceledFlag(this); + } + /** @inheritdoc */ + get defaultPrevented() { return this._canceledFlag; } + /** @inheritdoc */ + get composed() { return this._composedFlag; } + /** @inheritdoc */ + get isTrusted() { return this._isTrusted; } + /** @inheritdoc */ + get timeStamp() { return this._timeStamp; } + /** @inheritdoc */ + initEvent(type, bubbles = false, cancelable = false) { + /** + * 1. If the context object’s dispatch flag is set, then return. + */ + if (this._dispatchFlag) + return; + /** + * 2. Initialize the context object with type, bubbles, and cancelable. + */ + algorithm_1.event_initialize(this, type, bubbles, cancelable); + } +} +exports.EventImpl = EventImpl; +EventImpl.NONE = 0; +EventImpl.CAPTURING_PHASE = 1; +EventImpl.AT_TARGET = 2; +EventImpl.BUBBLING_PHASE = 3; +/** + * Define constants on prototype. + */ +WebIDLAlgorithm_1.idl_defineConst(EventImpl.prototype, "NONE", 0); +WebIDLAlgorithm_1.idl_defineConst(EventImpl.prototype, "CAPTURING_PHASE", 1); +WebIDLAlgorithm_1.idl_defineConst(EventImpl.prototype, "AT_TARGET", 2); +WebIDLAlgorithm_1.idl_defineConst(EventImpl.prototype, "BUBBLING_PHASE", 3); +//# sourceMappingURL=EventImpl.js.map + +/***/ }), + +/***/ 429: +/***/ (function(__unusedmodule, exports) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * Appends the given item to the queue. + * + * @param list - a list + * @param item - an item + */ +function enqueue(list, item) { + list.push(item); +} +exports.enqueue = enqueue; +/** + * Removes and returns an item from the queue. + * + * @param list - a list + */ +function dequeue(list) { + return list.shift() || null; +} +exports.dequeue = dequeue; +//# sourceMappingURL=Queue.js.map + +/***/ }), + +/***/ 431: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result["default"] = mod; + return result; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const os = __importStar(__webpack_require__(87)); +/** + * Commands + * + * Command Format: + * ::name key=value,key=value::message + * + * Examples: + * ::warning::This is the message + * ::set-env name=MY_VAR::some value + */ +function issueCommand(command, properties, message) { + const cmd = new Command(command, properties, message); + process.stdout.write(cmd.toString() + os.EOL); +} +exports.issueCommand = issueCommand; +function issue(name, message = '') { + issueCommand(name, {}, message); +} +exports.issue = issue; +const CMD_STRING = '::'; +class Command { + constructor(command, properties, message) { + if (!command) { + command = 'missing.command'; + } + this.command = command; + this.properties = properties; + this.message = message; + } + toString() { + let cmdStr = CMD_STRING + this.command; + if (this.properties && Object.keys(this.properties).length > 0) { + cmdStr += ' '; + let first = true; + for (const key in this.properties) { + if (this.properties.hasOwnProperty(key)) { + const val = this.properties[key]; + if (val) { + if (first) { + first = false; + } + else { + cmdStr += ','; + } + cmdStr += `${key}=${escapeProperty(val)}`; + } + } + } + } + cmdStr += `${CMD_STRING}${escapeData(this.message)}`; + return cmdStr; + } +} +function escapeData(s) { + return (s || '') + .replace(/%/g, '%25') + .replace(/\r/g, '%0D') + .replace(/\n/g, '%0A'); +} +function escapeProperty(s) { + return (s || '') + .replace(/%/g, '%25') + .replace(/\r/g, '%0D') + .replace(/\n/g, '%0A') + .replace(/:/g, '%3A') + .replace(/,/g, '%2C'); +} +//# sourceMappingURL=command.js.map + +/***/ }), + +/***/ 441: +/***/ (function(__unusedmodule, exports) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * Represents a cache for storing order between equal objects. + * + * This cache is used when an algorithm compares two objects and finds them to + * be equal but still needs to establish an order between those two objects. + * When two such objects `a` and `b` are passed to the `check` method, a random + * number is generated with `Math.random()`. If the random number is less than + * `0.5` it is assumed that `a < b` otherwise `a > b`. The random number along + * with `a` and `b` is stored in the cache, so that subsequent checks result + * in the same consistent result. + * + * The cache has a size limit which is defined on initialization. + */ +class CompareCache { + /** + * Initializes a new instance of `CompareCache`. + * + * @param limit - maximum number of items to keep in the cache. When the limit + * is exceeded the first item is removed from the cache. + */ + constructor(limit = 1000) { + this._items = new Map(); + this._limit = limit; + } + /** + * Compares and caches the given objects. Returns `true` if `objA < objB` and + * `false` otherwise. + * + * @param objA - an item to compare + * @param objB - an item to compare + */ + check(objA, objB) { + if (this._items.get(objA) === objB) + return true; + else if (this._items.get(objB) === objA) + return false; + const result = (Math.random() < 0.5); + if (result) { + this._items.set(objA, objB); + } + else { + this._items.set(objB, objA); + } + if (this._items.size > this._limit) { + const it = this._items.keys().next(); + /* istanbul ignore else */ + if (!it.done) { + this._items.delete(it.value); + } + } + return result; + } +} +exports.CompareCache = CompareCache; +//# sourceMappingURL=CompareCache.js.map + +/***/ }), + +/***/ 442: +/***/ (function(__unusedmodule, exports) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * Determines if the given string is valid for a `"Name"` construct. + * + * @param name - name string to test + */ +function xml_isName(name) { + for (let i = 0; i < name.length; i++) { + let n = name.charCodeAt(i); + // NameStartChar + if ((n >= 97 && n <= 122) || // [a-z] + (n >= 65 && n <= 90) || // [A-Z] + n === 58 || n === 95 || // ':' or '_' + (n >= 0xC0 && n <= 0xD6) || + (n >= 0xD8 && n <= 0xF6) || + (n >= 0xF8 && n <= 0x2FF) || + (n >= 0x370 && n <= 0x37D) || + (n >= 0x37F && n <= 0x1FFF) || + (n >= 0x200C && n <= 0x200D) || + (n >= 0x2070 && n <= 0x218F) || + (n >= 0x2C00 && n <= 0x2FEF) || + (n >= 0x3001 && n <= 0xD7FF) || + (n >= 0xF900 && n <= 0xFDCF) || + (n >= 0xFDF0 && n <= 0xFFFD)) { + continue; + } + else if (i !== 0 && + (n === 45 || n === 46 || // '-' or '.' + (n >= 48 && n <= 57) || // [0-9] + (n === 0xB7) || + (n >= 0x0300 && n <= 0x036F) || + (n >= 0x203F && n <= 0x2040))) { + continue; + } + if (n >= 0xD800 && n <= 0xDBFF && i < name.length - 1) { + const n2 = name.charCodeAt(i + 1); + if (n2 >= 0xDC00 && n2 <= 0xDFFF) { + n = (n - 0xD800) * 0x400 + n2 - 0xDC00 + 0x10000; + i++; + if (n >= 0x10000 && n <= 0xEFFFF) { + continue; + } + } + } + return false; + } + return true; +} +exports.xml_isName = xml_isName; +/** + * Determines if the given string is valid for a `"QName"` construct. + * + * @param name - name string to test + */ +function xml_isQName(name) { + let colonFound = false; + for (let i = 0; i < name.length; i++) { + let n = name.charCodeAt(i); + // NameStartChar + if ((n >= 97 && n <= 122) || // [a-z] + (n >= 65 && n <= 90) || // [A-Z] + n === 95 || // '_' + (n >= 0xC0 && n <= 0xD6) || + (n >= 0xD8 && n <= 0xF6) || + (n >= 0xF8 && n <= 0x2FF) || + (n >= 0x370 && n <= 0x37D) || + (n >= 0x37F && n <= 0x1FFF) || + (n >= 0x200C && n <= 0x200D) || + (n >= 0x2070 && n <= 0x218F) || + (n >= 0x2C00 && n <= 0x2FEF) || + (n >= 0x3001 && n <= 0xD7FF) || + (n >= 0xF900 && n <= 0xFDCF) || + (n >= 0xFDF0 && n <= 0xFFFD)) { + continue; + } + else if (i !== 0 && + (n === 45 || n === 46 || // '-' or '.' + (n >= 48 && n <= 57) || // [0-9] + (n === 0xB7) || + (n >= 0x0300 && n <= 0x036F) || + (n >= 0x203F && n <= 0x2040))) { + continue; + } + else if (i !== 0 && n === 58) { // : + if (colonFound) + return false; // multiple colons in qname + if (i === name.length - 1) + return false; // colon at the end of qname + colonFound = true; + continue; + } + if (n >= 0xD800 && n <= 0xDBFF && i < name.length - 1) { + const n2 = name.charCodeAt(i + 1); + if (n2 >= 0xDC00 && n2 <= 0xDFFF) { + n = (n - 0xD800) * 0x400 + n2 - 0xDC00 + 0x10000; + i++; + if (n >= 0x10000 && n <= 0xEFFFF) { + continue; + } + } + } + return false; + } + return true; +} +exports.xml_isQName = xml_isQName; +/** + * Determines if the given string contains legal characters. + * + * @param chars - sequence of characters to test + */ +function xml_isLegalChar(chars) { + for (let i = 0; i < chars.length; i++) { + let n = chars.charCodeAt(i); + // #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF] + if (n === 0x9 || n === 0xA || n === 0xD || + (n >= 0x20 && n <= 0xD7FF) || + (n >= 0xE000 && n <= 0xFFFD)) { + continue; + } + if (n >= 0xD800 && n <= 0xDBFF && i < chars.length - 1) { + const n2 = chars.charCodeAt(i + 1); + if (n2 >= 0xDC00 && n2 <= 0xDFFF) { + n = (n - 0xD800) * 0x400 + n2 - 0xDC00 + 0x10000; + i++; + if (n >= 0x10000 && n <= 0x10FFFF) { + continue; + } + } + } + return false; + } + return true; +} +exports.xml_isLegalChar = xml_isLegalChar; +/** + * Determines if the given string contains legal characters for a public + * identifier. + * + * @param chars - sequence of characters to test + */ +function xml_isPubidChar(chars) { + for (let i = 0; i < chars.length; i++) { + // PubId chars are all in the ASCII range, no need to check surrogates + const n = chars.charCodeAt(i); + // #x20 | #xD | #xA | [a-zA-Z0-9] | [-'()+,./:=?;!*#@$_%] + if ((n >= 97 && n <= 122) || // [a-z] + (n >= 65 && n <= 90) || // [A-Z] + (n >= 39 && n <= 59) || // ['()*+,-./] | [0-9] | [:;] + n === 0x20 || n === 0xD || n === 0xA || // #x20 | #xD | #xA + (n >= 35 && n <= 37) || // [#$%] + n === 33 || // ! + n === 61 || n === 63 || n === 64 || n === 95) { // [=?@_] + continue; + } + else { + return false; + } + } + return true; +} +exports.xml_isPubidChar = xml_isPubidChar; +//# sourceMappingURL=XMLAlgorithm.js.map + +/***/ }), + +/***/ 457: +/***/ (function(__unusedmodule, exports) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * UTF-8 encodes the given string. + * + * @param input - a string + */ +function utf8Encode(input) { + const bytes = new Uint8Array(input.length * 4); + let byteIndex = 0; + for (let i = 0; i < input.length; i++) { + let char = input.charCodeAt(i); + if (char < 128) { + bytes[byteIndex++] = char; + continue; + } + else if (char < 2048) { + bytes[byteIndex++] = char >> 6 | 192; + } + else { + if (char > 0xd7ff && char < 0xdc00) { + if (++i >= input.length) { + throw new Error("Incomplete surrogate pair."); + } + const c2 = input.charCodeAt(i); + if (c2 < 0xdc00 || c2 > 0xdfff) { + throw new Error("Invalid surrogate character."); + } + char = 0x10000 + ((char & 0x03ff) << 10) + (c2 & 0x03ff); + bytes[byteIndex++] = char >> 18 | 240; + bytes[byteIndex++] = char >> 12 & 63 | 128; + } + else { + bytes[byteIndex++] = char >> 12 | 224; + } + bytes[byteIndex++] = char >> 6 & 63 | 128; + } + bytes[byteIndex++] = char & 63 | 128; + } + return bytes.subarray(0, byteIndex); +} +exports.utf8Encode = utf8Encode; +/** + * UTF-8 decodes the given byte sequence into a string. + * + * @param bytes - a byte sequence + */ +function utf8Decode(bytes) { + let result = ""; + let i = 0; + while (i < bytes.length) { + var c = bytes[i++]; + if (c > 127) { + if (c > 191 && c < 224) { + if (i >= bytes.length) { + throw new Error("Incomplete 2-byte sequence."); + } + c = (c & 31) << 6 | bytes[i++] & 63; + } + else if (c > 223 && c < 240) { + if (i + 1 >= bytes.length) { + throw new Error("Incomplete 3-byte sequence."); + } + c = (c & 15) << 12 | (bytes[i++] & 63) << 6 | bytes[i++] & 63; + } + else if (c > 239 && c < 248) { + if (i + 2 >= bytes.length) { + throw new Error("Incomplete 4-byte sequence."); + } + c = (c & 7) << 18 | (bytes[i++] & 63) << 12 | (bytes[i++] & 63) << 6 | bytes[i++] & 63; + } + else { + throw new Error("Unknown multi-byte start."); + } + } + if (c <= 0xffff) { + result += String.fromCharCode(c); + } + else if (c <= 0x10ffff) { + c -= 0x10000; + result += String.fromCharCode(c >> 10 | 0xd800); + result += String.fromCharCode(c & 0x3FF | 0xdc00); + } + else { + throw new Error("Code point exceeds UTF-16 limit."); + } + } + return result; +} +exports.utf8Decode = utf8Decode; +//# sourceMappingURL=index.js.map + +/***/ }), + +/***/ 462: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const interfaces_1 = __webpack_require__(970); +const LocalNameSet_1 = __webpack_require__(575); +const NamespacePrefixMap_1 = __webpack_require__(392); +const DOMException_1 = __webpack_require__(35); +const infra_1 = __webpack_require__(23); +const algorithm_1 = __webpack_require__(163); +/** + * Pre-serializes XML nodes. + */ +class BaseWriter { + /** + * Initializes a new instance of `BaseWriter`. + * + * @param builderOptions - XML builder options + */ + constructor(builderOptions) { + /** + * Gets the current depth of the XML tree. + */ + this.level = 0; + this._builderOptions = builderOptions; + } + /** + * Used by derived classes to serialize a DocType node. + * + * @param name - node name + * @param publicId - public identifier + * @param systemId - system identifier + */ + docType(name, publicId, systemId) { } + /** + * Used by derived classes to serialize a comment node. + * + * @param data - node data + */ + comment(data) { } + /** + * Used by derived classes to serialize a text node. + * + * @param data - node data + */ + text(data) { } + /** + * Used by derived classes to serialize a processing instruction node. + * + * @param target - instruction target + * @param data - node data + */ + instruction(target, data) { } + /** + * Used by derived classes to serialize a CData section node. + * + * @param data - node data + */ + cdata(data) { } + /** + * Used by derived classes to serialize the beginning of the opening tag of an + * element node. + * + * @param name - node name + */ + openTagBegin(name) { } + /** + * Used by derived classes to serialize the ending of the opening tag of an + * element node. + * + * @param name - node name + * @param selfClosing - whether the element node is self closing + * @param voidElement - whether the element node is a HTML void element + */ + openTagEnd(name, selfClosing, voidElement) { } + /** + * Used by derived classes to serialize the closing tag of an element node. + * + * @param name - node name + */ + closeTag(name) { } + /** + * Used by derived classes to serialize attributes or namespace declarations. + * + * @param attributes - attribute array + */ + attributes(attributes) { + for (const attr of attributes) { + this.attribute(attr[1] === null ? attr[2] : attr[1] + ':' + attr[2], attr[3]); + } + } + /** + * Used by derived classes to serialize an attribute or namespace declaration. + * + * @param name - node name + * @param value - node value + */ + attribute(name, value) { } + /** + * Used by derived classes to perform any pre-processing steps before starting + * serializing an element node. + * + * @param name - node name + */ + beginElement(name) { } + /** + * Used by derived classes to perform any post-processing steps after + * completing serializing an element node. + * + * @param name - node name + */ + endElement(name) { } + /** + * Produces an XML serialization of the given node. The pre-serializer inserts + * namespace declarations where necessary and produces qualified names for + * nodes and attributes. + * + * @param node - node to serialize + * @param requireWellFormed - whether to check conformance + */ + serializeNode(node, requireWellFormed, noDoubleEncoding) { + const hasNamespaces = (node._nodeDocument !== undefined && node._nodeDocument._hasNamespaces); + this.level = 0; + this.currentNode = node; + if (hasNamespaces) { + /** From: https://w3c.github.io/DOM-Parsing/#xml-serialization + * + * 1. Let namespace be a context namespace with value null. + * The context namespace tracks the XML serialization algorithm's current + * default namespace. The context namespace is changed when either an Element + * Node has a default namespace declaration, or the algorithm generates a + * default namespace declaration for the Element Node to match its own + * namespace. The algorithm assumes no namespace (null) to start. + * 2. Let prefix map be a new namespace prefix map. + * 3. Add the XML namespace with prefix value "xml" to prefix map. + * 4. Let prefix index be a generated namespace prefix index with value 1. + * The generated namespace prefix index is used to generate a new unique + * prefix value when no suitable existing namespace prefix is available to + * serialize a node's namespaceURI (or the namespaceURI of one of node's + * attributes). See the generate a prefix algorithm. + */ + let namespace = null; + const prefixMap = new NamespacePrefixMap_1.NamespacePrefixMap(); + prefixMap.set("xml", infra_1.namespace.XML); + const prefixIndex = { value: 1 }; + /** + * 5. Return the result of running the XML serialization algorithm on node + * passing the context namespace namespace, namespace prefix map prefix map, + * generated namespace prefix index reference to prefix index, and the + * flag require well-formed. If an exception occurs during the execution + * of the algorithm, then catch that exception and throw an + * "InvalidStateError" DOMException. + */ + try { + this._serializeNodeNS(node, namespace, prefixMap, prefixIndex, requireWellFormed, noDoubleEncoding); + } + catch (e) { + throw new DOMException_1.InvalidStateError(e.message); + } + } + else { + try { + this._serializeNode(node, requireWellFormed, noDoubleEncoding); + } + catch (e) { + throw new DOMException_1.InvalidStateError(e.message); + } + } + } + /** + * Produces an XML serialization of a node. + * + * @param node - node to serialize + * @param namespace - context namespace + * @param prefixMap - namespace prefix map + * @param prefixIndex - generated namespace prefix index + * @param requireWellFormed - whether to check conformance + */ + _serializeNodeNS(node, namespace, prefixMap, prefixIndex, requireWellFormed, noDoubleEncoding) { + this.currentNode = node; + switch (node.nodeType) { + case interfaces_1.NodeType.Element: + this._serializeElementNS(node, namespace, prefixMap, prefixIndex, requireWellFormed, noDoubleEncoding); + break; + case interfaces_1.NodeType.Document: + this._serializeDocumentNS(node, namespace, prefixMap, prefixIndex, requireWellFormed, noDoubleEncoding); + break; + case interfaces_1.NodeType.Comment: + this._serializeComment(node, requireWellFormed, noDoubleEncoding); + break; + case interfaces_1.NodeType.Text: + this._serializeText(node, requireWellFormed, noDoubleEncoding); + break; + case interfaces_1.NodeType.DocumentFragment: + this._serializeDocumentFragmentNS(node, namespace, prefixMap, prefixIndex, requireWellFormed, noDoubleEncoding); + break; + case interfaces_1.NodeType.DocumentType: + this._serializeDocumentType(node, requireWellFormed, noDoubleEncoding); + break; + case interfaces_1.NodeType.ProcessingInstruction: + this._serializeProcessingInstruction(node, requireWellFormed, noDoubleEncoding); + break; + case interfaces_1.NodeType.CData: + this._serializeCData(node, requireWellFormed, noDoubleEncoding); + break; + default: + throw new Error(`Unknown node type: ${node.nodeType}`); + } + } + /** + * Produces an XML serialization of a node. + * + * @param node - node to serialize + * @param requireWellFormed - whether to check conformance + */ + _serializeNode(node, requireWellFormed, noDoubleEncoding) { + this.currentNode = node; + switch (node.nodeType) { + case interfaces_1.NodeType.Element: + this._serializeElement(node, requireWellFormed, noDoubleEncoding); + break; + case interfaces_1.NodeType.Document: + this._serializeDocument(node, requireWellFormed, noDoubleEncoding); + break; + case interfaces_1.NodeType.Comment: + this._serializeComment(node, requireWellFormed, noDoubleEncoding); + break; + case interfaces_1.NodeType.Text: + this._serializeText(node, requireWellFormed, noDoubleEncoding); + break; + case interfaces_1.NodeType.DocumentFragment: + this._serializeDocumentFragment(node, requireWellFormed, noDoubleEncoding); + break; + case interfaces_1.NodeType.DocumentType: + this._serializeDocumentType(node, requireWellFormed, noDoubleEncoding); + break; + case interfaces_1.NodeType.ProcessingInstruction: + this._serializeProcessingInstruction(node, requireWellFormed, noDoubleEncoding); + break; + case interfaces_1.NodeType.CData: + this._serializeCData(node, requireWellFormed, noDoubleEncoding); + break; + default: + throw new Error(`Unknown node type: ${node.nodeType}`); + } + } + /** + * Produces an XML serialization of an element node. + * + * @param node - node to serialize + * @param namespace - context namespace + * @param prefixMap - namespace prefix map + * @param prefixIndex - generated namespace prefix index + * @param requireWellFormed - whether to check conformance + */ + _serializeElementNS(node, namespace, prefixMap, prefixIndex, requireWellFormed, noDoubleEncoding) { + const attributes = []; + /** + * From: https://w3c.github.io/DOM-Parsing/#xml-serializing-an-element-node + * + * 1. If the require well-formed flag is set (its value is true), and this + * node's localName attribute contains the character ":" (U+003A COLON) or + * does not match the XML Name production, then throw an exception; the + * serialization of this node would not be a well-formed element. + */ + if (requireWellFormed && (node.localName.indexOf(":") !== -1 || + !algorithm_1.xml_isName(node.localName))) { + throw new Error("Node local name contains invalid characters (well-formed required)."); + } + /** + * 2. Let markup be the string "<" (U+003C LESS-THAN SIGN). + * 3. Let qualified name be an empty string. + * 4. Let skip end tag be a boolean flag with value false. + * 5. Let ignore namespace definition attribute be a boolean flag with value + * false. + * 6. Given prefix map, copy a namespace prefix map and let map be the + * result. + * 7. Let local prefixes map be an empty map. The map has unique Node prefix + * strings as its keys, with corresponding namespaceURI Node values as the + * map's key values (in this map, the null namespace is represented by the + * empty string). + * + * _Note:_ This map is local to each element. It is used to ensure there + * are no conflicting prefixes should a new namespace prefix attribute need + * to be generated. It is also used to enable skipping of duplicate prefix + * definitions when writing an element's attributes: the map allows the + * algorithm to distinguish between a prefix in the namespace prefix map + * that might be locally-defined (to the current Element) and one that is + * not. + * 8. Let local default namespace be the result of recording the namespace + * information for node given map and local prefixes map. + * + * _Note:_ The above step will update map with any found namespace prefix + * definitions, add the found prefix definitions to the local prefixes map + * and return a local default namespace value defined by a default namespace + * attribute if one exists. Otherwise it returns null. + * 9. Let inherited ns be a copy of namespace. + * 10. Let ns be the value of node's namespaceURI attribute. + */ + let qualifiedName = ''; + let skipEndTag = false; + let ignoreNamespaceDefinitionAttribute = false; + let map = prefixMap.copy(); + let localPrefixesMap = {}; + let localDefaultNamespace = this._recordNamespaceInformation(node, map, localPrefixesMap); + let inheritedNS = namespace; + let ns = node.namespaceURI; + /** 11. If inherited ns is equal to ns, then: */ + if (inheritedNS === ns) { + /** + * 11.1. If local default namespace is not null, then set ignore + * namespace definition attribute to true. + */ + if (localDefaultNamespace !== null) { + ignoreNamespaceDefinitionAttribute = true; + } + /** + * 11.2. If ns is the XML namespace, then append to qualified name the + * concatenation of the string "xml:" and the value of node's localName. + * 11.3. Otherwise, append to qualified name the value of node's + * localName. The node's prefix if it exists, is dropped. + */ + if (ns === infra_1.namespace.XML) { + qualifiedName = 'xml:' + node.localName; + } + else { + qualifiedName = node.localName; + } + /** 11.4. Append the value of qualified name to markup. */ + this.beginElement(qualifiedName); + this.openTagBegin(qualifiedName); + } + else { + /** + * 12. Otherwise, inherited ns is not equal to ns (the node's own + * namespace is different from the context namespace of its parent). + * Run these sub-steps: + * + * 12.1. Let prefix be the value of node's prefix attribute. + * 12.2. Let candidate prefix be the result of retrieving a preferred + * prefix string prefix from map given namespace ns. The above may return + * null if no namespace key ns exists in map. + */ + let prefix = node.prefix; + /** + * We don't need to run "retrieving a preferred prefix string" algorithm if + * the element has no prefix and its namespace matches to the default + * namespace. + * See: https://github.com/web-platform-tests/wpt/pull/16703 + */ + let candidatePrefix = null; + if (prefix !== null || ns !== localDefaultNamespace) { + candidatePrefix = map.get(prefix, ns); + } + /** + * 12.3. If the value of prefix matches "xmlns", then run the following + * steps: + */ + if (prefix === "xmlns") { + /** + * 12.3.1. If the require well-formed flag is set, then throw an error. + * An Element with prefix "xmlns" will not legally round-trip in a + * conforming XML parser. + */ + if (requireWellFormed) { + throw new Error("An element cannot have the 'xmlns' prefix (well-formed required)."); + } + /** + * 12.3.2. Let candidate prefix be the value of prefix. + */ + candidatePrefix = prefix; + } + /** + * 12.4.Found a suitable namespace prefix: if candidate prefix is not + * null (a namespace prefix is defined which maps to ns), then: + */ + if (candidatePrefix !== null) { + /** + * The following may serialize a different prefix than the Element's + * existing prefix if it already had one. However, the retrieving a + * preferred prefix string algorithm already tried to match the + * existing prefix if possible. + * + * 12.4.1. Append to qualified name the concatenation of candidate + * prefix, ":" (U+003A COLON), and node's localName. There exists on + * this node or the node's ancestry a namespace prefix definition that + * defines the node's namespace. + * 12.4.2. If the local default namespace is not null (there exists a + * locally-defined default namespace declaration attribute) and its + * value is not the XML namespace, then let inherited ns get the value + * of local default namespace unless the local default namespace is the + * empty string in which case let it get null (the context namespace + * is changed to the declared default, rather than this node's own + * namespace). + * + * _Note:_ Any default namespace definitions or namespace prefixes that + * define the XML namespace are omitted when serializing this node's + * attributes. + */ + qualifiedName = candidatePrefix + ':' + node.localName; + if (localDefaultNamespace !== null && localDefaultNamespace !== infra_1.namespace.XML) { + inheritedNS = localDefaultNamespace || null; + } + /** + * 12.4.3. Append the value of qualified name to markup. + */ + this.beginElement(qualifiedName); + this.openTagBegin(qualifiedName); + /** 12.5. Otherwise, if prefix is not null, then: */ + } + else if (prefix !== null) { + /** + * _Note:_ By this step, there is no namespace or prefix mapping + * declaration in this node (or any parent node visited by this + * algorithm) that defines prefix otherwise the step labelled Found + * a suitable namespace prefix would have been followed. The sub-steps + * that follow will create a new namespace prefix declaration for prefix + * and ensure that prefix does not conflict with an existing namespace + * prefix declaration of the same localName in node's attribute list. + * + * 12.5.1. If the local prefixes map contains a key matching prefix, + * then let prefix be the result of generating a prefix providing as + * input map, ns, and prefix index. + */ + if (prefix in localPrefixesMap) { + prefix = this._generatePrefix(ns, map, prefixIndex); + } + /** + * 12.5.2. Add prefix to map given namespace ns. + * 12.5.3. Append to qualified name the concatenation of prefix, ":" + * (U+003A COLON), and node's localName. + * 12.5.4. Append the value of qualified name to markup. + */ + map.set(prefix, ns); + qualifiedName += prefix + ':' + node.localName; + this.beginElement(qualifiedName); + this.openTagBegin(qualifiedName); + /** + * 12.5.5. Append the following to markup, in the order listed: + * + * _Note:_ The following serializes a namespace prefix declaration for + * prefix which was just added to the map. + * + * 12.5.5.1. " " (U+0020 SPACE); + * 12.5.5.2. The string "xmlns:"; + * 12.5.5.3. The value of prefix; + * 12.5.5.4. "="" (U+003D EQUALS SIGN, U+0022 QUOTATION MARK); + * 12.5.5.5. The result of serializing an attribute value given ns and + * the require well-formed flag as input; + * 12.5.5.6. """ (U+0022 QUOTATION MARK). + */ + attributes.push([null, 'xmlns', prefix, + this._serializeAttributeValue(ns, requireWellFormed, noDoubleEncoding)]); + /** + * 12.5.5.7. If local default namespace is not null (there exists a + * locally-defined default namespace declaration attribute), then + * let inherited ns get the value of local default namespace unless the + * local default namespace is the empty string in which case let it get + * null. + */ + if (localDefaultNamespace !== null) { + inheritedNS = localDefaultNamespace || null; + } + /** + * 12.6. Otherwise, if local default namespace is null, or local + * default namespace is not null and its value is not equal to ns, then: + */ + } + else if (localDefaultNamespace === null || + (localDefaultNamespace !== null && localDefaultNamespace !== ns)) { + /** + * _Note:_ At this point, the namespace for this node still needs to be + * serialized, but there's no prefix (or candidate prefix) available; the + * following uses the default namespace declaration to define the + * namespace--optionally replacing an existing default declaration + * if present. + * + * 12.6.1. Set the ignore namespace definition attribute flag to true. + * 12.6.2. Append to qualified name the value of node's localName. + * 12.6.3. Let the value of inherited ns be ns. + * + * _Note:_ The new default namespace will be used in the serialization + * to define this node's namespace and act as the context namespace for + * its children. + */ + ignoreNamespaceDefinitionAttribute = true; + qualifiedName += node.localName; + inheritedNS = ns; + /** + * 12.6.4. Append the value of qualified name to markup. + */ + this.beginElement(qualifiedName); + this.openTagBegin(qualifiedName); + /** + * 12.6.5. Append the following to markup, in the order listed: + * + * _Note:_ The following serializes the new (or replacement) default + * namespace definition. + * + * 12.6.5.1. " " (U+0020 SPACE); + * 12.6.5.2. The string "xmlns"; + * 12.6.5.3. "="" (U+003D EQUALS SIGN, U+0022 QUOTATION MARK); + * 12.6.5.4. The result of serializing an attribute value given ns + * and the require well-formed flag as input; + * 12.6.5.5. """ (U+0022 QUOTATION MARK). + */ + attributes.push([null, null, 'xmlns', + this._serializeAttributeValue(ns, requireWellFormed, noDoubleEncoding)]); + /** + * 12.7. Otherwise, the node has a local default namespace that matches + * ns. Append to qualified name the value of node's localName, let the + * value of inherited ns be ns, and append the value of qualified name + * to markup. + */ + } + else { + qualifiedName += node.localName; + inheritedNS = ns; + this.beginElement(qualifiedName); + this.openTagBegin(qualifiedName); + } + } + /** + * 13. Append to markup the result of the XML serialization of node's + * attributes given map, prefix index, local prefixes map, ignore namespace + * definition attribute flag, and require well-formed flag. + */ + attributes.push(...this._serializeAttributesNS(node, map, prefixIndex, localPrefixesMap, ignoreNamespaceDefinitionAttribute, requireWellFormed, noDoubleEncoding)); + this.attributes(attributes); + /** + * 14. If ns is the HTML namespace, and the node's list of children is + * empty, and the node's localName matches any one of the following void + * elements: "area", "base", "basefont", "bgsound", "br", "col", "embed", + * "frame", "hr", "img", "input", "keygen", "link", "menuitem", "meta", + * "param", "source", "track", "wbr"; then append the following to markup, + * in the order listed: + * 14.1. " " (U+0020 SPACE); + * 14.2. "/" (U+002F SOLIDUS). + * and set the skip end tag flag to true. + * 15. If ns is not the HTML namespace, and the node's list of children is + * empty, then append "/" (U+002F SOLIDUS) to markup and set the skip end + * tag flag to true. + * 16. Append ">" (U+003E GREATER-THAN SIGN) to markup. + */ + const isHTML = (ns === infra_1.namespace.HTML); + if (isHTML && node.childNodes.length === 0 && + BaseWriter._VoidElementNames.has(node.localName)) { + this.openTagEnd(qualifiedName, true, true); + this.endElement(qualifiedName); + skipEndTag = true; + } + else if (!isHTML && node.childNodes.length === 0) { + this.openTagEnd(qualifiedName, true, false); + this.endElement(qualifiedName); + skipEndTag = true; + } + else { + this.openTagEnd(qualifiedName, false, false); + } + /** + * 17. If the value of skip end tag is true, then return the value of markup + * and skip the remaining steps. The node is a leaf-node. + */ + if (skipEndTag) + return; + /** + * 18. If ns is the HTML namespace, and the node's localName matches the + * string "template", then this is a template element. Append to markup the + * result of XML serializing a DocumentFragment node given the template + * element's template contents (a DocumentFragment), providing inherited + * ns, map, prefix index, and the require well-formed flag. + * + * _Note:_ This allows template content to round-trip, given the rules for + * parsing XHTML documents. + * + * 19. Otherwise, append to markup the result of running the XML + * serialization algorithm on each of node's children, in tree order, + * providing inherited ns, map, prefix index, and the require well-formed + * flag. + */ + if (isHTML && node.localName === "template") { + // TODO: serialize template contents + } + else { + for (const childNode of node.childNodes) { + this.level++; + this._serializeNodeNS(childNode, inheritedNS, map, prefixIndex, requireWellFormed, noDoubleEncoding); + this.level--; + } + } + /** + * 20. Append the following to markup, in the order listed: + * 20.1. "" (U+003E GREATER-THAN SIGN). + * 21. Return the value of markup. + */ + this.closeTag(qualifiedName); + this.endElement(qualifiedName); + } + /** + * Produces an XML serialization of an element node. + * + * @param node - node to serialize + * @param requireWellFormed - whether to check conformance + */ + _serializeElement(node, requireWellFormed, noDoubleEncoding) { + /** + * From: https://w3c.github.io/DOM-Parsing/#xml-serializing-an-element-node + * + * 1. If the require well-formed flag is set (its value is true), and this + * node's localName attribute contains the character ":" (U+003A COLON) or + * does not match the XML Name production, then throw an exception; the + * serialization of this node would not be a well-formed element. + */ + if (requireWellFormed && (node.localName.indexOf(":") !== -1 || + !algorithm_1.xml_isName(node.localName))) { + throw new Error("Node local name contains invalid characters (well-formed required)."); + } + /** + * 2. Let markup be the string "<" (U+003C LESS-THAN SIGN). + * 3. Let qualified name be an empty string. + * 4. Let skip end tag be a boolean flag with value false. + * 5. Let ignore namespace definition attribute be a boolean flag with value + * false. + * 6. Given prefix map, copy a namespace prefix map and let map be the + * result. + * 7. Let local prefixes map be an empty map. The map has unique Node prefix + * strings as its keys, with corresponding namespaceURI Node values as the + * map's key values (in this map, the null namespace is represented by the + * empty string). + * + * _Note:_ This map is local to each element. It is used to ensure there + * are no conflicting prefixes should a new namespace prefix attribute need + * to be generated. It is also used to enable skipping of duplicate prefix + * definitions when writing an element's attributes: the map allows the + * algorithm to distinguish between a prefix in the namespace prefix map + * that might be locally-defined (to the current Element) and one that is + * not. + * 8. Let local default namespace be the result of recording the namespace + * information for node given map and local prefixes map. + * + * _Note:_ The above step will update map with any found namespace prefix + * definitions, add the found prefix definitions to the local prefixes map + * and return a local default namespace value defined by a default namespace + * attribute if one exists. Otherwise it returns null. + * 9. Let inherited ns be a copy of namespace. + * 10. Let ns be the value of node's namespaceURI attribute. + */ + let skipEndTag = false; + /** 11. If inherited ns is equal to ns, then: */ + /** + * 11.1. If local default namespace is not null, then set ignore + * namespace definition attribute to true. + */ + /** + * 11.2. If ns is the XML namespace, then append to qualified name the + * concatenation of the string "xml:" and the value of node's localName. + * 11.3. Otherwise, append to qualified name the value of node's + * localName. The node's prefix if it exists, is dropped. + */ + const qualifiedName = node.localName; + /** 11.4. Append the value of qualified name to markup. */ + this.beginElement(qualifiedName); + this.openTagBegin(qualifiedName); + /** + * 13. Append to markup the result of the XML serialization of node's + * attributes given map, prefix index, local prefixes map, ignore namespace + * definition attribute flag, and require well-formed flag. + */ + const attributes = this._serializeAttributes(node, requireWellFormed, noDoubleEncoding); + this.attributes(attributes); + /** + * 14. If ns is the HTML namespace, and the node's list of children is + * empty, and the node's localName matches any one of the following void + * elements: "area", "base", "basefont", "bgsound", "br", "col", "embed", + * "frame", "hr", "img", "input", "keygen", "link", "menuitem", "meta", + * "param", "source", "track", "wbr"; then append the following to markup, + * in the order listed: + * 14.1. " " (U+0020 SPACE); + * 14.2. "/" (U+002F SOLIDUS). + * and set the skip end tag flag to true. + * 15. If ns is not the HTML namespace, and the node's list of children is + * empty, then append "/" (U+002F SOLIDUS) to markup and set the skip end + * tag flag to true. + * 16. Append ">" (U+003E GREATER-THAN SIGN) to markup. + */ + if (!node.hasChildNodes()) { + this.openTagEnd(qualifiedName, true, false); + this.endElement(qualifiedName); + skipEndTag = true; + } + else { + this.openTagEnd(qualifiedName, false, false); + } + /** + * 17. If the value of skip end tag is true, then return the value of markup + * and skip the remaining steps. The node is a leaf-node. + */ + if (skipEndTag) + return; + /** + * 18. If ns is the HTML namespace, and the node's localName matches the + * string "template", then this is a template element. Append to markup the + * result of XML serializing a DocumentFragment node given the template + * element's template contents (a DocumentFragment), providing inherited + * ns, map, prefix index, and the require well-formed flag. + * + * _Note:_ This allows template content to round-trip, given the rules for + * parsing XHTML documents. + * + * 19. Otherwise, append to markup the result of running the XML + * serialization algorithm on each of node's children, in tree order, + * providing inherited ns, map, prefix index, and the require well-formed + * flag. + */ + for (const childNode of node._children) { + this.level++; + this._serializeNode(childNode, requireWellFormed, noDoubleEncoding); + this.level--; + } + /** + * 20. Append the following to markup, in the order listed: + * 20.1. "" (U+003E GREATER-THAN SIGN). + * 21. Return the value of markup. + */ + this.closeTag(qualifiedName); + this.endElement(qualifiedName); + } + /** + * Produces an XML serialization of a document node. + * + * @param node - node to serialize + * @param namespace - context namespace + * @param prefixMap - namespace prefix map + * @param prefixIndex - generated namespace prefix index + * @param requireWellFormed - whether to check conformance + */ + _serializeDocumentNS(node, namespace, prefixMap, prefixIndex, requireWellFormed, noDoubleEncoding) { + /** + * If the require well-formed flag is set (its value is true), and this node + * has no documentElement (the documentElement attribute's value is null), + * then throw an exception; the serialization of this node would not be a + * well-formed document. + */ + if (requireWellFormed && node.documentElement === null) { + throw new Error("Missing document element (well-formed required)."); + } + /** + * Otherwise, run the following steps: + * 1. Let serialized document be an empty string. + * 2. For each child child of node, in tree order, run the XML + * serialization algorithm on the child passing along the provided + * arguments, and append the result to serialized document. + * + * _Note:_ This will serialize any number of ProcessingInstruction and + * Comment nodes both before and after the Document's documentElement node, + * including at most one DocumentType node. (Text nodes are not allowed as + * children of the Document.) + * + * 3. Return the value of serialized document. + */ + for (const childNode of node.childNodes) { + this._serializeNodeNS(childNode, namespace, prefixMap, prefixIndex, requireWellFormed, noDoubleEncoding); + } + } + /** + * Produces an XML serialization of a document node. + * + * @param node - node to serialize + * @param requireWellFormed - whether to check conformance + */ + _serializeDocument(node, requireWellFormed, noDoubleEncoding) { + /** + * If the require well-formed flag is set (its value is true), and this node + * has no documentElement (the documentElement attribute's value is null), + * then throw an exception; the serialization of this node would not be a + * well-formed document. + */ + if (requireWellFormed && node.documentElement === null) { + throw new Error("Missing document element (well-formed required)."); + } + /** + * Otherwise, run the following steps: + * 1. Let serialized document be an empty string. + * 2. For each child child of node, in tree order, run the XML + * serialization algorithm on the child passing along the provided + * arguments, and append the result to serialized document. + * + * _Note:_ This will serialize any number of ProcessingInstruction and + * Comment nodes both before and after the Document's documentElement node, + * including at most one DocumentType node. (Text nodes are not allowed as + * children of the Document.) + * + * 3. Return the value of serialized document. + */ + for (const childNode of node._children) { + this._serializeNode(childNode, requireWellFormed, noDoubleEncoding); + } + } + /** + * Produces an XML serialization of a comment node. + * + * @param node - node to serialize + * @param requireWellFormed - whether to check conformance + */ + _serializeComment(node, requireWellFormed, noDoubleEncoding) { + /** + * If the require well-formed flag is set (its value is true), and node's + * data contains characters that are not matched by the XML Char production + * or contains "--" (two adjacent U+002D HYPHEN-MINUS characters) or that + * ends with a "-" (U+002D HYPHEN-MINUS) character, then throw an exception; + * the serialization of this node's data would not be well-formed. + */ + if (requireWellFormed && (!algorithm_1.xml_isLegalChar(node.data) || + node.data.indexOf("--") !== -1 || node.data.endsWith("-"))) { + throw new Error("Comment data contains invalid characters (well-formed required)."); + } + /** + * Otherwise, return the concatenation of "". + */ + this.comment(node.data); + } + /** + * Produces an XML serialization of a text node. + * + * @param node - node to serialize + * @param requireWellFormed - whether to check conformance + * @param level - current depth of the XML tree + */ + _serializeText(node, requireWellFormed, noDoubleEncoding) { + /** + * 1. If the require well-formed flag is set (its value is true), and + * node's data contains characters that are not matched by the XML Char + * production, then throw an exception; the serialization of this node's + * data would not be well-formed. + */ + if (requireWellFormed && !algorithm_1.xml_isLegalChar(node.data)) { + throw new Error("Text data contains invalid characters (well-formed required)."); + } + /** + * 2. Let markup be the value of node's data. + * 3. Replace any occurrences of "&" in markup by "&". + * 4. Replace any occurrences of "<" in markup by "<". + * 5. Replace any occurrences of ">" in markup by ">". + * 6. Return the value of markup. + */ + let markup = ""; + if (noDoubleEncoding) { + markup = node.data.replace(/(?!&(lt|gt|amp|apos|quot);)&/g, '&') + .replace(//g, '>') + .replace(/\r/g, ' '); + } + else { + for (let i = 0; i < node.data.length; i++) { + const c = node.data[i]; + if (c === "&") + markup += "&"; + else if (c === "<") + markup += "<"; + else if (c === ">") + markup += ">"; + else + markup += c; + } + } + this.text(markup); + } + /** + * Produces an XML serialization of a document fragment node. + * + * @param node - node to serialize + * @param namespace - context namespace + * @param prefixMap - namespace prefix map + * @param prefixIndex - generated namespace prefix index + * @param requireWellFormed - whether to check conformance + */ + _serializeDocumentFragmentNS(node, namespace, prefixMap, prefixIndex, requireWellFormed, noDoubleEncoding) { + /** + * 1. Let markup the empty string. + * 2. For each child child of node, in tree order, run the XML serialization + * algorithm on the child given namespace, prefix map, a reference to prefix + * index, and flag require well-formed. Concatenate the result to markup. + * 3. Return the value of markup. + */ + for (const childNode of node.childNodes) { + this._serializeNodeNS(childNode, namespace, prefixMap, prefixIndex, requireWellFormed, noDoubleEncoding); + } + } + /** + * Produces an XML serialization of a document fragment node. + * + * @param node - node to serialize + * @param requireWellFormed - whether to check conformance + */ + _serializeDocumentFragment(node, requireWellFormed, noDoubleEncoding) { + /** + * 1. Let markup the empty string. + * 2. For each child child of node, in tree order, run the XML serialization + * algorithm on the child given namespace, prefix map, a reference to prefix + * index, and flag require well-formed. Concatenate the result to markup. + * 3. Return the value of markup. + */ + for (const childNode of node._children) { + this._serializeNode(childNode, requireWellFormed, noDoubleEncoding); + } + } + /** + * Produces an XML serialization of a document type node. + * + * @param node - node to serialize + * @param requireWellFormed - whether to check conformance + */ + _serializeDocumentType(node, requireWellFormed, noDoubleEncoding) { + /** + * 1. If the require well-formed flag is true and the node's publicId + * attribute contains characters that are not matched by the XML PubidChar + * production, then throw an exception; the serialization of this node + * would not be a well-formed document type declaration. + */ + if (requireWellFormed && !algorithm_1.xml_isPubidChar(node.publicId)) { + throw new Error("DocType public identifier does not match PubidChar construct (well-formed required)."); + } + /** + * 2. If the require well-formed flag is true and the node's systemId + * attribute contains characters that are not matched by the XML Char + * production or that contains both a """ (U+0022 QUOTATION MARK) and a + * "'" (U+0027 APOSTROPHE), then throw an exception; the serialization + * of this node would not be a well-formed document type declaration. + */ + if (requireWellFormed && + (!algorithm_1.xml_isLegalChar(node.systemId) || + (node.systemId.indexOf('"') !== -1 && node.systemId.indexOf("'") !== -1))) { + throw new Error("DocType system identifier contains invalid characters (well-formed required)."); + } + /** + * 3. Let markup be an empty string. + * 4. Append the string "" (U+003E GREATER-THAN SIGN) to markup. + * 11. Return the value of markup. + */ + this.docType(node.name, node.publicId, node.systemId); + } + /** + * Produces an XML serialization of a processing instruction node. + * + * @param node - node to serialize + * @param requireWellFormed - whether to check conformance + */ + _serializeProcessingInstruction(node, requireWellFormed, noDoubleEncoding) { + /** + * 1. If the require well-formed flag is set (its value is true), and node's + * target contains a ":" (U+003A COLON) character or is an ASCII + * case-insensitive match for the string "xml", then throw an exception; + * the serialization of this node's target would not be well-formed. + */ + if (requireWellFormed && (node.target.indexOf(":") !== -1 || (/^xml$/i).test(node.target))) { + throw new Error("Processing instruction target contains invalid characters (well-formed required)."); + } + /** + * 2. If the require well-formed flag is set (its value is true), and node's + * data contains characters that are not matched by the XML Char production + * or contains the string "?>" (U+003F QUESTION MARK, + * U+003E GREATER-THAN SIGN), then throw an exception; the serialization of + * this node's data would not be well-formed. + */ + if (requireWellFormed && (!algorithm_1.xml_isLegalChar(node.data) || + node.data.indexOf("?>") !== -1)) { + throw new Error("Processing instruction data contains invalid characters (well-formed required)."); + } + /** + * 3. Let markup be the concatenation of the following, in the order listed: + * 3.1. "" (U+003F QUESTION MARK, U+003E GREATER-THAN SIGN). + * 4. Return the value of markup. + */ + this.instruction(node.target, node.data); + } + /** + * Produces an XML serialization of a CDATA node. + * + * @param node - node to serialize + * @param requireWellFormed - whether to check conformance + */ + _serializeCData(node, requireWellFormed, noDoubleEncoding) { + if (requireWellFormed && (node.data.indexOf("]]>") !== -1)) { + throw new Error("CDATA contains invalid characters (well-formed required)."); + } + this.cdata(node.data); + } + /** + * Produces an XML serialization of the attributes of an element node. + * + * @param node - node to serialize + * @param map - namespace prefix map + * @param prefixIndex - generated namespace prefix index + * @param localPrefixesMap - local prefixes map + * @param ignoreNamespaceDefinitionAttribute - whether to ignore namespace + * attributes + * @param requireWellFormed - whether to check conformance + */ + _serializeAttributesNS(node, map, prefixIndex, localPrefixesMap, ignoreNamespaceDefinitionAttribute, requireWellFormed, noDoubleEncoding) { + /** + * 1. Let result be the empty string. + * 2. Let localname set be a new empty namespace localname set. This + * localname set will contain tuples of unique attribute namespaceURI and + * localName pairs, and is populated as each attr is processed. This set is + * used to [optionally] enforce the well-formed constraint that an element + * cannot have two attributes with the same namespaceURI and localName. + * This can occur when two otherwise identical attributes on the same + * element differ only by their prefix values. + */ + const result = []; + const localNameSet = requireWellFormed ? new LocalNameSet_1.LocalNameSet() : undefined; + /** + * 3. Loop: For each attribute attr in element's attributes, in the order + * they are specified in the element's attribute list: + */ + for (const attr of node.attributes) { + // Optimize common case + if (!requireWellFormed && !ignoreNamespaceDefinitionAttribute && attr.namespaceURI === null) { + result.push([null, null, attr.localName, + this._serializeAttributeValue(attr.value, requireWellFormed, noDoubleEncoding)]); + continue; + } + /** + * 3.1. If the require well-formed flag is set (its value is true), and the + * localname set contains a tuple whose values match those of a new tuple + * consisting of attr's namespaceURI attribute and localName attribute, + * then throw an exception; the serialization of this attr would fail to + * produce a well-formed element serialization. + */ + if (requireWellFormed && localNameSet && localNameSet.has(attr.namespaceURI, attr.localName)) { + throw new Error("Element contains duplicate attributes (well-formed required)."); + } + /** + * 3.2. Create a new tuple consisting of attr's namespaceURI attribute and + * localName attribute, and add it to the localname set. + * 3.3. Let attribute namespace be the value of attr's namespaceURI value. + * 3.4. Let candidate prefix be null. + */ + if (requireWellFormed && localNameSet) + localNameSet.set(attr.namespaceURI, attr.localName); + let attributeNamespace = attr.namespaceURI; + let candidatePrefix = null; + /** 3.5. If attribute namespace is not null, then run these sub-steps: */ + if (attributeNamespace !== null) { + /** + * 3.5.1. Let candidate prefix be the result of retrieving a preferred + * prefix string from map given namespace attribute namespace with + * preferred prefix being attr's prefix value. + */ + candidatePrefix = map.get(attr.prefix, attributeNamespace); + /** + * 3.5.2. If the value of attribute namespace is the XMLNS namespace, + * then run these steps: + */ + if (attributeNamespace === infra_1.namespace.XMLNS) { + /** + * 3.5.2.1. If any of the following are true, then stop running these + * steps and goto Loop to visit the next attribute: + * - the attr's value is the XML namespace; + * _Note:_ The XML namespace cannot be redeclared and survive + * round-tripping (unless it defines the prefix "xml"). To avoid this + * problem, this algorithm always prefixes elements in the XML + * namespace with "xml" and drops any related definitions as seen + * in the above condition. + * - the attr's prefix is null and the ignore namespace definition + * attribute flag is true (the Element's default namespace attribute + * should be skipped); + * - the attr's prefix is not null and either + * * the attr's localName is not a key contained in the local + * prefixes map, or + * * the attr's localName is present in the local prefixes map but + * the value of the key does not match attr's value + * and furthermore that the attr's localName (as the prefix to find) + * is found in the namespace prefix map given the namespace consisting + * of the attr's value (the current namespace prefix definition was + * exactly defined previously--on an ancestor element not the current + * element whose attributes are being processed). + */ + if (attr.value === infra_1.namespace.XML || + (attr.prefix === null && ignoreNamespaceDefinitionAttribute) || + (attr.prefix !== null && (!(attr.localName in localPrefixesMap) || + localPrefixesMap[attr.localName] !== attr.value) && + map.has(attr.localName, attr.value))) + continue; + /** + * 3.5.2.2. If the require well-formed flag is set (its value is true), + * and the value of attr's value attribute matches the XMLNS + * namespace, then throw an exception; the serialization of this + * attribute would produce invalid XML because the XMLNS namespace + * is reserved and cannot be applied as an element's namespace via + * XML parsing. + * + * _Note:_ DOM APIs do allow creation of elements in the XMLNS + * namespace but with strict qualifications. + */ + if (requireWellFormed && attr.value === infra_1.namespace.XMLNS) { + throw new Error("XMLNS namespace is reserved (well-formed required)."); + } + /** + * 3.5.2.3. If the require well-formed flag is set (its value is true), + * and the value of attr's value attribute is the empty string, then + * throw an exception; namespace prefix declarations cannot be used + * to undeclare a namespace (use a default namespace declaration + * instead). + */ + if (requireWellFormed && attr.value === '') { + throw new Error("Namespace prefix declarations cannot be used to undeclare a namespace (well-formed required)."); + } + /** + * 3.5.2.4. the attr's prefix matches the string "xmlns", then let + * candidate prefix be the string "xmlns". + */ + if (attr.prefix === 'xmlns') + candidatePrefix = 'xmlns'; + /** + * 3.5.3. Otherwise, the attribute namespace is not the XMLNS namespace. + * Run these steps: + * + * _Note:_ The (candidatePrefix === null) check is not in the spec. + * We deviate from the spec here. Otherwise a prefix is generated for + * all attributes with namespaces. + */ + } + else if (candidatePrefix === null) { + if (attr.prefix !== null && + (!map.hasPrefix(attr.prefix) || + map.has(attr.prefix, attributeNamespace))) { + /** + * Check if we can use the attribute's own prefix. + * We deviate from the spec here. + * TODO: This is not an efficient way of searching for prefixes. + * Follow developments to the spec. + */ + candidatePrefix = attr.prefix; + } + else { + /** + * 3.5.3.1. Let candidate prefix be the result of generating a prefix + * providing map, attribute namespace, and prefix index as input. + */ + candidatePrefix = this._generatePrefix(attributeNamespace, map, prefixIndex); + } + /** + * 3.5.3.2. Append the following to result, in the order listed: + * 3.5.3.2.1. " " (U+0020 SPACE); + * 3.5.3.2.2. The string "xmlns:"; + * 3.5.3.2.3. The value of candidate prefix; + * 3.5.3.2.4. "="" (U+003D EQUALS SIGN, U+0022 QUOTATION MARK); + * 3.5.3.2.5. The result of serializing an attribute value given + * attribute namespace and the require well-formed flag as input; + * 3.5.3.2.6. """ (U+0022 QUOTATION MARK). + */ + result.push([null, "xmlns", candidatePrefix, + this._serializeAttributeValue(attributeNamespace, requireWellFormed, noDoubleEncoding)]); + } + } + /** + * 3.6. Append a " " (U+0020 SPACE) to result. + * 3.7. If candidate prefix is not null, then append to result the + * concatenation of candidate prefix with ":" (U+003A COLON). + */ + let attrName = ''; + if (candidatePrefix !== null) { + attrName = candidatePrefix; + } + /** + * 3.8. If the require well-formed flag is set (its value is true), and + * this attr's localName attribute contains the character + * ":" (U+003A COLON) or does not match the XML Name production or + * equals "xmlns" and attribute namespace is null, then throw an + * exception; the serialization of this attr would not be a + * well-formed attribute. + */ + if (requireWellFormed && (attr.localName.indexOf(":") !== -1 || + !algorithm_1.xml_isName(attr.localName) || + (attr.localName === "xmlns" && attributeNamespace === null))) { + throw new Error("Attribute local name contains invalid characters (well-formed required)."); + } + /** + * 3.9. Append the following strings to result, in the order listed: + * 3.9.1. The value of attr's localName; + * 3.9.2. "="" (U+003D EQUALS SIGN, U+0022 QUOTATION MARK); + * 3.9.3. The result of serializing an attribute value given attr's value + * attribute and the require well-formed flag as input; + * 3.9.4. """ (U+0022 QUOTATION MARK). + */ + result.push([attributeNamespace, candidatePrefix, attr.localName, + this._serializeAttributeValue(attr.value, requireWellFormed, noDoubleEncoding)]); + } + /** + * 4. Return the value of result. + */ + return result; + } + /** + * Produces an XML serialization of the attributes of an element node. + * + * @param node - node to serialize + * @param requireWellFormed - whether to check conformance + */ + _serializeAttributes(node, requireWellFormed, noDoubleEncoding) { + /** + * 1. Let result be the empty string. + * 2. Let localname set be a new empty namespace localname set. This + * localname set will contain tuples of unique attribute namespaceURI and + * localName pairs, and is populated as each attr is processed. This set is + * used to [optionally] enforce the well-formed constraint that an element + * cannot have two attributes with the same namespaceURI and localName. + * This can occur when two otherwise identical attributes on the same + * element differ only by their prefix values. + */ + const result = []; + const localNameSet = requireWellFormed ? {} : undefined; + /** + * 3. Loop: For each attribute attr in element's attributes, in the order + * they are specified in the element's attribute list: + */ + for (const attr of node.attributes) { + // Optimize common case + if (!requireWellFormed) { + result.push([null, null, attr.localName, + this._serializeAttributeValue(attr.value, requireWellFormed, noDoubleEncoding)]); + continue; + } + /** + * 3.1. If the require well-formed flag is set (its value is true), and the + * localname set contains a tuple whose values match those of a new tuple + * consisting of attr's namespaceURI attribute and localName attribute, + * then throw an exception; the serialization of this attr would fail to + * produce a well-formed element serialization. + */ + if (requireWellFormed && localNameSet && (attr.localName in localNameSet)) { + throw new Error("Element contains duplicate attributes (well-formed required)."); + } + /** + * 3.2. Create a new tuple consisting of attr's namespaceURI attribute and + * localName attribute, and add it to the localname set. + * 3.3. Let attribute namespace be the value of attr's namespaceURI value. + * 3.4. Let candidate prefix be null. + */ + /* istanbul ignore else */ + if (requireWellFormed && localNameSet) + localNameSet[attr.localName] = true; + /** 3.5. If attribute namespace is not null, then run these sub-steps: */ + /** + * 3.6. Append a " " (U+0020 SPACE) to result. + * 3.7. If candidate prefix is not null, then append to result the + * concatenation of candidate prefix with ":" (U+003A COLON). + */ + /** + * 3.8. If the require well-formed flag is set (its value is true), and + * this attr's localName attribute contains the character + * ":" (U+003A COLON) or does not match the XML Name production or + * equals "xmlns" and attribute namespace is null, then throw an + * exception; the serialization of this attr would not be a + * well-formed attribute. + */ + if (requireWellFormed && (attr.localName.indexOf(":") !== -1 || + !algorithm_1.xml_isName(attr.localName))) { + throw new Error("Attribute local name contains invalid characters (well-formed required)."); + } + /** + * 3.9. Append the following strings to result, in the order listed: + * 3.9.1. The value of attr's localName; + * 3.9.2. "="" (U+003D EQUALS SIGN, U+0022 QUOTATION MARK); + * 3.9.3. The result of serializing an attribute value given attr's value + * attribute and the require well-formed flag as input; + * 3.9.4. """ (U+0022 QUOTATION MARK). + */ + result.push([null, null, attr.localName, + this._serializeAttributeValue(attr.value, requireWellFormed, noDoubleEncoding)]); + } + /** + * 4. Return the value of result. + */ + return result; + } + /** + * Records namespace information for the given element and returns the + * default namespace attribute value. + * + * @param node - element node to process + * @param map - namespace prefix map + * @param localPrefixesMap - local prefixes map + */ + _recordNamespaceInformation(node, map, localPrefixesMap) { + /** + * 1. Let default namespace attr value be null. + */ + let defaultNamespaceAttrValue = null; + /** + * 2. Main: For each attribute attr in element's attributes, in the order + * they are specified in the element's attribute list: + */ + for (const attr of node.attributes) { + /** + * _Note:_ The following conditional steps find namespace prefixes. Only + * attributes in the XMLNS namespace are considered (e.g., attributes made + * to look like namespace declarations via + * setAttribute("xmlns:pretend-prefix", "pretend-namespace") are not + * included). + */ + /** 2.1. Let attribute namespace be the value of attr's namespaceURI value. */ + let attributeNamespace = attr.namespaceURI; + /** 2.2. Let attribute prefix be the value of attr's prefix. */ + let attributePrefix = attr.prefix; + /** 2.3. If the attribute namespace is the XMLNS namespace, then: */ + if (attributeNamespace === infra_1.namespace.XMLNS) { + /** + * 2.3.1. If attribute prefix is null, then attr is a default namespace + * declaration. Set the default namespace attr value to attr's value and + * stop running these steps, returning to Main to visit the next + * attribute. + */ + if (attributePrefix === null) { + defaultNamespaceAttrValue = attr.value; + continue; + /** + * 2.3.2. Otherwise, the attribute prefix is not null and attr is a + * namespace prefix definition. Run the following steps: + */ + } + else { + /** 2.3.2.1. Let prefix definition be the value of attr's localName. */ + let prefixDefinition = attr.localName; + /** 2.3.2.2. Let namespace definition be the value of attr's value. */ + let namespaceDefinition = attr.value; + /** + * 2.3.2.3. If namespace definition is the XML namespace, then stop + * running these steps, and return to Main to visit the next + * attribute. + * + * _Note:_ XML namespace definitions in prefixes are completely + * ignored (in order to avoid unnecessary work when there might be + * prefix conflicts). XML namespaced elements are always handled + * uniformly by prefixing (and overriding if necessary) the element's + * localname with the reserved "xml" prefix. + */ + if (namespaceDefinition === infra_1.namespace.XML) { + continue; + } + /** + * 2.3.2.4. If namespace definition is the empty string (the + * declarative form of having no namespace), then let namespace + * definition be null instead. + */ + if (namespaceDefinition === '') { + namespaceDefinition = null; + } + /** + * 2.3.2.5. If prefix definition is found in map given the namespace + * namespace definition, then stop running these steps, and return to + * Main to visit the next attribute. + * + * _Note:_ This step avoids adding duplicate prefix definitions for + * the same namespace in the map. This has the side-effect of avoiding + * later serialization of duplicate namespace prefix declarations in + * any descendant nodes. + */ + if (map.has(prefixDefinition, namespaceDefinition)) { + continue; + } + /** + * 2.3.2.6. Add the prefix prefix definition to map given namespace + * namespace definition. + */ + map.set(prefixDefinition, namespaceDefinition); + /** + * 2.3.2.7. Add the value of prefix definition as a new key to the + * local prefixes map, with the namespace definition as the key's + * value replacing the value of null with the empty string if + * applicable. + */ + localPrefixesMap[prefixDefinition] = namespaceDefinition || ''; + } + } + } + /** + * 3. Return the value of default namespace attr value. + * + * _Note:_ The empty string is a legitimate return value and is not + * converted to null. + */ + return defaultNamespaceAttrValue; + } + /** + * Generates a new prefix for the given namespace. + * + * @param newNamespace - a namespace to generate prefix for + * @param prefixMap - namespace prefix map + * @param prefixIndex - generated namespace prefix index + */ + _generatePrefix(newNamespace, prefixMap, prefixIndex) { + /** + * 1. Let generated prefix be the concatenation of the string "ns" and the + * current numerical value of prefix index. + * 2. Let the value of prefix index be incremented by one. + * 3. Add to map the generated prefix given the new namespace namespace. + * 4. Return the value of generated prefix. + */ + const generatedPrefix = "ns" + prefixIndex.value.toString(); + prefixIndex.value++; + prefixMap.set(generatedPrefix, newNamespace); + return generatedPrefix; + } + /** + * Produces an XML serialization of an attribute value. + * + * @param value - attribute value + * @param requireWellFormed - whether to check conformance + */ + _serializeAttributeValue(value, requireWellFormed, noDoubleEncoding) { + /** + * From: https://w3c.github.io/DOM-Parsing/#dfn-serializing-an-attribute-value + * + * 1. If the require well-formed flag is set (its value is true), and + * attribute value contains characters that are not matched by the XML Char + * production, then throw an exception; the serialization of this attribute + * value would fail to produce a well-formed element serialization. + */ + if (requireWellFormed && value !== null && !algorithm_1.xml_isLegalChar(value)) { + throw new Error("Invalid characters in attribute value."); + } + /** + * 2. If attribute value is null, then return the empty string. + */ + if (value === null) + return ""; + /** + * 3. Otherwise, attribute value is a string. Return the value of attribute + * value, first replacing any occurrences of the following: + * - "&" with "&" + * - """ with """ + * - "<" with "<" + * - ">" with ">" + * NOTE + * This matches behavior present in browsers, and goes above and beyond the + * grammar requirement in the XML specification's AttValue production by + * also replacing ">" characters. + */ + if (noDoubleEncoding) { + return value.replace(/(?!&(lt|gt|amp|apos|quot);)&/g, '&') + .replace(/") + result += ">"; + else + result += c; + } + return result; + } + } +} +exports.BaseWriter = BaseWriter; +BaseWriter._VoidElementNames = new Set(['area', 'base', 'basefont', + 'bgsound', 'br', 'col', 'embed', 'frame', 'hr', 'img', 'input', 'keygen', + 'link', 'menuitem', 'meta', 'param', 'source', 'track', 'wbr']); +//# sourceMappingURL=BaseWriter.js.map + +/***/ }), + +/***/ 464: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const interfaces_1 = __webpack_require__(970); +const DOMException_1 = __webpack_require__(35); +/** + * Applies the filter to the given node and returns the result. + * + * @param traverser - the `NodeIterator` or `TreeWalker` instance + * @param node - the node to filter + */ +function traversal_filter(traverser, node) { + /** + * 1. If traverser’s active flag is set, then throw an "InvalidStateError" + * DOMException. + */ + if (traverser._activeFlag) { + throw new DOMException_1.InvalidStateError(); + } + /** + * 2. Let n be node’s nodeType attribute value − 1. + */ + const n = node._nodeType - 1; + /** + * 3. If the nth bit (where 0 is the least significant bit) of traverser’s + * whatToShow is not set, then return FILTER_SKIP. + */ + const mask = 1 << n; + if ((traverser.whatToShow & mask) === 0) { + return interfaces_1.FilterResult.Skip; + } + /** + * 4. If traverser’s filter is null, then return FILTER_ACCEPT. + */ + if (!traverser.filter) { + return interfaces_1.FilterResult.Accept; + } + /** + * 5. Set traverser’s active flag. + */ + traverser._activeFlag = true; + /** + * 6. Let result be the return value of call a user object’s operation with + * traverser’s filter, "acceptNode", and « node ». If this throws an + * exception, then unset traverser’s active flag and rethrow the exception. + */ + let result = interfaces_1.FilterResult.Reject; + try { + result = traverser.filter.acceptNode(node); + } + catch (err) { + traverser._activeFlag = false; + throw err; + } + /** + * 7. Unset traverser’s active flag. + * 8. Return result. + */ + traverser._activeFlag = false; + return result; +} +exports.traversal_filter = traversal_filter; +//# sourceMappingURL=TraversalAlgorithm.js.map + +/***/ }), + +/***/ 468: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const XMLStringLexer_1 = __webpack_require__(911); +const interfaces_1 = __webpack_require__(172); +const infra_1 = __webpack_require__(23); +const algorithm_1 = __webpack_require__(163); +const LocalNameSet_1 = __webpack_require__(575); +/** + * Represents a parser for XML content. + * + * See: https://html.spec.whatwg.org/#xml-parser + */ +class XMLParserImpl { + /** + * Parses XML content. + * + * @param source - a string containing XML content + */ + parse(source) { + const lexer = new XMLStringLexer_1.XMLStringLexer(source, { skipWhitespaceOnlyText: true }); + const doc = algorithm_1.create_document(); + let context = doc; + let token = lexer.nextToken(); + while (token.type !== interfaces_1.TokenType.EOF) { + switch (token.type) { + case interfaces_1.TokenType.Declaration: + const declaration = token; + if (declaration.version !== "1.0") { + throw new Error("Invalid xml version: " + declaration.version); + } + break; + case interfaces_1.TokenType.DocType: + const doctype = token; + if (!algorithm_1.xml_isPubidChar(doctype.pubId)) { + throw new Error("DocType public identifier does not match PubidChar construct."); + } + if (!algorithm_1.xml_isLegalChar(doctype.sysId) || + (doctype.sysId.indexOf('"') !== -1 && doctype.sysId.indexOf("'") !== -1)) { + throw new Error("DocType system identifier contains invalid characters."); + } + context.appendChild(doc.implementation.createDocumentType(doctype.name, doctype.pubId, doctype.sysId)); + break; + case interfaces_1.TokenType.CDATA: + const cdata = token; + if (!algorithm_1.xml_isLegalChar(cdata.data) || + cdata.data.indexOf("]]>") !== -1) { + throw new Error("CDATA contains invalid characters."); + } + context.appendChild(doc.createCDATASection(cdata.data)); + break; + case interfaces_1.TokenType.Comment: + const comment = token; + if (!algorithm_1.xml_isLegalChar(comment.data) || + comment.data.indexOf("--") !== -1 || comment.data.endsWith("-")) { + throw new Error("Comment data contains invalid characters."); + } + context.appendChild(doc.createComment(comment.data)); + break; + case interfaces_1.TokenType.PI: + const pi = token; + if (pi.target.indexOf(":") !== -1 || (/^xml$/i).test(pi.target)) { + throw new Error("Processing instruction target contains invalid characters."); + } + if (!algorithm_1.xml_isLegalChar(pi.data) || pi.data.indexOf("?>") !== -1) { + throw new Error("Processing instruction data contains invalid characters."); + } + context.appendChild(doc.createProcessingInstruction(pi.target, pi.data)); + break; + case interfaces_1.TokenType.Text: + const text = token; + if (!algorithm_1.xml_isLegalChar(text.data)) { + throw new Error("Text data contains invalid characters."); + } + context.appendChild(doc.createTextNode(text.data)); + break; + case interfaces_1.TokenType.Element: + const element = token; + // inherit namespace from parent + const [prefix, localName] = algorithm_1.namespace_extractQName(element.name); + if (localName.indexOf(":") !== -1 || !algorithm_1.xml_isName(localName)) { + throw new Error("Node local name contains invalid characters."); + } + if (prefix === "xmlns") { + throw new Error("An element cannot have the 'xmlns' prefix."); + } + let namespace = context.lookupNamespaceURI(prefix); + // override namespace if there is a namespace declaration + // attribute + // also lookup namespace declaration attributes + const nsDeclarations = {}; + for (const [attName, attValue] of element.attributes) { + if (attName === "xmlns") { + namespace = attValue; + } + else { + const [attPrefix, attLocalName] = algorithm_1.namespace_extractQName(attName); + if (attPrefix === "xmlns") { + if (attLocalName === prefix) { + namespace = attValue; + } + nsDeclarations[attLocalName] = attValue; + } + } + } + // create the DOM element node + const elementNode = (namespace !== null ? + doc.createElementNS(namespace, element.name) : + doc.createElement(element.name)); + context.appendChild(elementNode); + // assign attributes + const localNameSet = new LocalNameSet_1.LocalNameSet(); + for (const [attName, attValue] of element.attributes) { + const [attPrefix, attLocalName] = algorithm_1.namespace_extractQName(attName); + let attNamespace = null; + if (attPrefix === "xmlns" || (attPrefix === null && attLocalName === "xmlns")) { + // namespace declaration attribute + attNamespace = infra_1.namespace.XMLNS; + } + else { + attNamespace = elementNode.lookupNamespaceURI(attPrefix); + if (attNamespace !== null && elementNode.isDefaultNamespace(attNamespace)) { + attNamespace = null; + } + else if (attNamespace === null && attPrefix !== null) { + attNamespace = nsDeclarations[attPrefix] || null; + } + } + if (localNameSet.has(attNamespace, attLocalName)) { + throw new Error("Element contains duplicate attributes."); + } + localNameSet.set(attNamespace, attLocalName); + if (attNamespace === infra_1.namespace.XMLNS) { + if (attValue === infra_1.namespace.XMLNS) { + throw new Error("XMLNS namespace is reserved."); + } + } + if (attLocalName.indexOf(":") !== -1 || !algorithm_1.xml_isName(attLocalName)) { + throw new Error("Attribute local name contains invalid characters."); + } + if (attPrefix === "xmlns" && attValue === "") { + throw new Error("Empty XML namespace is not allowed."); + } + if (attNamespace !== null) + elementNode.setAttributeNS(attNamespace, attName, attValue); + else + elementNode.setAttribute(attName, attValue); + } + if (!element.selfClosing) { + context = elementNode; + } + break; + case interfaces_1.TokenType.ClosingTag: + const closingTag = token; + if (closingTag.name !== context.nodeName) { + throw new Error('Closing tag name does not match opening tag name.'); + } + /* istanbul ignore else */ + if (context._parent) { + context = context._parent; + } + break; + } + token = lexer.nextToken(); + } + return doc; + } +} +exports.XMLParserImpl = XMLParserImpl; +//# sourceMappingURL=XMLParserImpl.js.map + +/***/ }), + +/***/ 470: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result["default"] = mod; + return result; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const command_1 = __webpack_require__(431); +const os = __importStar(__webpack_require__(87)); +const path = __importStar(__webpack_require__(622)); +/** + * The code to exit an action + */ +var ExitCode; +(function (ExitCode) { + /** + * A code indicating that the action was successful + */ + ExitCode[ExitCode["Success"] = 0] = "Success"; + /** + * A code indicating that the action was a failure + */ + ExitCode[ExitCode["Failure"] = 1] = "Failure"; +})(ExitCode = exports.ExitCode || (exports.ExitCode = {})); +//----------------------------------------------------------------------- +// Variables +//----------------------------------------------------------------------- +/** + * Sets env variable for this action and future actions in the job + * @param name the name of the variable to set + * @param val the value of the variable + */ +function exportVariable(name, val) { + process.env[name] = val; + command_1.issueCommand('set-env', { name }, val); +} +exports.exportVariable = exportVariable; +/** + * Registers a secret which will get masked from logs + * @param secret value of the secret + */ +function setSecret(secret) { + command_1.issueCommand('add-mask', {}, secret); +} +exports.setSecret = setSecret; +/** + * Prepends inputPath to the PATH (for this action and future actions) + * @param inputPath + */ +function addPath(inputPath) { + command_1.issueCommand('add-path', {}, inputPath); + process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`; +} +exports.addPath = addPath; +/** + * Gets the value of an input. The value is also trimmed. + * + * @param name name of the input to get + * @param options optional. See InputOptions. + * @returns string + */ +function getInput(name, options) { + const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || ''; + if (options && options.required && !val) { + throw new Error(`Input required and not supplied: ${name}`); + } + return val.trim(); +} +exports.getInput = getInput; +/** + * Sets the value of an output. + * + * @param name name of the output to set + * @param value value to store + */ +function setOutput(name, value) { + command_1.issueCommand('set-output', { name }, value); +} +exports.setOutput = setOutput; +//----------------------------------------------------------------------- +// Results +//----------------------------------------------------------------------- +/** + * Sets the action status to failed. + * When the action exits it will be with an exit code of 1 + * @param message add error issue message + */ +function setFailed(message) { + process.exitCode = ExitCode.Failure; + error(message); +} +exports.setFailed = setFailed; +//----------------------------------------------------------------------- +// Logging Commands +//----------------------------------------------------------------------- +/** + * Writes debug message to user log + * @param message debug message + */ +function debug(message) { + command_1.issueCommand('debug', {}, message); +} +exports.debug = debug; +/** + * Adds an error issue + * @param message error issue message + */ +function error(message) { + command_1.issue('error', message); +} +exports.error = error; +/** + * Adds an warning issue + * @param message warning issue message + */ +function warning(message) { + command_1.issue('warning', message); +} +exports.warning = warning; +/** + * Writes info to log with console.log. + * @param message info message + */ +function info(message) { + process.stdout.write(message + os.EOL); +} +exports.info = info; +/** + * Begin an output group. + * + * Output until the next `groupEnd` will be foldable in this group + * + * @param name The name of the output group + */ +function startGroup(name) { + command_1.issue('group', name); +} +exports.startGroup = startGroup; +/** + * End an output group. + */ +function endGroup() { + command_1.issue('endgroup'); +} +exports.endGroup = endGroup; +/** + * Wrap an asynchronous function call in a group. + * + * Returns the same type as the function itself. + * + * @param name The name of the group + * @param fn The function to wrap in the group + */ +function group(name, fn) { + return __awaiter(this, void 0, void 0, function* () { + startGroup(name); + let result; + try { + result = yield fn(); + } + finally { + endGroup(); + } + return result; + }); +} +exports.group = group; +//----------------------------------------------------------------------- +// Wrapper action state +//----------------------------------------------------------------------- +/** + * Saves state for current action, the state can only be retrieved by this action's post job execution. + * + * @param name name of the state to store + * @param value value to store + */ +function saveState(name, value) { + command_1.issueCommand('save-state', { name }, value); +} +exports.saveState = saveState; +/** + * Gets the value of an state set by this action's main execution. + * + * @param name name of the state to get + * @returns string + */ +function getState(name) { + return process.env[`STATE_${name}`] || ''; +} +exports.getState = getState; +//# sourceMappingURL=core.js.map + +/***/ }), + +/***/ 476: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const algorithm_1 = __webpack_require__(163); +/** + * Represents a mixin that allows nodes to become the contents of + * a element. This mixin is implemented by {@link Element} and + * {@link Text}. + */ +class SlotableImpl { + get _name() { return this.__name || ''; } + set _name(val) { this.__name = val; } + get _assignedSlot() { return this.__assignedSlot || null; } + set _assignedSlot(val) { this.__assignedSlot = val; } + /** @inheritdoc */ + get assignedSlot() { + return algorithm_1.shadowTree_findASlot(this, true); + } +} +exports.SlotableImpl = SlotableImpl; +//# sourceMappingURL=SlotableImpl.js.map + +/***/ }), + +/***/ 479: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const dom_1 = __webpack_require__(113); +const DOMException_1 = __webpack_require__(35); +const interfaces_1 = __webpack_require__(970); +const util_1 = __webpack_require__(918); +const util_2 = __webpack_require__(337); +const infra_1 = __webpack_require__(23); +const CustomElementAlgorithm_1 = __webpack_require__(344); +const TreeAlgorithm_1 = __webpack_require__(873); +const NodeIteratorAlgorithm_1 = __webpack_require__(272); +const ShadowTreeAlgorithm_1 = __webpack_require__(180); +const MutationObserverAlgorithm_1 = __webpack_require__(151); +const DOMAlgorithm_1 = __webpack_require__(304); +const DocumentAlgorithm_1 = __webpack_require__(493); +/** + * Ensures pre-insertion validity of a node into a parent before a + * child. + * + * @param node - node to insert + * @param parent - parent node to receive node + * @param child - child node to insert node before + */ +function mutation_ensurePreInsertionValidity(node, parent, child) { + const parentNodeType = parent._nodeType; + const nodeNodeType = node._nodeType; + const childNodeType = child ? child._nodeType : null; + /** + * 1. If parent is not a Document, DocumentFragment, or Element node, + * throw a "HierarchyRequestError" DOMException. + */ + if (parentNodeType !== interfaces_1.NodeType.Document && + parentNodeType !== interfaces_1.NodeType.DocumentFragment && + parentNodeType !== interfaces_1.NodeType.Element) + throw new DOMException_1.HierarchyRequestError(`Only document, document fragment and element nodes can contain child nodes. Parent node is ${parent.nodeName}.`); + /** + * 2. If node is a host-including inclusive ancestor of parent, throw a + * "HierarchyRequestError" DOMException. + */ + if (TreeAlgorithm_1.tree_isHostIncludingAncestorOf(parent, node, true)) + throw new DOMException_1.HierarchyRequestError(`The node to be inserted cannot be an inclusive ancestor of parent node. Node is ${node.nodeName}, parent node is ${parent.nodeName}.`); + /** + * 3. If child is not null and its parent is not parent, then throw a + * "NotFoundError" DOMException. + */ + if (child !== null && child._parent !== parent) + throw new DOMException_1.NotFoundError(`The reference child node cannot be found under parent node. Child node is ${child.nodeName}, parent node is ${parent.nodeName}.`); + /** + * 4. If node is not a DocumentFragment, DocumentType, Element, Text, + * ProcessingInstruction, or Comment node, throw a "HierarchyRequestError" + * DOMException. + */ + if (nodeNodeType !== interfaces_1.NodeType.DocumentFragment && + nodeNodeType !== interfaces_1.NodeType.DocumentType && + nodeNodeType !== interfaces_1.NodeType.Element && + nodeNodeType !== interfaces_1.NodeType.Text && + nodeNodeType !== interfaces_1.NodeType.ProcessingInstruction && + nodeNodeType !== interfaces_1.NodeType.CData && + nodeNodeType !== interfaces_1.NodeType.Comment) + throw new DOMException_1.HierarchyRequestError(`Only document fragment, document type, element, text, processing instruction, cdata section or comment nodes can be inserted. Node is ${node.nodeName}.`); + /** + * 5. If either node is a Text node and parent is a document, or node is a + * doctype and parent is not a document, throw a "HierarchyRequestError" + * DOMException. + */ + if (nodeNodeType === interfaces_1.NodeType.Text && + parentNodeType === interfaces_1.NodeType.Document) + throw new DOMException_1.HierarchyRequestError(`Cannot insert a text node as a child of a document node. Node is ${node.nodeName}.`); + if (nodeNodeType === interfaces_1.NodeType.DocumentType && + parentNodeType !== interfaces_1.NodeType.Document) + throw new DOMException_1.HierarchyRequestError(`A document type node can only be inserted under a document node. Parent node is ${parent.nodeName}.`); + /** + * 6. If parent is a document, and any of the statements below, switched on + * node, are true, throw a "HierarchyRequestError" DOMException. + * - DocumentFragment node + * If node has more than one element child or has a Text node child. + * Otherwise, if node has one element child and either parent has an element + * child, child is a doctype, or child is not null and a doctype is + * following child. + * - element + * parent has an element child, child is a doctype, or child is not null and + * a doctype is following child. + * - doctype + * parent has a doctype child, child is non-null and an element is preceding + * child, or child is null and parent has an element child. + */ + if (parentNodeType === interfaces_1.NodeType.Document) { + if (nodeNodeType === interfaces_1.NodeType.DocumentFragment) { + let eleCount = 0; + for (const childNode of node._children) { + if (childNode._nodeType === interfaces_1.NodeType.Element) + eleCount++; + else if (childNode._nodeType === interfaces_1.NodeType.Text) + throw new DOMException_1.HierarchyRequestError(`Cannot insert text a node as a child of a document node. Node is ${childNode.nodeName}.`); + } + if (eleCount > 1) { + throw new DOMException_1.HierarchyRequestError(`A document node can only have one document element node. Document fragment to be inserted has ${eleCount} element nodes.`); + } + else if (eleCount === 1) { + for (const ele of parent._children) { + if (ele._nodeType === interfaces_1.NodeType.Element) + throw new DOMException_1.HierarchyRequestError(`The document node already has a document element node.`); + } + if (child) { + if (childNodeType === interfaces_1.NodeType.DocumentType) + throw new DOMException_1.HierarchyRequestError(`Cannot insert an element node before a document type node.`); + let doctypeChild = child._nextSibling; + while (doctypeChild) { + if (doctypeChild._nodeType === interfaces_1.NodeType.DocumentType) + throw new DOMException_1.HierarchyRequestError(`Cannot insert an element node before a document type node.`); + doctypeChild = doctypeChild._nextSibling; + } + } + } + } + else if (nodeNodeType === interfaces_1.NodeType.Element) { + for (const ele of parent._children) { + if (ele._nodeType === interfaces_1.NodeType.Element) + throw new DOMException_1.HierarchyRequestError(`Document already has a document element node. Node is ${node.nodeName}.`); + } + if (child) { + if (childNodeType === interfaces_1.NodeType.DocumentType) + throw new DOMException_1.HierarchyRequestError(`Cannot insert an element node before a document type node. Node is ${node.nodeName}.`); + let doctypeChild = child._nextSibling; + while (doctypeChild) { + if (doctypeChild._nodeType === interfaces_1.NodeType.DocumentType) + throw new DOMException_1.HierarchyRequestError(`Cannot insert an element node before a document type node. Node is ${node.nodeName}.`); + doctypeChild = doctypeChild._nextSibling; + } + } + } + else if (nodeNodeType === interfaces_1.NodeType.DocumentType) { + for (const ele of parent._children) { + if (ele._nodeType === interfaces_1.NodeType.DocumentType) + throw new DOMException_1.HierarchyRequestError(`Document already has a document type node. Node is ${node.nodeName}.`); + } + if (child) { + let elementChild = child._previousSibling; + while (elementChild) { + if (elementChild._nodeType === interfaces_1.NodeType.Element) + throw new DOMException_1.HierarchyRequestError(`Cannot insert a document type node before an element node. Node is ${node.nodeName}.`); + elementChild = elementChild._previousSibling; + } + } + else { + let elementChild = parent._firstChild; + while (elementChild) { + if (elementChild._nodeType === interfaces_1.NodeType.Element) + throw new DOMException_1.HierarchyRequestError(`Cannot insert a document type node before an element node. Node is ${node.nodeName}.`); + elementChild = elementChild._nextSibling; + } + } + } + } +} +exports.mutation_ensurePreInsertionValidity = mutation_ensurePreInsertionValidity; +/** + * Ensures pre-insertion validity of a node into a parent before a + * child, then adopts the node to the tree and inserts it. + * + * @param node - node to insert + * @param parent - parent node to receive node + * @param child - child node to insert node before + */ +function mutation_preInsert(node, parent, child) { + /** + * 1. Ensure pre-insertion validity of node into parent before child. + * 2. Let reference child be child. + * 3. If reference child is node, set it to node’s next sibling. + * 4. Adopt node into parent’s node document. + * 5. Insert node into parent before reference child. + * 6. Return node. + */ + mutation_ensurePreInsertionValidity(node, parent, child); + let referenceChild = child; + if (referenceChild === node) + referenceChild = node._nextSibling; + DocumentAlgorithm_1.document_adopt(node, parent._nodeDocument); + mutation_insert(node, parent, referenceChild); + return node; +} +exports.mutation_preInsert = mutation_preInsert; +/** + * Inserts a node into a parent node before the given child node. + * + * @param node - node to insert + * @param parent - parent node to receive node + * @param child - child node to insert node before + * @param suppressObservers - whether to notify observers + */ +function mutation_insert(node, parent, child, suppressObservers) { + // Optimized common case + if (child === null && node._nodeType !== interfaces_1.NodeType.DocumentFragment) { + mutation_insert_single(node, parent, suppressObservers); + return; + } + /** + * 1. Let count be the number of children of node if it is a + * DocumentFragment node, and one otherwise. + */ + const count = (node._nodeType === interfaces_1.NodeType.DocumentFragment ? + node._children.size : 1); + /** + * 2. If child is non-null, then: + */ + if (child !== null) { + /** + * 2.1. For each live range whose start node is parent and start + * offset is greater than child's index, increase its start + * offset by count. + * 2.2. For each live range whose end node is parent and end + * offset is greater than child's index, increase its end + * offset by count. + */ + if (dom_1.dom.rangeList.size !== 0) { + const index = TreeAlgorithm_1.tree_index(child); + for (const range of dom_1.dom.rangeList) { + if (range._start[0] === parent && range._start[1] > index) { + range._start[1] += count; + } + if (range._end[0] === parent && range._end[1] > index) { + range._end[1] += count; + } + } + } + } + /** + * 3. Let nodes be node’s children, if node is a DocumentFragment node; + * otherwise « node ». + */ + const nodes = node._nodeType === interfaces_1.NodeType.DocumentFragment ? + new Array(...node._children) : [node]; + /** + * 4. If node is a DocumentFragment node, remove its children with the + * suppress observers flag set. + */ + if (node._nodeType === interfaces_1.NodeType.DocumentFragment) { + while (node._firstChild) { + mutation_remove(node._firstChild, node, true); + } + } + /** + * 5. If node is a DocumentFragment node, then queue a tree mutation record + * for node with « », nodes, null, and null. + */ + if (dom_1.dom.features.mutationObservers) { + if (node._nodeType === interfaces_1.NodeType.DocumentFragment) { + MutationObserverAlgorithm_1.observer_queueTreeMutationRecord(node, [], nodes, null, null); + } + } + /** + * 6. Let previousSibling be child’s previous sibling or parent’s last + * child if child is null. + */ + const previousSibling = (child ? child._previousSibling : parent._lastChild); + let index = child === null ? -1 : TreeAlgorithm_1.tree_index(child); + /** + * 7. For each node in nodes, in tree order: + */ + for (let i = 0; i < nodes.length; i++) { + const node = nodes[i]; + if (util_1.Guard.isElementNode(node)) { + // set document element node + if (util_1.Guard.isDocumentNode(parent)) { + parent._documentElement = node; + } + // mark that the document has namespaces + if (!node._nodeDocument._hasNamespaces && (node._namespace !== null || + node._namespacePrefix !== null)) { + node._nodeDocument._hasNamespaces = true; + } + } + /** + * 7.1. If child is null, then append node to parent’s children. + * 7.2. Otherwise, insert node into parent’s children before child’s + * index. + */ + node._parent = parent; + if (child === null) { + infra_1.set.append(parent._children, node); + } + else { + infra_1.set.insert(parent._children, node, index); + index++; + } + // assign siblings and children for quick lookups + if (parent._firstChild === null) { + node._previousSibling = null; + node._nextSibling = null; + parent._firstChild = node; + parent._lastChild = node; + } + else { + const prev = (child ? child._previousSibling : parent._lastChild); + const next = (child ? child : null); + node._previousSibling = prev; + node._nextSibling = next; + if (prev) + prev._nextSibling = node; + if (next) + next._previousSibling = node; + if (!prev) + parent._firstChild = node; + if (!next) + parent._lastChild = node; + } + /** + * 7.3. If parent is a shadow host and node is a slotable, then + * assign a slot for node. + */ + if (dom_1.dom.features.slots) { + if (parent._shadowRoot !== null && util_1.Guard.isSlotable(node)) { + ShadowTreeAlgorithm_1.shadowTree_assignASlot(node); + } + } + /** + * 7.4. If node is a Text node, run the child text content change + * steps for parent. + */ + if (dom_1.dom.features.steps) { + if (util_1.Guard.isTextNode(node)) { + DOMAlgorithm_1.dom_runChildTextContentChangeSteps(parent); + } + } + /** + * 7.5. If parent's root is a shadow root, and parent is a slot + * whose assigned nodes is the empty list, then run signal + * a slot change for parent. + */ + if (dom_1.dom.features.slots) { + if (util_1.Guard.isShadowRoot(TreeAlgorithm_1.tree_rootNode(parent)) && + util_1.Guard.isSlot(parent) && util_2.isEmpty(parent._assignedNodes)) { + ShadowTreeAlgorithm_1.shadowTree_signalASlotChange(parent); + } + } + /** + * 7.6. Run assign slotables for a tree with node's root. + */ + if (dom_1.dom.features.slots) { + ShadowTreeAlgorithm_1.shadowTree_assignSlotablesForATree(TreeAlgorithm_1.tree_rootNode(node)); + } + /** + * 7.7. For each shadow-including inclusive descendant + * inclusiveDescendant of node, in shadow-including tree + * order: + */ + let inclusiveDescendant = TreeAlgorithm_1.tree_getFirstDescendantNode(node, true, true); + while (inclusiveDescendant !== null) { + /** + * 7.7.1. Run the insertion steps with inclusiveDescendant. + */ + if (dom_1.dom.features.steps) { + DOMAlgorithm_1.dom_runInsertionSteps(inclusiveDescendant); + } + if (dom_1.dom.features.customElements) { + /** + * 7.7.2. If inclusiveDescendant is connected, then: + */ + if (util_1.Guard.isElementNode(inclusiveDescendant) && + ShadowTreeAlgorithm_1.shadowTree_isConnected(inclusiveDescendant)) { + if (util_1.Guard.isCustomElementNode(inclusiveDescendant)) { + /** + * 7.7.2.1. If inclusiveDescendant is custom, then enqueue a custom + * element callback reaction with inclusiveDescendant, callback name + * "connectedCallback", and an empty argument list. + */ + CustomElementAlgorithm_1.customElement_enqueueACustomElementCallbackReaction(inclusiveDescendant, "connectedCallback", []); + } + else { + /** + * 7.7.2.2. Otherwise, try to upgrade inclusiveDescendant. + */ + CustomElementAlgorithm_1.customElement_tryToUpgrade(inclusiveDescendant); + } + } + } + inclusiveDescendant = TreeAlgorithm_1.tree_getNextDescendantNode(node, inclusiveDescendant, true, true); + } + } + /** + * 8. If suppress observers flag is unset, then queue a tree mutation record + * for parent with nodes, « », previousSibling, and child. + */ + if (dom_1.dom.features.mutationObservers) { + if (!suppressObservers) { + MutationObserverAlgorithm_1.observer_queueTreeMutationRecord(parent, nodes, [], previousSibling, child); + } + } +} +exports.mutation_insert = mutation_insert; +/** + * Inserts a node into a parent node. Optimized routine for the common case where + * node is not a document fragment node and it has no child nodes. + * + * @param node - node to insert + * @param parent - parent node to receive node + * @param suppressObservers - whether to notify observers + */ +function mutation_insert_single(node, parent, suppressObservers) { + /** + * 1. Let count be the number of children of node if it is a + * DocumentFragment node, and one otherwise. + * 2. If child is non-null, then: + * 2.1. For each live range whose start node is parent and start + * offset is greater than child's index, increase its start + * offset by count. + * 2.2. For each live range whose end node is parent and end + * offset is greater than child's index, increase its end + * offset by count. + * 3. Let nodes be node’s children, if node is a DocumentFragment node; + * otherwise « node ». + * 4. If node is a DocumentFragment node, remove its children with the + * suppress observers flag set. + * 5. If node is a DocumentFragment node, then queue a tree mutation record + * for node with « », nodes, null, and null. + */ + /** + * 6. Let previousSibling be child’s previous sibling or parent’s last + * child if child is null. + */ + const previousSibling = parent._lastChild; + // set document element node + if (util_1.Guard.isElementNode(node)) { + // set document element node + if (util_1.Guard.isDocumentNode(parent)) { + parent._documentElement = node; + } + // mark that the document has namespaces + if (!node._nodeDocument._hasNamespaces && (node._namespace !== null || + node._namespacePrefix !== null)) { + node._nodeDocument._hasNamespaces = true; + } + } + /** + * 7. For each node in nodes, in tree order: + * 7.1. If child is null, then append node to parent’s children. + * 7.2. Otherwise, insert node into parent’s children before child’s + * index. + */ + node._parent = parent; + parent._children.add(node); + // assign siblings and children for quick lookups + if (parent._firstChild === null) { + node._previousSibling = null; + node._nextSibling = null; + parent._firstChild = node; + parent._lastChild = node; + } + else { + const prev = parent._lastChild; + node._previousSibling = prev; + node._nextSibling = null; + if (prev) + prev._nextSibling = node; + if (!prev) + parent._firstChild = node; + parent._lastChild = node; + } + /** + * 7.3. If parent is a shadow host and node is a slotable, then + * assign a slot for node. + */ + if (dom_1.dom.features.slots) { + if (parent._shadowRoot !== null && util_1.Guard.isSlotable(node)) { + ShadowTreeAlgorithm_1.shadowTree_assignASlot(node); + } + } + /** + * 7.4. If node is a Text node, run the child text content change + * steps for parent. + */ + if (dom_1.dom.features.steps) { + if (util_1.Guard.isTextNode(node)) { + DOMAlgorithm_1.dom_runChildTextContentChangeSteps(parent); + } + } + /** + * 7.5. If parent's root is a shadow root, and parent is a slot + * whose assigned nodes is the empty list, then run signal + * a slot change for parent. + */ + if (dom_1.dom.features.slots) { + if (util_1.Guard.isShadowRoot(TreeAlgorithm_1.tree_rootNode(parent)) && + util_1.Guard.isSlot(parent) && util_2.isEmpty(parent._assignedNodes)) { + ShadowTreeAlgorithm_1.shadowTree_signalASlotChange(parent); + } + } + /** + * 7.6. Run assign slotables for a tree with node's root. + */ + if (dom_1.dom.features.slots) { + ShadowTreeAlgorithm_1.shadowTree_assignSlotablesForATree(TreeAlgorithm_1.tree_rootNode(node)); + } + /** + * 7.7. For each shadow-including inclusive descendant + * inclusiveDescendant of node, in shadow-including tree + * order: + * 7.7.1. Run the insertion steps with inclusiveDescendant. + */ + if (dom_1.dom.features.steps) { + DOMAlgorithm_1.dom_runInsertionSteps(node); + } + if (dom_1.dom.features.customElements) { + /** + * 7.7.2. If inclusiveDescendant is connected, then: + */ + if (util_1.Guard.isElementNode(node) && + ShadowTreeAlgorithm_1.shadowTree_isConnected(node)) { + if (util_1.Guard.isCustomElementNode(node)) { + /** + * 7.7.2.1. If inclusiveDescendant is custom, then enqueue a custom + * element callback reaction with inclusiveDescendant, callback name + * "connectedCallback", and an empty argument list. + */ + CustomElementAlgorithm_1.customElement_enqueueACustomElementCallbackReaction(node, "connectedCallback", []); + } + else { + /** + * 7.7.2.2. Otherwise, try to upgrade inclusiveDescendant. + */ + CustomElementAlgorithm_1.customElement_tryToUpgrade(node); + } + } + } + /** + * 8. If suppress observers flag is unset, then queue a tree mutation record + * for parent with nodes, « », previousSibling, and child. + */ + if (dom_1.dom.features.mutationObservers) { + if (!suppressObservers) { + MutationObserverAlgorithm_1.observer_queueTreeMutationRecord(parent, [node], [], previousSibling, null); + } + } +} +/** + * Appends a node to the children of a parent node. + * + * @param node - a node + * @param parent - the parent to receive node + */ +function mutation_append(node, parent) { + /** + * To append a node to a parent, pre-insert node into parent before null. + */ + return mutation_preInsert(node, parent, null); +} +exports.mutation_append = mutation_append; +/** + * Replaces a node with another node. + * + * @param child - child node to remove + * @param node - node to insert + * @param parent - parent node to receive node + */ +function mutation_replace(child, node, parent) { + /** + * 1. If parent is not a Document, DocumentFragment, or Element node, + * throw a "HierarchyRequestError" DOMException. + */ + if (parent._nodeType !== interfaces_1.NodeType.Document && + parent._nodeType !== interfaces_1.NodeType.DocumentFragment && + parent._nodeType !== interfaces_1.NodeType.Element) + throw new DOMException_1.HierarchyRequestError(`Only document, document fragment and element nodes can contain child nodes. Parent node is ${parent.nodeName}.`); + /** + * 2. If node is a host-including inclusive ancestor of parent, throw a + * "HierarchyRequestError" DOMException. + */ + if (TreeAlgorithm_1.tree_isHostIncludingAncestorOf(parent, node, true)) + throw new DOMException_1.HierarchyRequestError(`The node to be inserted cannot be an ancestor of parent node. Node is ${node.nodeName}, parent node is ${parent.nodeName}.`); + /** + * 3. If child’s parent is not parent, then throw a "NotFoundError" + * DOMException. + */ + if (child._parent !== parent) + throw new DOMException_1.NotFoundError(`The reference child node cannot be found under parent node. Child node is ${child.nodeName}, parent node is ${parent.nodeName}.`); + /** + * 4. If node is not a DocumentFragment, DocumentType, Element, Text, + * ProcessingInstruction, or Comment node, throw a "HierarchyRequestError" + * DOMException. + */ + if (node._nodeType !== interfaces_1.NodeType.DocumentFragment && + node._nodeType !== interfaces_1.NodeType.DocumentType && + node._nodeType !== interfaces_1.NodeType.Element && + node._nodeType !== interfaces_1.NodeType.Text && + node._nodeType !== interfaces_1.NodeType.ProcessingInstruction && + node._nodeType !== interfaces_1.NodeType.CData && + node._nodeType !== interfaces_1.NodeType.Comment) + throw new DOMException_1.HierarchyRequestError(`Only document fragment, document type, element, text, processing instruction, cdata section or comment nodes can be inserted. Node is ${node.nodeName}.`); + /** + * 5. If either node is a Text node and parent is a document, or node is a + * doctype and parent is not a document, throw a "HierarchyRequestError" + * DOMException. + */ + if (node._nodeType === interfaces_1.NodeType.Text && + parent._nodeType === interfaces_1.NodeType.Document) + throw new DOMException_1.HierarchyRequestError(`Cannot insert a text node as a child of a document node. Node is ${node.nodeName}.`); + if (node._nodeType === interfaces_1.NodeType.DocumentType && + parent._nodeType !== interfaces_1.NodeType.Document) + throw new DOMException_1.HierarchyRequestError(`A document type node can only be inserted under a document node. Parent node is ${parent.nodeName}.`); + /** + * 6. If parent is a document, and any of the statements below, switched on + * node, are true, throw a "HierarchyRequestError" DOMException. + * - DocumentFragment node + * If node has more than one element child or has a Text node child. + * Otherwise, if node has one element child and either parent has an element + * child that is not child or a doctype is following child. + * - element + * parent has an element child that is not child or a doctype is + * following child. + * - doctype + * parent has a doctype child that is not child, or an element is + * preceding child. + */ + if (parent._nodeType === interfaces_1.NodeType.Document) { + if (node._nodeType === interfaces_1.NodeType.DocumentFragment) { + let eleCount = 0; + for (const childNode of node._children) { + if (childNode._nodeType === interfaces_1.NodeType.Element) + eleCount++; + else if (childNode._nodeType === interfaces_1.NodeType.Text) + throw new DOMException_1.HierarchyRequestError(`Cannot insert text a node as a child of a document node. Node is ${childNode.nodeName}.`); + } + if (eleCount > 1) { + throw new DOMException_1.HierarchyRequestError(`A document node can only have one document element node. Document fragment to be inserted has ${eleCount} element nodes.`); + } + else if (eleCount === 1) { + for (const ele of parent._children) { + if (ele._nodeType === interfaces_1.NodeType.Element && ele !== child) + throw new DOMException_1.HierarchyRequestError(`The document node already has a document element node.`); + } + let doctypeChild = child._nextSibling; + while (doctypeChild) { + if (doctypeChild._nodeType === interfaces_1.NodeType.DocumentType) + throw new DOMException_1.HierarchyRequestError(`Cannot insert an element node before a document type node.`); + doctypeChild = doctypeChild._nextSibling; + } + } + } + else if (node._nodeType === interfaces_1.NodeType.Element) { + for (const ele of parent._children) { + if (ele._nodeType === interfaces_1.NodeType.Element && ele !== child) + throw new DOMException_1.HierarchyRequestError(`Document already has a document element node. Node is ${node.nodeName}.`); + } + let doctypeChild = child._nextSibling; + while (doctypeChild) { + if (doctypeChild._nodeType === interfaces_1.NodeType.DocumentType) + throw new DOMException_1.HierarchyRequestError(`Cannot insert an element node before a document type node. Node is ${node.nodeName}.`); + doctypeChild = doctypeChild._nextSibling; + } + } + else if (node._nodeType === interfaces_1.NodeType.DocumentType) { + for (const ele of parent._children) { + if (ele._nodeType === interfaces_1.NodeType.DocumentType && ele !== child) + throw new DOMException_1.HierarchyRequestError(`Document already has a document type node. Node is ${node.nodeName}.`); + } + let elementChild = child._previousSibling; + while (elementChild) { + if (elementChild._nodeType === interfaces_1.NodeType.Element) + throw new DOMException_1.HierarchyRequestError(`Cannot insert a document type node before an element node. Node is ${node.nodeName}.`); + elementChild = elementChild._previousSibling; + } + } + } + /** + * 7. Let reference child be child’s next sibling. + * 8. If reference child is node, set it to node’s next sibling. + * 8. Let previousSibling be child’s previous sibling. + */ + let referenceChild = child._nextSibling; + if (referenceChild === node) + referenceChild = node._nextSibling; + let previousSibling = child._previousSibling; + /** + * 10. Adopt node into parent’s node document. + * 11. Let removedNodes be the empty list. + */ + DocumentAlgorithm_1.document_adopt(node, parent._nodeDocument); + const removedNodes = []; + /** + * 12. If child’s parent is not null, then: + */ + if (child._parent !== null) { + /** + * 12.1. Set removedNodes to [child]. + * 12.2. Remove child from its parent with the suppress observers flag + * set. + */ + removedNodes.push(child); + mutation_remove(child, child._parent, true); + } + /** + * 13. Let nodes be node’s children if node is a DocumentFragment node; + * otherwise [node]. + */ + let nodes = []; + if (node._nodeType === interfaces_1.NodeType.DocumentFragment) { + nodes = Array.from(node._children); + } + else { + nodes.push(node); + } + /** + * 14. Insert node into parent before reference child with the suppress + * observers flag set. + */ + mutation_insert(node, parent, referenceChild, true); + /** + * 15. Queue a tree mutation record for parent with nodes, removedNodes, + * previousSibling, and reference child. + */ + if (dom_1.dom.features.mutationObservers) { + MutationObserverAlgorithm_1.observer_queueTreeMutationRecord(parent, nodes, removedNodes, previousSibling, referenceChild); + } + /** + * 16. Return child. + */ + return child; +} +exports.mutation_replace = mutation_replace; +/** + * Replaces all nodes of a parent with the given node. + * + * @param node - node to insert + * @param parent - parent node to receive node + */ +function mutation_replaceAll(node, parent) { + /** + * 1. If node is not null, adopt node into parent’s node document. + */ + if (node !== null) { + DocumentAlgorithm_1.document_adopt(node, parent._nodeDocument); + } + /** + * 2. Let removedNodes be parent’s children. + */ + const removedNodes = Array.from(parent._children); + /** + * 3. Let addedNodes be the empty list. + * 4. If node is DocumentFragment node, then set addedNodes to node’s + * children. + * 5. Otherwise, if node is non-null, set addedNodes to [node]. + */ + let addedNodes = []; + if (node && node._nodeType === interfaces_1.NodeType.DocumentFragment) { + addedNodes = Array.from(node._children); + } + else if (node !== null) { + addedNodes.push(node); + } + /** + * 6. Remove all parent’s children, in tree order, with the suppress + * observers flag set. + */ + for (const childNode of removedNodes) { + mutation_remove(childNode, parent, true); + } + /** + * 7. If node is not null, then insert node into parent before null with the + * suppress observers flag set. + */ + if (node !== null) { + mutation_insert(node, parent, null, true); + } + /** + * 8. Queue a tree mutation record for parent with addedNodes, removedNodes, + * null, and null. + */ + if (dom_1.dom.features.mutationObservers) { + MutationObserverAlgorithm_1.observer_queueTreeMutationRecord(parent, addedNodes, removedNodes, null, null); + } +} +exports.mutation_replaceAll = mutation_replaceAll; +/** + * Ensures pre-removal validity of a child node from a parent, then + * removes it. + * + * @param child - child node to remove + * @param parent - parent node + */ +function mutation_preRemove(child, parent) { + /** + * 1. If child’s parent is not parent, then throw a "NotFoundError" + * DOMException. + * 2. Remove child from parent. + * 3. Return child. + */ + if (child._parent !== parent) + throw new DOMException_1.NotFoundError(`The child node cannot be found under parent node. Child node is ${child.nodeName}, parent node is ${parent.nodeName}.`); + mutation_remove(child, parent); + return child; +} +exports.mutation_preRemove = mutation_preRemove; +/** + * Removes a child node from its parent. + * + * @param node - node to remove + * @param parent - parent node + * @param suppressObservers - whether to notify observers + */ +function mutation_remove(node, parent, suppressObservers) { + if (dom_1.dom.rangeList.size !== 0) { + /** + * 1. Let index be node’s index. + */ + const index = TreeAlgorithm_1.tree_index(node); + /** + * 2. For each live range whose start node is an inclusive descendant of + * node, set its start to (parent, index). + * 3. For each live range whose end node is an inclusive descendant of + * node, set its end to (parent, index). + */ + for (const range of dom_1.dom.rangeList) { + if (TreeAlgorithm_1.tree_isDescendantOf(node, range._start[0], true)) { + range._start = [parent, index]; + } + if (TreeAlgorithm_1.tree_isDescendantOf(node, range._end[0], true)) { + range._end = [parent, index]; + } + if (range._start[0] === parent && range._start[1] > index) { + range._start[1]--; + } + if (range._end[0] === parent && range._end[1] > index) { + range._end[1]--; + } + } + /** + * 4. For each live range whose start node is parent and start offset is + * greater than index, decrease its start offset by 1. + * 5. For each live range whose end node is parent and end offset is greater + * than index, decrease its end offset by 1. + */ + for (const range of dom_1.dom.rangeList) { + if (range._start[0] === parent && range._start[1] > index) { + range._start[1] -= 1; + } + if (range._end[0] === parent && range._end[1] > index) { + range._end[1] -= 1; + } + } + } + /** + * 6. For each NodeIterator object iterator whose root’s node document is + * node’s node document, run the NodeIterator pre-removing steps given node + * and iterator. + */ + if (dom_1.dom.features.steps) { + for (const iterator of NodeIteratorAlgorithm_1.nodeIterator_iteratorList()) { + if (iterator._root._nodeDocument === node._nodeDocument) { + DOMAlgorithm_1.dom_runNodeIteratorPreRemovingSteps(iterator, node); + } + } + } + /** + * 7. Let oldPreviousSibling be node’s previous sibling. + * 8. Let oldNextSibling be node’s next sibling. + */ + const oldPreviousSibling = node._previousSibling; + const oldNextSibling = node._nextSibling; + // set document element node + if (util_1.Guard.isDocumentNode(parent) && util_1.Guard.isElementNode(node)) { + parent._documentElement = null; + } + /** + * 9. Remove node from its parent’s children. + */ + node._parent = null; + parent._children.delete(node); + // assign siblings and children for quick lookups + const prev = node._previousSibling; + const next = node._nextSibling; + node._previousSibling = null; + node._nextSibling = null; + if (prev) + prev._nextSibling = next; + if (next) + next._previousSibling = prev; + if (!prev) + parent._firstChild = next; + if (!next) + parent._lastChild = prev; + /** + * 10. If node is assigned, then run assign slotables for node’s assigned + * slot. + */ + if (dom_1.dom.features.slots) { + if (util_1.Guard.isSlotable(node) && node._assignedSlot !== null && ShadowTreeAlgorithm_1.shadowTree_isAssigned(node)) { + ShadowTreeAlgorithm_1.shadowTree_assignSlotables(node._assignedSlot); + } + } + /** + * 11. If parent’s root is a shadow root, and parent is a slot whose + * assigned nodes is the empty list, then run signal a slot change for + * parent. + */ + if (dom_1.dom.features.slots) { + if (util_1.Guard.isShadowRoot(TreeAlgorithm_1.tree_rootNode(parent)) && + util_1.Guard.isSlot(parent) && util_2.isEmpty(parent._assignedNodes)) { + ShadowTreeAlgorithm_1.shadowTree_signalASlotChange(parent); + } + } + /** + * 12. If node has an inclusive descendant that is a slot, then: + * 12.1. Run assign slotables for a tree with parent's root. + * 12.2. Run assign slotables for a tree with node. + */ + if (dom_1.dom.features.slots) { + const descendant = TreeAlgorithm_1.tree_getFirstDescendantNode(node, true, false, (e) => util_1.Guard.isSlot(e)); + if (descendant !== null) { + ShadowTreeAlgorithm_1.shadowTree_assignSlotablesForATree(TreeAlgorithm_1.tree_rootNode(parent)); + ShadowTreeAlgorithm_1.shadowTree_assignSlotablesForATree(node); + } + } + /** + * 13. Run the removing steps with node and parent. + */ + if (dom_1.dom.features.steps) { + DOMAlgorithm_1.dom_runRemovingSteps(node, parent); + } + /** + * 14. If node is custom, then enqueue a custom element callback + * reaction with node, callback name "disconnectedCallback", + * and an empty argument list. + */ + if (dom_1.dom.features.customElements) { + if (util_1.Guard.isCustomElementNode(node)) { + CustomElementAlgorithm_1.customElement_enqueueACustomElementCallbackReaction(node, "disconnectedCallback", []); + } + } + /** + * 15. For each shadow-including descendant descendant of node, + * in shadow-including tree order, then: + */ + let descendant = TreeAlgorithm_1.tree_getFirstDescendantNode(node, false, true); + while (descendant !== null) { + /** + * 15.1. Run the removing steps with descendant. + */ + if (dom_1.dom.features.steps) { + DOMAlgorithm_1.dom_runRemovingSteps(descendant, node); + } + /** + * 15.2. If descendant is custom, then enqueue a custom element + * callback reaction with descendant, callback name + * "disconnectedCallback", and an empty argument list. + */ + if (dom_1.dom.features.customElements) { + if (util_1.Guard.isCustomElementNode(descendant)) { + CustomElementAlgorithm_1.customElement_enqueueACustomElementCallbackReaction(descendant, "disconnectedCallback", []); + } + } + descendant = TreeAlgorithm_1.tree_getNextDescendantNode(node, descendant, false, true); + } + /** + * 16. For each inclusive ancestor inclusiveAncestor of parent, and + * then for each registered of inclusiveAncestor's registered + * observer list, if registered's options's subtree is true, + * then append a new transient registered observer whose + * observer is registered's observer, options is registered's + * options, and source is registered to node's registered + * observer list. + */ + if (dom_1.dom.features.mutationObservers) { + let inclusiveAncestor = TreeAlgorithm_1.tree_getFirstAncestorNode(parent, true); + while (inclusiveAncestor !== null) { + for (const registered of inclusiveAncestor._registeredObserverList) { + if (registered.options.subtree) { + node._registeredObserverList.push({ + observer: registered.observer, + options: registered.options, + source: registered + }); + } + } + inclusiveAncestor = TreeAlgorithm_1.tree_getNextAncestorNode(parent, inclusiveAncestor, true); + } + } + /** + * 17. If suppress observers flag is unset, then queue a tree mutation + * record for parent with « », « node », oldPreviousSibling, and + * oldNextSibling. + */ + if (dom_1.dom.features.mutationObservers) { + if (!suppressObservers) { + MutationObserverAlgorithm_1.observer_queueTreeMutationRecord(parent, [], [node], oldPreviousSibling, oldNextSibling); + } + } + /** + * 18. If node is a Text node, then run the child text content change steps + * for parent. + */ + if (dom_1.dom.features.steps) { + if (util_1.Guard.isTextNode(node)) { + DOMAlgorithm_1.dom_runChildTextContentChangeSteps(parent); + } + } +} +exports.mutation_remove = mutation_remove; +//# sourceMappingURL=MutationAlgorithm.js.map + +/***/ }), + +/***/ 483: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const DOMException_1 = __webpack_require__(35); +/** + * Matches elements with the given selectors. + * + * @param selectors - selectors + * @param node - the node to match against + */ +function selectors_scopeMatchASelectorsString(selectors, node) { + /** + * TODO: Selectors + * 1. Let s be the result of parse a selector selectors. [SELECTORS4] + * 2. If s is failure, then throw a "SyntaxError" DOMException. + * 3. Return the result of match a selector against a tree with s and node’s + * root using scoping root node. [SELECTORS4]. + */ + throw new DOMException_1.NotSupportedError(); +} +exports.selectors_scopeMatchASelectorsString = selectors_scopeMatchASelectorsString; +//# sourceMappingURL=SelectorsAlgorithm.js.map + +/***/ }), + +/***/ 486: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const util_1 = __webpack_require__(42); +/** + * Gets the value corresponding to the given key. + * + * @param map - a map + * @param key - a key + */ +function get(map, key) { + return map.get(key); +} +exports.get = get; +/** + * Sets the value corresponding to the given key. + * + * @param map - a map + * @param key - a key + * @param val - a value + */ +function set(map, key, val) { + map.set(key, val); +} +exports.set = set; +/** + * Removes the item with the given key or all items matching condition. + * + * @param map - a map + * @param conditionOrItem - the key of an item to remove or a condition matching + * items to remove + */ +function remove(map, conditionOrItem) { + if (!util_1.isFunction(conditionOrItem)) { + map.delete(conditionOrItem); + } + else { + const toRemove = []; + for (const item of map) { + if (!!conditionOrItem.call(null, item)) { + toRemove.push(item[0]); + } + } + for (const key of toRemove) { + map.delete(key); + } + } +} +exports.remove = remove; +/** + * Determines if the map contains a value with the given key. + * + * @param map - a map + * @param conditionOrItem - the key of an item to match or a condition matching + * items + */ +function contains(map, conditionOrItem) { + if (!util_1.isFunction(conditionOrItem)) { + return map.has(conditionOrItem); + } + else { + for (const item of map) { + if (!!conditionOrItem.call(null, item)) { + return true; + } + } + return false; + } +} +exports.contains = contains; +/** + * Gets the keys of the map. + * + * @param map - a map + */ +function keys(map) { + return new Set(map.keys()); +} +exports.keys = keys; +/** + * Gets the values of the map. + * + * @param map - a map + */ +function values(map) { + return [...map.values()]; +} +exports.values = values; +/** + * Gets the size of the map. + * + * @param map - a map + * @param condition - an optional condition to match + */ +function size(map, condition) { + if (condition === undefined) { + return map.size; + } + else { + let count = 0; + for (const item of map) { + if (!!condition.call(null, item)) { + count++; + } + } + return count; + } +} +exports.size = size; +/** + * Determines if the map is empty. + * + * @param map - a map + */ +function isEmpty(map) { + return map.size === 0; +} +exports.isEmpty = isEmpty; +/** + * Returns an iterator for the items of the map. + * + * @param map - a map + * @param condition - an optional condition to match + */ +function* forEach(map, condition) { + if (condition === undefined) { + yield* map; + } + else { + for (const item of map) { + if (!!condition.call(null, item)) { + yield item; + } + } + } +} +exports.forEach = forEach; +/** + * Creates and returns a shallow clone of map. + * + * @param map - a map + */ +function clone(map) { + return new Map(map); +} +exports.clone = clone; +/** + * Returns a new map containing items from the map sorted in ascending + * order. + * + * @param map - a map + * @param lessThanAlgo - a function that returns `true` if its first argument + * is less than its second argument, and `false` otherwise. + */ +function sortInAscendingOrder(map, lessThanAlgo) { + const list = new Array(...map); + list.sort((itemA, itemB) => lessThanAlgo.call(null, itemA, itemB) ? -1 : 1); + return new Map(list); +} +exports.sortInAscendingOrder = sortInAscendingOrder; +/** + * Returns a new map containing items from the map sorted in descending + * order. + * + * @param map - a map + * @param lessThanAlgo - a function that returns `true` if its first argument + * is less than its second argument, and `false` otherwise. + */ +function sortInDescendingOrder(map, lessThanAlgo) { + const list = new Array(...map); + list.sort((itemA, itemB) => lessThanAlgo.call(null, itemA, itemB) ? 1 : -1); + return new Map(list); +} +exports.sortInDescendingOrder = sortInDescendingOrder; +//# sourceMappingURL=Map.js.map + +/***/ }), + +/***/ 487: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const interfaces_1 = __webpack_require__(970); +/** + * Represents an object which can be used to iterate through the nodes + * of a subtree. + */ +class TraverserImpl { + /** + * Initializes a new instance of `Traverser`. + * + * @param root - root node + */ + constructor(root) { + this._activeFlag = false; + this._root = root; + this._whatToShow = interfaces_1.WhatToShow.All; + this._filter = null; + } + /** @inheritdoc */ + get root() { return this._root; } + /** @inheritdoc */ + get whatToShow() { return this._whatToShow; } + /** @inheritdoc */ + get filter() { return this._filter; } +} +exports.TraverserImpl = TraverserImpl; +//# sourceMappingURL=TraverserImpl.js.map + +/***/ }), + +/***/ 488: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const _1 = __webpack_require__(113); +const interfaces_1 = __webpack_require__(970); +const DOMException_1 = __webpack_require__(35); +const NodeImpl_1 = __webpack_require__(935); +const util_1 = __webpack_require__(918); +const util_2 = __webpack_require__(337); +const infra_1 = __webpack_require__(23); +const URLAlgorithm_1 = __webpack_require__(813); +const algorithm_1 = __webpack_require__(163); +const WebIDLAlgorithm_1 = __webpack_require__(495); +/** + * Represents a document node. + */ +class DocumentImpl extends NodeImpl_1.NodeImpl { + /** + * Initializes a new instance of `Document`. + */ + constructor() { + super(); + this._children = new Set(); + this._encoding = { + name: "UTF-8", + labels: ["unicode-1-1-utf-8", "utf-8", "utf8"] + }; + this._contentType = 'application/xml'; + this._URL = { + scheme: "about", + username: "", + password: "", + host: null, + port: null, + path: ["blank"], + query: null, + fragment: null, + _cannotBeABaseURLFlag: true, + _blobURLEntry: null + }; + this._origin = null; + this._type = "xml"; + this._mode = "no-quirks"; + this._documentElement = null; + this._hasNamespaces = false; + this._nodeDocumentOverwrite = null; + } + get _nodeDocument() { return this._nodeDocumentOverwrite || this; } + set _nodeDocument(val) { this._nodeDocumentOverwrite = val; } + /** @inheritdoc */ + get implementation() { + /** + * The implementation attribute’s getter must return the DOMImplementation + * object that is associated with the document. + */ + return this._implementation || (this._implementation = algorithm_1.create_domImplementation(this)); + } + /** @inheritdoc */ + get URL() { + /** + * The URL attribute’s getter and documentURI attribute’s getter must return + * the URL, serialized. + * See: https://url.spec.whatwg.org/#concept-url-serializer + */ + return URLAlgorithm_1.urlSerializer(this._URL); + } + /** @inheritdoc */ + get documentURI() { return this.URL; } + /** @inheritdoc */ + get origin() { + return "null"; + } + /** @inheritdoc */ + get compatMode() { + /** + * The compatMode attribute’s getter must return "BackCompat" if context + * object’s mode is "quirks", and "CSS1Compat" otherwise. + */ + return this._mode === "quirks" ? "BackCompat" : "CSS1Compat"; + } + /** @inheritdoc */ + get characterSet() { + /** + * The characterSet attribute’s getter, charset attribute’s getter, and + * inputEncoding attribute’s getter, must return context object’s + * encoding’s name. + */ + return this._encoding.name; + } + /** @inheritdoc */ + get charset() { return this._encoding.name; } + /** @inheritdoc */ + get inputEncoding() { return this._encoding.name; } + /** @inheritdoc */ + get contentType() { + /** + * The contentType attribute’s getter must return the content type. + */ + return this._contentType; + } + /** @inheritdoc */ + get doctype() { + /** + * The doctype attribute’s getter must return the child of the document + * that is a doctype, and null otherwise. + */ + for (const child of this._children) { + if (util_1.Guard.isDocumentTypeNode(child)) + return child; + } + return null; + } + /** @inheritdoc */ + get documentElement() { + /** + * The documentElement attribute’s getter must return the document element. + */ + return this._documentElement; + } + /** @inheritdoc */ + getElementsByTagName(qualifiedName) { + /** + * The getElementsByTagName(qualifiedName) method, when invoked, must return + * the list of elements with qualified name qualifiedName for the context object. + */ + return algorithm_1.node_listOfElementsWithQualifiedName(qualifiedName, this); + } + /** @inheritdoc */ + getElementsByTagNameNS(namespace, localName) { + /** + * The getElementsByTagNameNS(namespace, localName) method, when invoked, + * must return the list of elements with namespace namespace and local name + * localName for the context object. + */ + return algorithm_1.node_listOfElementsWithNamespace(namespace, localName, this); + } + /** @inheritdoc */ + getElementsByClassName(classNames) { + /** + * The getElementsByClassName(classNames) method, when invoked, must return + * the list of elements with class names classNames for the context object. + */ + return algorithm_1.node_listOfElementsWithClassNames(classNames, this); + } + /** @inheritdoc */ + createElement(localName, options) { + /** + * 1. If localName does not match the Name production, then throw an + * "InvalidCharacterError" DOMException. + * 2. If the context object is an HTML document, then set localName to + * localName in ASCII lowercase. + * 3. Let is be null. + * 4. If options is a dictionary and options’s is is present, then set is + * to it. + * 5. Let namespace be the HTML namespace, if the context object is an + * HTML document or context object’s content type is + * "application/xhtml+xml", and null otherwise. + * 6. Return the result of creating an element given the context object, + * localName, namespace, null, is, and with the synchronous custom elements + * flag set. + */ + if (!algorithm_1.xml_isName(localName)) + throw new DOMException_1.InvalidCharacterError(); + if (this._type === "html") + localName = localName.toLowerCase(); + let is = null; + if (options !== undefined) { + if (util_2.isString(options)) { + is = options; + } + else { + is = options.is; + } + } + const namespace = (this._type === "html" || this._contentType === "application/xhtml+xml") ? + infra_1.namespace.HTML : null; + return algorithm_1.element_createAnElement(this, localName, namespace, null, is, true); + } + /** @inheritdoc */ + createElementNS(namespace, qualifiedName, options) { + /** + * The createElementNS(namespace, qualifiedName, options) method, when + * invoked, must return the result of running the internal createElementNS + * steps, given context object, namespace, qualifiedName, and options. + */ + return algorithm_1.document_internalCreateElementNS(this, namespace, qualifiedName, options); + } + /** @inheritdoc */ + createDocumentFragment() { + /** + * The createDocumentFragment() method, when invoked, must return a new + * DocumentFragment node with its node document set to the context object. + */ + return algorithm_1.create_documentFragment(this); + } + /** @inheritdoc */ + createTextNode(data) { + /** + * The createTextNode(data) method, when invoked, must return a new Text + * node with its data set to data and node document set to the context object. + */ + return algorithm_1.create_text(this, data); + } + /** @inheritdoc */ + createCDATASection(data) { + /** + * 1. If context object is an HTML document, then throw a + * "NotSupportedError" DOMException. + * 2. If data contains the string "]]>", then throw an + * "InvalidCharacterError" DOMException. + * 3. Return a new CDATASection node with its data set to data and node + * document set to the context object. + */ + if (this._type === "html") + throw new DOMException_1.NotSupportedError(); + if (data.indexOf(']]>') !== -1) + throw new DOMException_1.InvalidCharacterError(); + return algorithm_1.create_cdataSection(this, data); + } + /** @inheritdoc */ + createComment(data) { + /** + * The createComment(data) method, when invoked, must return a new Comment + * node with its data set to data and node document set to the context object. + */ + return algorithm_1.create_comment(this, data); + } + /** @inheritdoc */ + createProcessingInstruction(target, data) { + /** + * 1. If target does not match the Name production, then throw an + * "InvalidCharacterError" DOMException. + * 2. If data contains the string "?>", then throw an + * "InvalidCharacterError" DOMException. + * 3. Return a new ProcessingInstruction node, with target set to target, + * data set to data, and node document set to the context object. + */ + if (!algorithm_1.xml_isName(target)) + throw new DOMException_1.InvalidCharacterError(); + if (data.indexOf("?>") !== -1) + throw new DOMException_1.InvalidCharacterError(); + return algorithm_1.create_processingInstruction(this, target, data); + } + /** @inheritdoc */ + importNode(node, deep = false) { + /** + * 1. If node is a document or shadow root, then throw a "NotSupportedError" DOMException. + */ + if (util_1.Guard.isDocumentNode(node) || util_1.Guard.isShadowRoot(node)) + throw new DOMException_1.NotSupportedError(); + /** + * 2. Return a clone of node, with context object and the clone children flag set if deep is true. + */ + return algorithm_1.node_clone(node, this, deep); + } + /** @inheritdoc */ + adoptNode(node) { + /** + * 1. If node is a document, then throw a "NotSupportedError" DOMException. + */ + if (util_1.Guard.isDocumentNode(node)) + throw new DOMException_1.NotSupportedError(); + /** + * 2. If node is a shadow root, then throw a "HierarchyRequestError" DOMException. + */ + if (util_1.Guard.isShadowRoot(node)) + throw new DOMException_1.HierarchyRequestError(); + /** + * 3. Adopt node into the context object. + * 4. Return node. + */ + algorithm_1.document_adopt(node, this); + return node; + } + /** @inheritdoc */ + createAttribute(localName) { + /** + * 1. If localName does not match the Name production in XML, then throw + * an "InvalidCharacterError" DOMException. + * 2. If the context object is an HTML document, then set localName to + * localName in ASCII lowercase. + * 3. Return a new attribute whose local name is localName and node document + * is context object. + */ + if (!algorithm_1.xml_isName(localName)) + throw new DOMException_1.InvalidCharacterError(); + if (this._type === "html") { + localName = localName.toLowerCase(); + } + const attr = algorithm_1.create_attr(this, localName); + return attr; + } + /** @inheritdoc */ + createAttributeNS(namespace, qualifiedName) { + /** + * 1. Let namespace, prefix, and localName be the result of passing + * namespace and qualifiedName to validate and extract. + * 2. Return a new attribute whose namespace is namespace, namespace prefix + * is prefix, local name is localName, and node document is context object. + */ + const [ns, prefix, localName] = algorithm_1.namespace_validateAndExtract(namespace, qualifiedName); + const attr = algorithm_1.create_attr(this, localName); + attr._namespace = ns; + attr._namespacePrefix = prefix; + return attr; + } + /** @inheritdoc */ + createEvent(eventInterface) { + return algorithm_1.event_createLegacyEvent(eventInterface); + } + /** @inheritdoc */ + createRange() { + /** + * The createRange() method, when invoked, must return a new live range + * with (context object, 0) as its start and end. + */ + const range = algorithm_1.create_range(); + range._start = [this, 0]; + range._end = [this, 0]; + return range; + } + /** @inheritdoc */ + createNodeIterator(root, whatToShow = interfaces_1.WhatToShow.All, filter = null) { + /** + * 1. Let iterator be a new NodeIterator object. + * 2. Set iterator’s root and iterator’s reference to root. + * 3. Set iterator’s pointer before reference to true. + * 4. Set iterator’s whatToShow to whatToShow. + * 5. Set iterator’s filter to filter. + * 6. Return iterator. + */ + const iterator = algorithm_1.create_nodeIterator(root, root, true); + iterator._whatToShow = whatToShow; + iterator._iteratorCollection = algorithm_1.create_nodeList(root); + if (util_2.isFunction(filter)) { + iterator._filter = algorithm_1.create_nodeFilter(); + iterator._filter.acceptNode = filter; + } + else { + iterator._filter = filter; + } + return iterator; + } + /** @inheritdoc */ + createTreeWalker(root, whatToShow = interfaces_1.WhatToShow.All, filter = null) { + /** + * 1. Let walker be a new TreeWalker object. + * 2. Set walker’s root and walker’s current to root. + * 3. Set walker’s whatToShow to whatToShow. + * 4. Set walker’s filter to filter. + * 5. Return walker. + */ + const walker = algorithm_1.create_treeWalker(root, root); + walker._whatToShow = whatToShow; + if (util_2.isFunction(filter)) { + walker._filter = algorithm_1.create_nodeFilter(); + walker._filter.acceptNode = filter; + } + else { + walker._filter = filter; + } + return walker; + } + /** + * Gets the parent event target for the given event. + * + * @param event - an event + */ + _getTheParent(event) { + /** + * TODO: Implement realms + * A document’s get the parent algorithm, given an event, returns null if + * event’s type attribute value is "load" or document does not have a + * browsing context, and the document’s relevant global object otherwise. + */ + if (event._type === "load") { + return null; + } + else { + return _1.dom.window; + } + } + // MIXIN: NonElementParentNode + /* istanbul ignore next */ + getElementById(elementId) { throw new Error("Mixin: NonElementParentNode not implemented."); } + // MIXIN: DocumentOrShadowRoot + // No elements + // MIXIN: ParentNode + /* istanbul ignore next */ + get children() { throw new Error("Mixin: ParentNode not implemented."); } + /* istanbul ignore next */ + get firstElementChild() { throw new Error("Mixin: ParentNode not implemented."); } + /* istanbul ignore next */ + get lastElementChild() { throw new Error("Mixin: ParentNode not implemented."); } + /* istanbul ignore next */ + get childElementCount() { throw new Error("Mixin: ParentNode not implemented."); } + /* istanbul ignore next */ + prepend(...nodes) { throw new Error("Mixin: ParentNode not implemented."); } + /* istanbul ignore next */ + append(...nodes) { throw new Error("Mixin: ParentNode not implemented."); } + /* istanbul ignore next */ + querySelector(selectors) { throw new Error("Mixin: ParentNode not implemented."); } + /* istanbul ignore next */ + querySelectorAll(selectors) { throw new Error("Mixin: ParentNode not implemented."); } +} +exports.DocumentImpl = DocumentImpl; +/** + * Initialize prototype properties + */ +WebIDLAlgorithm_1.idl_defineConst(DocumentImpl.prototype, "_nodeType", interfaces_1.NodeType.Document); +//# sourceMappingURL=DocumentImpl.js.map + +/***/ }), + +/***/ 493: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const dom_1 = __webpack_require__(113); +const util_1 = __webpack_require__(918); +const util_2 = __webpack_require__(337); +const ElementImpl_1 = __webpack_require__(695); +const CustomElementAlgorithm_1 = __webpack_require__(344); +const TreeAlgorithm_1 = __webpack_require__(873); +const NamespaceAlgorithm_1 = __webpack_require__(664); +const DOMAlgorithm_1 = __webpack_require__(304); +const ElementAlgorithm_1 = __webpack_require__(33); +const MutationAlgorithm_1 = __webpack_require__(479); +/** + * Returns an element interface for the given name and namespace. + * + * @param name - element name + * @param namespace - namespace + */ +function document_elementInterface(name, namespace) { + return ElementImpl_1.ElementImpl; +} +exports.document_elementInterface = document_elementInterface; +/** + * Creates a new element node. + * See: https://dom.spec.whatwg.org/#internal-createelementns-steps + * + * @param document - owner document + * @param namespace - element namespace + * @param qualifiedName - qualified name + * @param options - element options + */ +function document_internalCreateElementNS(document, namespace, qualifiedName, options) { + /** + * 1. Let namespace, prefix, and localName be the result of passing + * namespace and qualifiedName to validate and extract. + * 2. Let is be null. + * 3. If options is a dictionary and options’s is is present, then set + * is to it. + * 4. Return the result of creating an element given document, localName, + * namespace, prefix, is, and with the synchronous custom elements flag set. + */ + const [ns, prefix, localName] = NamespaceAlgorithm_1.namespace_validateAndExtract(namespace, qualifiedName); + let is = null; + if (options !== undefined) { + if (util_2.isString(options)) { + is = options; + } + else { + is = options.is; + } + } + return ElementAlgorithm_1.element_createAnElement(document, localName, ns, prefix, is, true); +} +exports.document_internalCreateElementNS = document_internalCreateElementNS; +/** + * Removes `node` and its subtree from its document and changes + * its owner document to `document` so that it can be inserted + * into `document`. + * + * @param node - the node to move + * @param document - document to receive the node and its subtree + */ +function document_adopt(node, document) { + // Optimize for common case of inserting a fresh node + if (node._nodeDocument === document && node._parent === null) { + return; + } + /** + * 1. Let oldDocument be node’s node document. + * 2. If node’s parent is not null, remove node from its parent. + */ + const oldDocument = node._nodeDocument; + if (node._parent) + MutationAlgorithm_1.mutation_remove(node, node._parent); + /** + * 3. If document is not oldDocument, then: + */ + if (document !== oldDocument) { + /** + * 3.1. For each inclusiveDescendant in node’s shadow-including inclusive + * descendants: + */ + let inclusiveDescendant = TreeAlgorithm_1.tree_getFirstDescendantNode(node, true, true); + while (inclusiveDescendant !== null) { + /** + * 3.1.1. Set inclusiveDescendant’s node document to document. + * 3.1.2. If inclusiveDescendant is an element, then set the node + * document of each attribute in inclusiveDescendant’s attribute list + * to document. + */ + inclusiveDescendant._nodeDocument = document; + if (util_1.Guard.isElementNode(inclusiveDescendant)) { + for (const attr of inclusiveDescendant._attributeList._asArray()) { + attr._nodeDocument = document; + } + } + /** + * 3.2. For each inclusiveDescendant in node's shadow-including + * inclusive descendants that is custom, enqueue a custom + * element callback reaction with inclusiveDescendant, + * callback name "adoptedCallback", and an argument list + * containing oldDocument and document. + */ + if (dom_1.dom.features.customElements) { + if (util_1.Guard.isElementNode(inclusiveDescendant) && + inclusiveDescendant._customElementState === "custom") { + CustomElementAlgorithm_1.customElement_enqueueACustomElementCallbackReaction(inclusiveDescendant, "adoptedCallback", [oldDocument, document]); + } + } + /** + * 3.3. For each inclusiveDescendant in node’s shadow-including + * inclusive descendants, in shadow-including tree order, run the + * adopting steps with inclusiveDescendant and oldDocument. + */ + if (dom_1.dom.features.steps) { + DOMAlgorithm_1.dom_runAdoptingSteps(inclusiveDescendant, oldDocument); + } + inclusiveDescendant = TreeAlgorithm_1.tree_getNextDescendantNode(node, inclusiveDescendant, true, true); + } + } +} +exports.document_adopt = document_adopt; +//# sourceMappingURL=DocumentAlgorithm.js.map + +/***/ }), + +/***/ 495: +/***/ (function(__unusedmodule, exports) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * Defines a WebIDL `Const` property on the given object. + * + * @param o - object on which to add the property + * @param name - property name + * @param value - property value + */ +function idl_defineConst(o, name, value) { + Object.defineProperty(o, name, { writable: false, enumerable: true, configurable: false, value: value }); +} +exports.idl_defineConst = idl_defineConst; +//# sourceMappingURL=WebIDLAlgorithm.js.map + +/***/ }), + +/***/ 496: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const util_1 = __webpack_require__(68); +/** + * Adds the given item to the end of the set. + * + * @param set - a set + * @param item - an item + */ +function append(set, item) { + set.add(item); +} +exports.append = append; +/** + * Extends a set by appending all items from another set. + * + * @param setA - a list to extend + * @param setB - a list containing items to append to `setA` + */ +function extend(setA, setB) { + setB.forEach(setA.add, setA); +} +exports.extend = extend; +/** + * Inserts the given item to the start of the set. + * + * @param set - a set + * @param item - an item + */ +function prepend(set, item) { + const cloned = new Set(set); + set.clear(); + set.add(item); + cloned.forEach(set.add, set); +} +exports.prepend = prepend; +/** + * Replaces the given item or all items matching condition with a new item. + * + * @param set - a set + * @param conditionOrItem - an item to replace or a condition matching items + * to replace + * @param item - an item + */ +function replace(set, conditionOrItem, newItem) { + const newSet = new Set(); + for (const oldItem of set) { + if (util_1.isFunction(conditionOrItem)) { + if (!!conditionOrItem.call(null, oldItem)) { + newSet.add(newItem); + } + else { + newSet.add(oldItem); + } + } + else if (oldItem === conditionOrItem) { + newSet.add(newItem); + } + else { + newSet.add(oldItem); + } + } + set.clear(); + newSet.forEach(set.add, set); +} +exports.replace = replace; +/** + * Inserts the given item before the given index. + * + * @param set - a set + * @param item - an item + */ +function insert(set, item, index) { + const newSet = new Set(); + let i = 0; + for (const oldItem of set) { + if (i === index) + newSet.add(item); + newSet.add(oldItem); + i++; + } + set.clear(); + newSet.forEach(set.add, set); +} +exports.insert = insert; +/** + * Removes the given item or all items matching condition. + * + * @param set - a set + * @param conditionOrItem - an item to remove or a condition matching items + * to remove + */ +function remove(set, conditionOrItem) { + if (!util_1.isFunction(conditionOrItem)) { + set.delete(conditionOrItem); + } + else { + const toRemove = []; + for (const item of set) { + if (!!conditionOrItem.call(null, item)) { + toRemove.push(item); + } + } + for (const oldItem of toRemove) { + set.delete(oldItem); + } + } +} +exports.remove = remove; +/** + * Removes all items from the set. + */ +function empty(set) { + set.clear(); +} +exports.empty = empty; +/** + * Determines if the set contains the given item or any items matching + * condition. + * + * @param set - a set + * @param conditionOrItem - an item to a condition to match + */ +function contains(set, conditionOrItem) { + if (!util_1.isFunction(conditionOrItem)) { + return set.has(conditionOrItem); + } + else { + for (const oldItem of set) { + if (!!conditionOrItem.call(null, oldItem)) { + return true; + } + } + } + return false; +} +exports.contains = contains; +/** + * Returns the count of items in the set matching the given condition. + * + * @param set - a set + * @param condition - an optional condition to match + */ +function size(set, condition) { + if (condition === undefined) { + return set.size; + } + else { + let count = 0; + for (const item of set) { + if (!!condition.call(null, item)) { + count++; + } + } + return count; + } +} +exports.size = size; +/** + * Determines if the set is empty. + * + * @param set - a set + */ +function isEmpty(set) { + return set.size === 0; +} +exports.isEmpty = isEmpty; +/** + * Returns an iterator for the items of the set. + * + * @param set - a set + * @param condition - an optional condition to match + */ +function* forEach(set, condition) { + if (condition === undefined) { + yield* set; + } + else { + for (const item of set) { + if (!!condition.call(null, item)) { + yield item; + } + } + } +} +exports.forEach = forEach; +/** + * Creates and returns a shallow clone of set. + * + * @param set - a set + */ +function clone(set) { + return new Set(set); +} +exports.clone = clone; +/** + * Returns a new set containing items from the set sorted in ascending + * order. + * + * @param set - a set + * @param lessThanAlgo - a function that returns `true` if its first argument + * is less than its second argument, and `false` otherwise. + */ +function sortInAscendingOrder(set, lessThanAlgo) { + const list = new Array(...set); + list.sort((itemA, itemB) => lessThanAlgo.call(null, itemA, itemB) ? -1 : 1); + return new Set(list); +} +exports.sortInAscendingOrder = sortInAscendingOrder; +/** + * Returns a new set containing items from the set sorted in descending + * order. + * + * @param set - a set + * @param lessThanAlgo - a function that returns `true` if its first argument + * is less than its second argument, and `false` otherwise. + */ +function sortInDescendingOrder(set, lessThanAlgo) { + const list = new Array(...set); + list.sort((itemA, itemB) => lessThanAlgo.call(null, itemA, itemB) ? 1 : -1); + return new Set(list); +} +exports.sortInDescendingOrder = sortInDescendingOrder; +/** + * Determines if a set is a subset of another set. + * + * @param subset - a set + * @param superset - a superset possibly containing all items from `subset`. + */ +function isSubsetOf(subset, superset) { + for (const item of subset) { + if (!superset.has(item)) + return false; + } + return true; +} +exports.isSubsetOf = isSubsetOf; +/** + * Determines if a set is a superset of another set. + * + * @param superset - a set + * @param subset - a subset possibly contained within `superset`. + */ +function isSupersetOf(superset, subset) { + return isSubsetOf(subset, superset); +} +exports.isSupersetOf = isSupersetOf; +/** + * Returns a new set with items that are contained in both sets. + * + * @param setA - a set + * @param setB - a set + */ +function intersection(setA, setB) { + const newSet = new Set(); + for (const item of setA) { + if (setB.has(item)) + newSet.add(item); + } + return newSet; +} +exports.intersection = intersection; +/** + * Returns a new set with items from both sets. + * + * @param setA - a set + * @param setB - a set + */ +function union(setA, setB) { + const newSet = new Set(setA); + setB.forEach(newSet.add, newSet); + return newSet; +} +exports.union = union; +/** + * Returns a set of integers from `n` to `m` inclusive. + * + * @param n - starting number + * @param m - ending number + */ +function range(n, m) { + const newSet = new Set(); + for (let i = n; i <= m; i++) { + newSet.add(i); + } + return newSet; +} +exports.range = range; +//# sourceMappingURL=Set.js.map + +/***/ }), + +/***/ 501: +/***/ (function(__unusedmodule, exports) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * Appends the given item to the queue. + * + * @param list - a list + * @param item - an item + */ +function enqueue(list, item) { + list.push(item); +} +exports.enqueue = enqueue; +/** + * Removes and returns an item from the queue. + * + * @param list - a list + */ +function dequeue(list) { + return list.shift() || null; +} +exports.dequeue = dequeue; +//# sourceMappingURL=Queue.js.map + +/***/ }), + +/***/ 512: +/***/ (function(__unusedmodule, exports) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * Pre-serializes XML nodes. + */ +class BaseCBWriter { + /** + * Initializes a new instance of `BaseCBWriter`. + * + * @param builderOptions - XML builder options + */ + constructor(builderOptions) { + /** + * Gets the current depth of the XML tree. + */ + this.level = 0; + this._builderOptions = builderOptions; + this._writerOptions = builderOptions; + } +} +exports.BaseCBWriter = BaseCBWriter; +//# sourceMappingURL=BaseCBWriter.js.map + +/***/ }), + +/***/ 522: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const util_1 = __webpack_require__(68); +/** + * Parses the given byte sequence representing a JSON string into an object. + * + * @param bytes - a byte sequence + */ +function parseJSONFromBytes(bytes) { + /** + * 1. Let jsonText be the result of running UTF-8 decode on bytes. [ENCODING] + * 2. Return ? Call(%JSONParse%, undefined, « jsonText »). + */ + const jsonText = util_1.utf8Decode(bytes); + return JSON.parse.call(undefined, jsonText); +} +exports.parseJSONFromBytes = parseJSONFromBytes; +/** + * Serialize the given JavaScript value into a byte sequence. + * + * @param value - a JavaScript value + */ +function serializeJSONToBytes(value) { + /** + * 1. Let jsonString be ? Call(%JSONStringify%, undefined, « value »). + * 2. Return the result of running UTF-8 encode on jsonString. [ENCODING] + */ + const jsonString = JSON.stringify.call(undefined, value); + return util_1.utf8Encode(jsonString); +} +exports.serializeJSONToBytes = serializeJSONToBytes; +/** + * Parses the given JSON string into a Realm-independent JavaScript value. + * + * @param jsonText - a JSON string + */ +function parseJSONIntoInfraValues(jsonText) { + /** + * 1. Let jsValue be ? Call(%JSONParse%, undefined, « jsonText »). + * 2. Return the result of converting a JSON-derived JavaScript value to an + * Infra value, given jsValue. + */ + const jsValue = JSON.parse.call(undefined, jsonText); + return convertAJSONDerivedJavaScriptValueToAnInfraValue(jsValue); +} +exports.parseJSONIntoInfraValues = parseJSONIntoInfraValues; +/** + * Parses the value into a Realm-independent JavaScript value. + * + * @param jsValue - a JavaScript value + */ +function convertAJSONDerivedJavaScriptValueToAnInfraValue(jsValue) { + /** + * 1. If Type(jsValue) is Null, String, or Number, then return jsValue. + */ + if (jsValue === null || util_1.isString(jsValue) || util_1.isNumber(jsValue)) + return jsValue; + /** + * 2. If IsArray(jsValue) is true, then: + * 2.1. Let result be an empty list. + * 2.2. Let length be ! ToLength(! Get(jsValue, "length")). + * 2.3. For each index of the range 0 to length − 1, inclusive: + * 2.3.1. Let indexName be ! ToString(index). + * 2.3.2. Let jsValueAtIndex be ! Get(jsValue, indexName). + * 2.3.3. Let infraValueAtIndex be the result of converting a JSON-derived + * JavaScript value to an Infra value, given jsValueAtIndex. + * 2.3.4. Append infraValueAtIndex to result. + * 2.8. Return result. + */ + if (util_1.isArray(jsValue)) { + const result = new Array(); + for (const jsValueAtIndex of jsValue) { + result.push(convertAJSONDerivedJavaScriptValueToAnInfraValue(jsValueAtIndex)); + } + return result; + } + else if (util_1.isObject(jsValue)) { + /** + * 3. Let result be an empty ordered map. + * 4. For each key of ! jsValue.[[OwnPropertyKeys]](): + * 4.1. Let jsValueAtKey be ! Get(jsValue, key). + * 4.2. Let infraValueAtKey be the result of converting a JSON-derived + * JavaScript value to an Infra value, given jsValueAtKey. + * 4.3. Set result[key] to infraValueAtKey. + * 5. Return result. + */ + const result = new Map(); + for (const key in jsValue) { + /* istanbul ignore else */ + if (jsValue.hasOwnProperty(key)) { + const jsValueAtKey = jsValue[key]; + result.set(key, convertAJSONDerivedJavaScriptValueToAnInfraValue(jsValueAtKey)); + } + } + return result; + } + /* istanbul ignore next */ + return jsValue; +} +exports.convertAJSONDerivedJavaScriptValueToAnInfraValue = convertAJSONDerivedJavaScriptValueToAnInfraValue; +//# sourceMappingURL=JSON.js.map + +/***/ }), + +/***/ 524: +/***/ (function(__unusedmodule, exports) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * Represents a cache for storing order between equal objects. + * + * This cache is used when an algorithm compares two objects and finds them to + * be equal but still needs to establish an order between those two objects. + * When two such objects `a` and `b` are passed to the `check` method, a random + * number is generated with `Math.random()`. If the random number is less than + * `0.5` it is assumed that `a < b` otherwise `a > b`. The random number along + * with `a` and `b` is stored in the cache, so that subsequent checks result + * in the same consistent result. + * + * The cache has a size limit which is defined on initialization. + */ +class CompareCache { + /** + * Initializes a new instance of `CompareCache`. + * + * @param limit - maximum number of items to keep in the cache. When the limit + * is exceeded the first item is removed from the cache. + */ + constructor(limit = 1000) { + this._items = new Map(); + this._limit = limit; + } + /** + * Compares and caches the given objects. Returns `true` if `objA < objB` and + * `false` otherwise. + * + * @param objA - an item to compare + * @param objB - an item to compare + */ + check(objA, objB) { + if (this._items.get(objA) === objB) + return true; + else if (this._items.get(objB) === objA) + return false; + const result = (Math.random() < 0.5); + if (result) { + this._items.set(objA, objB); + } + else { + this._items.set(objB, objA); + } + if (this._items.size > this._limit) { + const it = this._items.keys().next(); + /* istanbul ignore else */ + if (!it.done) { + this._items.delete(it.value); + } + } + return result; + } +} +exports.CompareCache = CompareCache; +//# sourceMappingURL=CompareCache.js.map + +/***/ }), + +/***/ 533: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result["default"] = mod; + return result; +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const core = __importStar(__webpack_require__(470)); +const io = __importStar(__webpack_require__(1)); +const fs = __importStar(__webpack_require__(747)); +const os = __importStar(__webpack_require__(87)); +const path = __importStar(__webpack_require__(622)); +const httpm = __importStar(__webpack_require__(539)); +const semver = __importStar(__webpack_require__(280)); +const v4_1 = __importDefault(__webpack_require__(826)); +const exec_1 = __webpack_require__(986); +const assert_1 = __webpack_require__(357); +class HTTPError extends Error { + constructor(httpStatusCode) { + super(`Unexpected HTTP response: ${httpStatusCode}`); + this.httpStatusCode = httpStatusCode; + Object.setPrototypeOf(this, new.target.prototype); + } +} +exports.HTTPError = HTTPError; +const IS_WINDOWS = process.platform === 'win32'; +const userAgent = 'actions/tool-cache'; +// On load grab temp directory and cache directory and remove them from env (currently don't want to expose this) +let tempDirectory = process.env['RUNNER_TEMP'] || ''; +let cacheRoot = process.env['RUNNER_TOOL_CACHE'] || ''; +// If directories not found, place them in common temp locations +if (!tempDirectory || !cacheRoot) { + let baseLocation; + if (IS_WINDOWS) { + // On windows use the USERPROFILE env variable + baseLocation = process.env['USERPROFILE'] || 'C:\\'; + } + else { + if (process.platform === 'darwin') { + baseLocation = '/Users'; + } + else { + baseLocation = '/home'; + } + } + if (!tempDirectory) { + tempDirectory = path.join(baseLocation, 'actions', 'temp'); + } + if (!cacheRoot) { + cacheRoot = path.join(baseLocation, 'actions', 'cache'); + } +} +/** + * Download a tool from an url and stream it into a file + * + * @param url url of tool to download + * @param dest path to download tool + * @returns path to downloaded tool + */ +function downloadTool(url, dest) { + return __awaiter(this, void 0, void 0, function* () { + // Wrap in a promise so that we can resolve from within stream callbacks + return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () { + try { + const http = new httpm.HttpClient(userAgent, [], { + allowRetries: true, + maxRetries: 3 + }); + dest = dest || path.join(tempDirectory, v4_1.default()); + yield io.mkdirP(path.dirname(dest)); + core.debug(`Downloading ${url}`); + core.debug(`Downloading ${dest}`); + if (fs.existsSync(dest)) { + throw new Error(`Destination file path ${dest} already exists`); + } + const response = yield http.get(url); + if (response.message.statusCode !== 200) { + const err = new HTTPError(response.message.statusCode); + core.debug(`Failed to download from "${url}". Code(${response.message.statusCode}) Message(${response.message.statusMessage})`); + throw err; + } + const file = fs.createWriteStream(dest); + file.on('open', () => __awaiter(this, void 0, void 0, function* () { + try { + const stream = response.message.pipe(file); + stream.on('close', () => { + core.debug('download complete'); + resolve(dest); + }); + } + catch (err) { + core.debug(`Failed to download from "${url}". Code(${response.message.statusCode}) Message(${response.message.statusMessage})`); + reject(err); + } + })); + file.on('error', err => { + file.end(); + reject(err); + }); + } + catch (err) { + reject(err); + } + })); + }); +} +exports.downloadTool = downloadTool; +/** + * Extract a .7z file + * + * @param file path to the .7z file + * @param dest destination directory. Optional. + * @param _7zPath path to 7zr.exe. Optional, for long path support. Most .7z archives do not have this + * problem. If your .7z archive contains very long paths, you can pass the path to 7zr.exe which will + * gracefully handle long paths. By default 7zdec.exe is used because it is a very small program and is + * bundled with the tool lib. However it does not support long paths. 7zr.exe is the reduced command line + * interface, it is smaller than the full command line interface, and it does support long paths. At the + * time of this writing, it is freely available from the LZMA SDK that is available on the 7zip website. + * Be sure to check the current license agreement. If 7zr.exe is bundled with your action, then the path + * to 7zr.exe can be pass to this function. + * @returns path to the destination directory + */ +function extract7z(file, dest, _7zPath) { + return __awaiter(this, void 0, void 0, function* () { + assert_1.ok(IS_WINDOWS, 'extract7z() not supported on current OS'); + assert_1.ok(file, 'parameter "file" is required'); + dest = yield _createExtractFolder(dest); + const originalCwd = process.cwd(); + process.chdir(dest); + if (_7zPath) { + try { + const args = [ + 'x', + '-bb1', + '-bd', + '-sccUTF-8', + file + ]; + const options = { + silent: true + }; + yield exec_1.exec(`"${_7zPath}"`, args, options); + } + finally { + process.chdir(originalCwd); + } + } + else { + const escapedScript = path + .join(__dirname, '..', 'scripts', 'Invoke-7zdec.ps1') + .replace(/'/g, "''") + .replace(/"|\n|\r/g, ''); // double-up single quotes, remove double quotes and newlines + const escapedFile = file.replace(/'/g, "''").replace(/"|\n|\r/g, ''); + const escapedTarget = dest.replace(/'/g, "''").replace(/"|\n|\r/g, ''); + const command = `& '${escapedScript}' -Source '${escapedFile}' -Target '${escapedTarget}'`; + const args = [ + '-NoLogo', + '-Sta', + '-NoProfile', + '-NonInteractive', + '-ExecutionPolicy', + 'Unrestricted', + '-Command', + command + ]; + const options = { + silent: true + }; + try { + const powershellPath = yield io.which('powershell', true); + yield exec_1.exec(`"${powershellPath}"`, args, options); + } + finally { + process.chdir(originalCwd); + } + } + return dest; + }); +} +exports.extract7z = extract7z; +/** + * Extract a compressed tar archive + * + * @param file path to the tar + * @param dest destination directory. Optional. + * @param flags flags for the tar command to use for extraction. Defaults to 'xz' (extracting gzipped tars). Optional. + * @returns path to the destination directory + */ +function extractTar(file, dest, flags = 'xz') { + return __awaiter(this, void 0, void 0, function* () { + if (!file) { + throw new Error("parameter 'file' is required"); + } + // Create dest + dest = yield _createExtractFolder(dest); + // Determine whether GNU tar + let versionOutput = ''; + yield exec_1.exec('tar --version', [], { + ignoreReturnCode: true, + listeners: { + stdout: (data) => (versionOutput += data.toString()), + stderr: (data) => (versionOutput += data.toString()) + } + }); + const isGnuTar = versionOutput.toUpperCase().includes('GNU TAR'); + // Initialize args + const args = [flags]; + let destArg = dest; + let fileArg = file; + if (IS_WINDOWS && isGnuTar) { + args.push('--force-local'); + destArg = dest.replace(/\\/g, '/'); + // Technically only the dest needs to have `/` but for aesthetic consistency + // convert slashes in the file arg too. + fileArg = file.replace(/\\/g, '/'); + } + if (isGnuTar) { + // Suppress warnings when using GNU tar to extract archives created by BSD tar + args.push('--warning=no-unknown-keyword'); + } + args.push('-C', destArg, '-f', fileArg); + yield exec_1.exec(`tar`, args); + return dest; + }); +} +exports.extractTar = extractTar; +/** + * Extract a zip + * + * @param file path to the zip + * @param dest destination directory. Optional. + * @returns path to the destination directory + */ +function extractZip(file, dest) { + return __awaiter(this, void 0, void 0, function* () { + if (!file) { + throw new Error("parameter 'file' is required"); + } + dest = yield _createExtractFolder(dest); + if (IS_WINDOWS) { + yield extractZipWin(file, dest); + } + else { + yield extractZipNix(file, dest); + } + return dest; + }); +} +exports.extractZip = extractZip; +function extractZipWin(file, dest) { + return __awaiter(this, void 0, void 0, function* () { + // build the powershell command + const escapedFile = file.replace(/'/g, "''").replace(/"|\n|\r/g, ''); // double-up single quotes, remove double quotes and newlines + const escapedDest = dest.replace(/'/g, "''").replace(/"|\n|\r/g, ''); + const command = `$ErrorActionPreference = 'Stop' ; try { Add-Type -AssemblyName System.IO.Compression.FileSystem } catch { } ; [System.IO.Compression.ZipFile]::ExtractToDirectory('${escapedFile}', '${escapedDest}')`; + // run powershell + const powershellPath = yield io.which('powershell'); + const args = [ + '-NoLogo', + '-Sta', + '-NoProfile', + '-NonInteractive', + '-ExecutionPolicy', + 'Unrestricted', + '-Command', + command + ]; + yield exec_1.exec(`"${powershellPath}"`, args); + }); +} +function extractZipNix(file, dest) { + return __awaiter(this, void 0, void 0, function* () { + const unzipPath = yield io.which('unzip'); + yield exec_1.exec(`"${unzipPath}"`, [file], { cwd: dest }); + }); +} +/** + * Caches a directory and installs it into the tool cacheDir + * + * @param sourceDir the directory to cache into tools + * @param tool tool name + * @param version version of the tool. semver format + * @param arch architecture of the tool. Optional. Defaults to machine architecture + */ +function cacheDir(sourceDir, tool, version, arch) { + return __awaiter(this, void 0, void 0, function* () { + version = semver.clean(version) || version; + arch = arch || os.arch(); + core.debug(`Caching tool ${tool} ${version} ${arch}`); + core.debug(`source dir: ${sourceDir}`); + if (!fs.statSync(sourceDir).isDirectory()) { + throw new Error('sourceDir is not a directory'); + } + // Create the tool dir + const destPath = yield _createToolPath(tool, version, arch); + // copy each child item. do not move. move can fail on Windows + // due to anti-virus software having an open handle on a file. + for (const itemName of fs.readdirSync(sourceDir)) { + const s = path.join(sourceDir, itemName); + yield io.cp(s, destPath, { recursive: true }); + } + // write .complete + _completeToolPath(tool, version, arch); + return destPath; + }); +} +exports.cacheDir = cacheDir; +/** + * Caches a downloaded file (GUID) and installs it + * into the tool cache with a given targetName + * + * @param sourceFile the file to cache into tools. Typically a result of downloadTool which is a guid. + * @param targetFile the name of the file name in the tools directory + * @param tool tool name + * @param version version of the tool. semver format + * @param arch architecture of the tool. Optional. Defaults to machine architecture + */ +function cacheFile(sourceFile, targetFile, tool, version, arch) { + return __awaiter(this, void 0, void 0, function* () { + version = semver.clean(version) || version; + arch = arch || os.arch(); + core.debug(`Caching tool ${tool} ${version} ${arch}`); + core.debug(`source file: ${sourceFile}`); + if (!fs.statSync(sourceFile).isFile()) { + throw new Error('sourceFile is not a file'); + } + // create the tool dir + const destFolder = yield _createToolPath(tool, version, arch); + // copy instead of move. move can fail on Windows due to + // anti-virus software having an open handle on a file. + const destPath = path.join(destFolder, targetFile); + core.debug(`destination file ${destPath}`); + yield io.cp(sourceFile, destPath); + // write .complete + _completeToolPath(tool, version, arch); + return destFolder; + }); +} +exports.cacheFile = cacheFile; +/** + * Finds the path to a tool version in the local installed tool cache + * + * @param toolName name of the tool + * @param versionSpec version of the tool + * @param arch optional arch. defaults to arch of computer + */ +function find(toolName, versionSpec, arch) { + if (!toolName) { + throw new Error('toolName parameter is required'); + } + if (!versionSpec) { + throw new Error('versionSpec parameter is required'); + } + arch = arch || os.arch(); + // attempt to resolve an explicit version + if (!_isExplicitVersion(versionSpec)) { + const localVersions = findAllVersions(toolName, arch); + const match = _evaluateVersions(localVersions, versionSpec); + versionSpec = match; + } + // check for the explicit version in the cache + let toolPath = ''; + if (versionSpec) { + versionSpec = semver.clean(versionSpec) || ''; + const cachePath = path.join(cacheRoot, toolName, versionSpec, arch); + core.debug(`checking cache: ${cachePath}`); + if (fs.existsSync(cachePath) && fs.existsSync(`${cachePath}.complete`)) { + core.debug(`Found tool in cache ${toolName} ${versionSpec} ${arch}`); + toolPath = cachePath; + } + else { + core.debug('not found'); + } + } + return toolPath; +} +exports.find = find; +/** + * Finds the paths to all versions of a tool that are installed in the local tool cache + * + * @param toolName name of the tool + * @param arch optional arch. defaults to arch of computer + */ +function findAllVersions(toolName, arch) { + const versions = []; + arch = arch || os.arch(); + const toolPath = path.join(cacheRoot, toolName); + if (fs.existsSync(toolPath)) { + const children = fs.readdirSync(toolPath); + for (const child of children) { + if (_isExplicitVersion(child)) { + const fullPath = path.join(toolPath, child, arch || ''); + if (fs.existsSync(fullPath) && fs.existsSync(`${fullPath}.complete`)) { + versions.push(child); + } + } + } + } + return versions; +} +exports.findAllVersions = findAllVersions; +function _createExtractFolder(dest) { + return __awaiter(this, void 0, void 0, function* () { + if (!dest) { + // create a temp dir + dest = path.join(tempDirectory, v4_1.default()); + } + yield io.mkdirP(dest); + return dest; + }); +} +function _createToolPath(tool, version, arch) { + return __awaiter(this, void 0, void 0, function* () { + const folderPath = path.join(cacheRoot, tool, semver.clean(version) || version, arch || ''); + core.debug(`destination ${folderPath}`); + const markerPath = `${folderPath}.complete`; + yield io.rmRF(folderPath); + yield io.rmRF(markerPath); + yield io.mkdirP(folderPath); + return folderPath; + }); +} +function _completeToolPath(tool, version, arch) { + const folderPath = path.join(cacheRoot, tool, semver.clean(version) || version, arch || ''); + const markerPath = `${folderPath}.complete`; + fs.writeFileSync(markerPath, ''); + core.debug('finished caching tool'); +} +function _isExplicitVersion(versionSpec) { + const c = semver.clean(versionSpec) || ''; + core.debug(`isExplicit: ${c}`); + const valid = semver.valid(c) != null; + core.debug(`explicit? ${valid}`); + return valid; +} +function _evaluateVersions(versions, versionSpec) { + let version = ''; + core.debug(`evaluating ${versions.length} versions`); + versions = versions.sort((a, b) => { + if (semver.gt(a, b)) { + return 1; + } + return -1; + }); + for (let i = versions.length - 1; i >= 0; i--) { + const potential = versions[i]; + const satisfied = semver.satisfies(potential, versionSpec); + if (satisfied) { + version = potential; + break; + } + } + if (version) { + core.debug(`matched: ${version}`); + } + else { + core.debug('match not found'); + } + return version; +} +//# sourceMappingURL=tool-cache.js.map + +/***/ }), + +/***/ 535: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +var XMLBuilderImpl_1 = __webpack_require__(595); +exports.XMLBuilderImpl = XMLBuilderImpl_1.XMLBuilderImpl; +var XMLBuilderCBImpl_1 = __webpack_require__(551); +exports.XMLBuilderCBImpl = XMLBuilderCBImpl_1.XMLBuilderCBImpl; +//# sourceMappingURL=index.js.map + +/***/ }), + +/***/ 537: +/***/ (function(__unusedmodule, exports) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * Represents an abstract range with a start and end boundary point. + */ +class AbstractRangeImpl { + get _startNode() { return this._start[0]; } + get _startOffset() { return this._start[1]; } + get _endNode() { return this._end[0]; } + get _endOffset() { return this._end[1]; } + get _collapsed() { + return (this._start[0] === this._end[0] && + this._start[1] === this._end[1]); + } + /** @inheritdoc */ + get startContainer() { return this._startNode; } + /** @inheritdoc */ + get startOffset() { return this._startOffset; } + /** @inheritdoc */ + get endContainer() { return this._endNode; } + /** @inheritdoc */ + get endOffset() { return this._endOffset; } + /** @inheritdoc */ + get collapsed() { return this._collapsed; } +} +exports.AbstractRangeImpl = AbstractRangeImpl; +//# sourceMappingURL=AbstractRangeImpl.js.map + +/***/ }), + +/***/ 539: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const url = __webpack_require__(835); +const http = __webpack_require__(605); +const https = __webpack_require__(211); +const pm = __webpack_require__(950); +let tunnel; +var HttpCodes; +(function (HttpCodes) { + HttpCodes[HttpCodes["OK"] = 200] = "OK"; + HttpCodes[HttpCodes["MultipleChoices"] = 300] = "MultipleChoices"; + HttpCodes[HttpCodes["MovedPermanently"] = 301] = "MovedPermanently"; + HttpCodes[HttpCodes["ResourceMoved"] = 302] = "ResourceMoved"; + HttpCodes[HttpCodes["SeeOther"] = 303] = "SeeOther"; + HttpCodes[HttpCodes["NotModified"] = 304] = "NotModified"; + HttpCodes[HttpCodes["UseProxy"] = 305] = "UseProxy"; + HttpCodes[HttpCodes["SwitchProxy"] = 306] = "SwitchProxy"; + HttpCodes[HttpCodes["TemporaryRedirect"] = 307] = "TemporaryRedirect"; + HttpCodes[HttpCodes["PermanentRedirect"] = 308] = "PermanentRedirect"; + HttpCodes[HttpCodes["BadRequest"] = 400] = "BadRequest"; + HttpCodes[HttpCodes["Unauthorized"] = 401] = "Unauthorized"; + HttpCodes[HttpCodes["PaymentRequired"] = 402] = "PaymentRequired"; + HttpCodes[HttpCodes["Forbidden"] = 403] = "Forbidden"; + HttpCodes[HttpCodes["NotFound"] = 404] = "NotFound"; + HttpCodes[HttpCodes["MethodNotAllowed"] = 405] = "MethodNotAllowed"; + HttpCodes[HttpCodes["NotAcceptable"] = 406] = "NotAcceptable"; + HttpCodes[HttpCodes["ProxyAuthenticationRequired"] = 407] = "ProxyAuthenticationRequired"; + HttpCodes[HttpCodes["RequestTimeout"] = 408] = "RequestTimeout"; + HttpCodes[HttpCodes["Conflict"] = 409] = "Conflict"; + HttpCodes[HttpCodes["Gone"] = 410] = "Gone"; + HttpCodes[HttpCodes["InternalServerError"] = 500] = "InternalServerError"; + HttpCodes[HttpCodes["NotImplemented"] = 501] = "NotImplemented"; + HttpCodes[HttpCodes["BadGateway"] = 502] = "BadGateway"; + HttpCodes[HttpCodes["ServiceUnavailable"] = 503] = "ServiceUnavailable"; + HttpCodes[HttpCodes["GatewayTimeout"] = 504] = "GatewayTimeout"; +})(HttpCodes = exports.HttpCodes || (exports.HttpCodes = {})); +var Headers; +(function (Headers) { + Headers["Accept"] = "accept"; + Headers["ContentType"] = "content-type"; +})(Headers = exports.Headers || (exports.Headers = {})); +var MediaTypes; +(function (MediaTypes) { + MediaTypes["ApplicationJson"] = "application/json"; +})(MediaTypes = exports.MediaTypes || (exports.MediaTypes = {})); +/** + * Returns the proxy URL, depending upon the supplied url and proxy environment variables. + * @param serverUrl The server URL where the request will be sent. For example, https://api.github.com + */ +function getProxyUrl(serverUrl) { + let proxyUrl = pm.getProxyUrl(url.parse(serverUrl)); + return proxyUrl ? proxyUrl.href : ''; +} +exports.getProxyUrl = getProxyUrl; +const HttpRedirectCodes = [HttpCodes.MovedPermanently, HttpCodes.ResourceMoved, HttpCodes.SeeOther, HttpCodes.TemporaryRedirect, HttpCodes.PermanentRedirect]; +const HttpResponseRetryCodes = [HttpCodes.BadGateway, HttpCodes.ServiceUnavailable, HttpCodes.GatewayTimeout]; +const RetryableHttpVerbs = ['OPTIONS', 'GET', 'DELETE', 'HEAD']; +const ExponentialBackoffCeiling = 10; +const ExponentialBackoffTimeSlice = 5; +class HttpClientResponse { + constructor(message) { + this.message = message; + } + readBody() { + return new Promise(async (resolve, reject) => { + let output = Buffer.alloc(0); + this.message.on('data', (chunk) => { + output = Buffer.concat([output, chunk]); + }); + this.message.on('end', () => { + resolve(output.toString()); + }); + }); + } +} +exports.HttpClientResponse = HttpClientResponse; +function isHttps(requestUrl) { + let parsedUrl = url.parse(requestUrl); + return parsedUrl.protocol === 'https:'; +} +exports.isHttps = isHttps; +class HttpClient { + constructor(userAgent, handlers, requestOptions) { + this._ignoreSslError = false; + this._allowRedirects = true; + this._allowRedirectDowngrade = false; + this._maxRedirects = 50; + this._allowRetries = false; + this._maxRetries = 1; + this._keepAlive = false; + this._disposed = false; + this.userAgent = userAgent; + this.handlers = handlers || []; + this.requestOptions = requestOptions; + if (requestOptions) { + if (requestOptions.ignoreSslError != null) { + this._ignoreSslError = requestOptions.ignoreSslError; + } + this._socketTimeout = requestOptions.socketTimeout; + if (requestOptions.allowRedirects != null) { + this._allowRedirects = requestOptions.allowRedirects; + } + if (requestOptions.allowRedirectDowngrade != null) { + this._allowRedirectDowngrade = requestOptions.allowRedirectDowngrade; + } + if (requestOptions.maxRedirects != null) { + this._maxRedirects = Math.max(requestOptions.maxRedirects, 0); + } + if (requestOptions.keepAlive != null) { + this._keepAlive = requestOptions.keepAlive; + } + if (requestOptions.allowRetries != null) { + this._allowRetries = requestOptions.allowRetries; + } + if (requestOptions.maxRetries != null) { + this._maxRetries = requestOptions.maxRetries; + } + } + } + options(requestUrl, additionalHeaders) { + return this.request('OPTIONS', requestUrl, null, additionalHeaders || {}); + } + get(requestUrl, additionalHeaders) { + return this.request('GET', requestUrl, null, additionalHeaders || {}); + } + del(requestUrl, additionalHeaders) { + return this.request('DELETE', requestUrl, null, additionalHeaders || {}); + } + post(requestUrl, data, additionalHeaders) { + return this.request('POST', requestUrl, data, additionalHeaders || {}); + } + patch(requestUrl, data, additionalHeaders) { + return this.request('PATCH', requestUrl, data, additionalHeaders || {}); + } + put(requestUrl, data, additionalHeaders) { + return this.request('PUT', requestUrl, data, additionalHeaders || {}); + } + head(requestUrl, additionalHeaders) { + return this.request('HEAD', requestUrl, null, additionalHeaders || {}); + } + sendStream(verb, requestUrl, stream, additionalHeaders) { + return this.request(verb, requestUrl, stream, additionalHeaders); + } + /** + * Gets a typed object from an endpoint + * Be aware that not found returns a null. Other errors (4xx, 5xx) reject the promise + */ + async getJson(requestUrl, additionalHeaders = {}) { + additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson); + let res = await this.get(requestUrl, additionalHeaders); + return this._processResponse(res, this.requestOptions); + } + async postJson(requestUrl, obj, additionalHeaders = {}) { + let data = JSON.stringify(obj, null, 2); + additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson); + additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson); + let res = await this.post(requestUrl, data, additionalHeaders); + return this._processResponse(res, this.requestOptions); + } + async putJson(requestUrl, obj, additionalHeaders = {}) { + let data = JSON.stringify(obj, null, 2); + additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson); + additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson); + let res = await this.put(requestUrl, data, additionalHeaders); + return this._processResponse(res, this.requestOptions); + } + async patchJson(requestUrl, obj, additionalHeaders = {}) { + let data = JSON.stringify(obj, null, 2); + additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson); + additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson); + let res = await this.patch(requestUrl, data, additionalHeaders); + return this._processResponse(res, this.requestOptions); + } + /** + * Makes a raw http request. + * All other methods such as get, post, patch, and request ultimately call this. + * Prefer get, del, post and patch + */ + async request(verb, requestUrl, data, headers) { + if (this._disposed) { + throw new Error("Client has already been disposed."); + } + let parsedUrl = url.parse(requestUrl); + let info = this._prepareRequest(verb, parsedUrl, headers); + // Only perform retries on reads since writes may not be idempotent. + let maxTries = (this._allowRetries && RetryableHttpVerbs.indexOf(verb) != -1) ? this._maxRetries + 1 : 1; + let numTries = 0; + let response; + while (numTries < maxTries) { + response = await this.requestRaw(info, data); + // Check if it's an authentication challenge + if (response && response.message && response.message.statusCode === HttpCodes.Unauthorized) { + let authenticationHandler; + for (let i = 0; i < this.handlers.length; i++) { + if (this.handlers[i].canHandleAuthentication(response)) { + authenticationHandler = this.handlers[i]; + break; + } + } + if (authenticationHandler) { + return authenticationHandler.handleAuthentication(this, info, data); + } + else { + // We have received an unauthorized response but have no handlers to handle it. + // Let the response return to the caller. + return response; + } + } + let redirectsRemaining = this._maxRedirects; + while (HttpRedirectCodes.indexOf(response.message.statusCode) != -1 + && this._allowRedirects + && redirectsRemaining > 0) { + const redirectUrl = response.message.headers["location"]; + if (!redirectUrl) { + // if there's no location to redirect to, we won't + break; + } + let parsedRedirectUrl = url.parse(redirectUrl); + if (parsedUrl.protocol == 'https:' && parsedUrl.protocol != parsedRedirectUrl.protocol && !this._allowRedirectDowngrade) { + throw new Error("Redirect from HTTPS to HTTP protocol. This downgrade is not allowed for security reasons. If you want to allow this behavior, set the allowRedirectDowngrade option to true."); + } + // we need to finish reading the response before reassigning response + // which will leak the open socket. + await response.readBody(); + // let's make the request with the new redirectUrl + info = this._prepareRequest(verb, parsedRedirectUrl, headers); + response = await this.requestRaw(info, data); + redirectsRemaining--; + } + if (HttpResponseRetryCodes.indexOf(response.message.statusCode) == -1) { + // If not a retry code, return immediately instead of retrying + return response; + } + numTries += 1; + if (numTries < maxTries) { + await response.readBody(); + await this._performExponentialBackoff(numTries); + } + } + return response; + } + /** + * Needs to be called if keepAlive is set to true in request options. + */ + dispose() { + if (this._agent) { + this._agent.destroy(); + } + this._disposed = true; + } + /** + * Raw request. + * @param info + * @param data + */ + requestRaw(info, data) { + return new Promise((resolve, reject) => { + let callbackForResult = function (err, res) { + if (err) { + reject(err); + } + resolve(res); + }; + this.requestRawWithCallback(info, data, callbackForResult); + }); + } + /** + * Raw request with callback. + * @param info + * @param data + * @param onResult + */ + requestRawWithCallback(info, data, onResult) { + let socket; + if (typeof (data) === 'string') { + info.options.headers["Content-Length"] = Buffer.byteLength(data, 'utf8'); + } + let callbackCalled = false; + let handleResult = (err, res) => { + if (!callbackCalled) { + callbackCalled = true; + onResult(err, res); + } + }; + let req = info.httpModule.request(info.options, (msg) => { + let res = new HttpClientResponse(msg); + handleResult(null, res); + }); + req.on('socket', (sock) => { + socket = sock; + }); + // If we ever get disconnected, we want the socket to timeout eventually + req.setTimeout(this._socketTimeout || 3 * 60000, () => { + if (socket) { + socket.end(); + } + handleResult(new Error('Request timeout: ' + info.options.path), null); + }); + req.on('error', function (err) { + // err has statusCode property + // res should have headers + handleResult(err, null); + }); + if (data && typeof (data) === 'string') { + req.write(data, 'utf8'); + } + if (data && typeof (data) !== 'string') { + data.on('close', function () { + req.end(); + }); + data.pipe(req); + } + else { + req.end(); + } + } + /** + * Gets an http agent. This function is useful when you need an http agent that handles + * routing through a proxy server - depending upon the url and proxy environment variables. + * @param serverUrl The server URL where the request will be sent. For example, https://api.github.com + */ + getAgent(serverUrl) { + let parsedUrl = url.parse(serverUrl); + return this._getAgent(parsedUrl); + } + _prepareRequest(method, requestUrl, headers) { + const info = {}; + info.parsedUrl = requestUrl; + const usingSsl = info.parsedUrl.protocol === 'https:'; + info.httpModule = usingSsl ? https : http; + const defaultPort = usingSsl ? 443 : 80; + info.options = {}; + info.options.host = info.parsedUrl.hostname; + info.options.port = info.parsedUrl.port ? parseInt(info.parsedUrl.port) : defaultPort; + info.options.path = (info.parsedUrl.pathname || '') + (info.parsedUrl.search || ''); + info.options.method = method; + info.options.headers = this._mergeHeaders(headers); + if (this.userAgent != null) { + info.options.headers["user-agent"] = this.userAgent; + } + info.options.agent = this._getAgent(info.parsedUrl); + // gives handlers an opportunity to participate + if (this.handlers) { + this.handlers.forEach((handler) => { + handler.prepareRequest(info.options); + }); + } + return info; + } + _mergeHeaders(headers) { + const lowercaseKeys = obj => Object.keys(obj).reduce((c, k) => (c[k.toLowerCase()] = obj[k], c), {}); + if (this.requestOptions && this.requestOptions.headers) { + return Object.assign({}, lowercaseKeys(this.requestOptions.headers), lowercaseKeys(headers)); + } + return lowercaseKeys(headers || {}); + } + _getExistingOrDefaultHeader(additionalHeaders, header, _default) { + const lowercaseKeys = obj => Object.keys(obj).reduce((c, k) => (c[k.toLowerCase()] = obj[k], c), {}); + let clientHeader; + if (this.requestOptions && this.requestOptions.headers) { + clientHeader = lowercaseKeys(this.requestOptions.headers)[header]; + } + return additionalHeaders[header] || clientHeader || _default; + } + _getAgent(parsedUrl) { + let agent; + let proxyUrl = pm.getProxyUrl(parsedUrl); + let useProxy = proxyUrl && proxyUrl.hostname; + if (this._keepAlive && useProxy) { + agent = this._proxyAgent; + } + if (this._keepAlive && !useProxy) { + agent = this._agent; + } + // if agent is already assigned use that agent. + if (!!agent) { + return agent; + } + const usingSsl = parsedUrl.protocol === 'https:'; + let maxSockets = 100; + if (!!this.requestOptions) { + maxSockets = this.requestOptions.maxSockets || http.globalAgent.maxSockets; + } + if (useProxy) { + // If using proxy, need tunnel + if (!tunnel) { + tunnel = __webpack_require__(413); + } + const agentOptions = { + maxSockets: maxSockets, + keepAlive: this._keepAlive, + proxy: { + proxyAuth: proxyUrl.auth, + host: proxyUrl.hostname, + port: proxyUrl.port + }, + }; + let tunnelAgent; + const overHttps = proxyUrl.protocol === 'https:'; + if (usingSsl) { + tunnelAgent = overHttps ? tunnel.httpsOverHttps : tunnel.httpsOverHttp; + } + else { + tunnelAgent = overHttps ? tunnel.httpOverHttps : tunnel.httpOverHttp; + } + agent = tunnelAgent(agentOptions); + this._proxyAgent = agent; + } + // if reusing agent across request and tunneling agent isn't assigned create a new agent + if (this._keepAlive && !agent) { + const options = { keepAlive: this._keepAlive, maxSockets: maxSockets }; + agent = usingSsl ? new https.Agent(options) : new http.Agent(options); + this._agent = agent; + } + // if not using private agent and tunnel agent isn't setup then use global agent + if (!agent) { + agent = usingSsl ? https.globalAgent : http.globalAgent; + } + if (usingSsl && this._ignoreSslError) { + // we don't want to set NODE_TLS_REJECT_UNAUTHORIZED=0 since that will affect request for entire process + // http.RequestOptions doesn't expose a way to modify RequestOptions.agent.options + // we have to cast it to any and change it directly + agent.options = Object.assign(agent.options || {}, { rejectUnauthorized: false }); + } + return agent; + } + _performExponentialBackoff(retryNumber) { + retryNumber = Math.min(ExponentialBackoffCeiling, retryNumber); + const ms = ExponentialBackoffTimeSlice * Math.pow(2, retryNumber); + return new Promise(resolve => setTimeout(() => resolve(), ms)); + } + static dateTimeDeserializer(key, value) { + if (typeof value === 'string') { + let a = new Date(value); + if (!isNaN(a.valueOf())) { + return a; + } + } + return value; + } + async _processResponse(res, options) { + return new Promise(async (resolve, reject) => { + const statusCode = res.message.statusCode; + const response = { + statusCode: statusCode, + result: null, + headers: {} + }; + // not found leads to null obj returned + if (statusCode == HttpCodes.NotFound) { + resolve(response); + } + let obj; + let contents; + // get the result from the body + try { + contents = await res.readBody(); + if (contents && contents.length > 0) { + if (options && options.deserializeDates) { + obj = JSON.parse(contents, HttpClient.dateTimeDeserializer); + } + else { + obj = JSON.parse(contents); + } + response.result = obj; + } + response.headers = res.message.headers; + } + catch (err) { + // Invalid resource (contents not json); leaving result obj null + } + // note that 3xx redirects are handled by the http layer. + if (statusCode > 299) { + let msg; + // if exception/error in body, attempt to get better error + if (obj && obj.message) { + msg = obj.message; + } + else if (contents && contents.length > 0) { + // it may be the case that the exception is in the body message as string + msg = contents; + } + else { + msg = "Failed request: (" + statusCode + ")"; + } + let err = new Error(msg); + // attach statusCode and body obj (if available) to the error object + err['statusCode'] = statusCode; + if (response.result) { + err['result'] = response.result; + } + reject(err); + } + else { + resolve(response); + } + }); + } +} +exports.HttpClient = HttpClient; + + +/***/ }), + +/***/ 541: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const dom_1 = __webpack_require__(113); +const util_1 = __webpack_require__(918); +const infra_1 = __webpack_require__(23); +const CreateAlgorithm_1 = __webpack_require__(86); +const OrderedSetAlgorithm_1 = __webpack_require__(146); +const DOMAlgorithm_1 = __webpack_require__(304); +const MutationAlgorithm_1 = __webpack_require__(479); +const ElementAlgorithm_1 = __webpack_require__(33); +/** + * Replaces the contents of the given node with a single text node. + * + * @param string - node contents + * @param parent - a node + */ +function node_stringReplaceAll(str, parent) { + /** + * 1. Let node be null. + * 2. If string is not the empty string, then set node to a new Text node + * whose data is string and node document is parent’s node document. + * 3. Replace all with node within parent. + */ + let node = null; + if (str !== '') { + node = CreateAlgorithm_1.create_text(parent._nodeDocument, str); + } + MutationAlgorithm_1.mutation_replaceAll(node, parent); +} +exports.node_stringReplaceAll = node_stringReplaceAll; +/** + * Clones a node. + * + * @param node - a node to clone + * @param document - the document to own the cloned node + * @param cloneChildrenFlag - whether to clone node's children + */ +function node_clone(node, document = null, cloneChildrenFlag = false) { + /** + * 1. If document is not given, let document be node’s node document. + */ + if (document === null) + document = node._nodeDocument; + let copy; + if (util_1.Guard.isElementNode(node)) { + /** + * 2. If node is an element, then: + * 2.1. Let copy be the result of creating an element, given document, + * node’s local name, node’s namespace, node’s namespace prefix, + * and node’s is value, with the synchronous custom elements flag unset. + * 2.2. For each attribute in node’s attribute list: + * 2.2.1. Let copyAttribute be a clone of attribute. + * 2.2.2. Append copyAttribute to copy. + */ + copy = ElementAlgorithm_1.element_createAnElement(document, node._localName, node._namespace, node._namespacePrefix, node._is, false); + for (const attribute of node._attributeList) { + const copyAttribute = node_clone(attribute, document); + ElementAlgorithm_1.element_append(copyAttribute, copy); + } + } + else { + /** + * 3. Otherwise, let copy be a node that implements the same interfaces as + * node, and fulfills these additional requirements, switching on node: + * - Document + * Set copy’s encoding, content type, URL, origin, type, and mode, to those + * of node. + * - DocumentType + * Set copy’s name, public ID, and system ID, to those of node. + * - Attr + * Set copy’s namespace, namespace prefix, local name, and value, to + * those of node. + * - Text + * - Comment + * Set copy’s data, to that of node. + * - ProcessingInstruction + * Set copy’s target and data to those of node. + * - Any other node + */ + if (util_1.Guard.isDocumentNode(node)) { + const doc = CreateAlgorithm_1.create_document(); + doc._encoding = node._encoding; + doc._contentType = node._contentType; + doc._URL = node._URL; + doc._origin = node._origin; + doc._type = node._type; + doc._mode = node._mode; + copy = doc; + } + else if (util_1.Guard.isDocumentTypeNode(node)) { + const doctype = CreateAlgorithm_1.create_documentType(document, node._name, node._publicId, node._systemId); + copy = doctype; + } + else if (util_1.Guard.isAttrNode(node)) { + const attr = CreateAlgorithm_1.create_attr(document, node.localName); + attr._namespace = node._namespace; + attr._namespacePrefix = node._namespacePrefix; + attr._value = node._value; + copy = attr; + } + else if (util_1.Guard.isExclusiveTextNode(node)) { + copy = CreateAlgorithm_1.create_text(document, node._data); + } + else if (util_1.Guard.isCDATASectionNode(node)) { + copy = CreateAlgorithm_1.create_cdataSection(document, node._data); + } + else if (util_1.Guard.isCommentNode(node)) { + copy = CreateAlgorithm_1.create_comment(document, node._data); + } + else if (util_1.Guard.isProcessingInstructionNode(node)) { + copy = CreateAlgorithm_1.create_processingInstruction(document, node._target, node._data); + } + else if (util_1.Guard.isDocumentFragmentNode(node)) { + copy = CreateAlgorithm_1.create_documentFragment(document); + } + else { + copy = Object.create(node); + } + } + /** + * 4. Set copy’s node document and document to copy, if copy is a document, + * and set copy’s node document to document otherwise. + */ + if (util_1.Guard.isDocumentNode(copy)) { + copy._nodeDocument = copy; + document = copy; + } + else { + copy._nodeDocument = document; + } + /** + * 5. Run any cloning steps defined for node in other applicable + * specifications and pass copy, node, document and the clone children flag + * if set, as parameters. + */ + if (dom_1.dom.features.steps) { + DOMAlgorithm_1.dom_runCloningSteps(copy, node, document, cloneChildrenFlag); + } + /** + * 6. If the clone children flag is set, clone all the children of node and + * append them to copy, with document as specified and the clone children + * flag being set. + */ + if (cloneChildrenFlag) { + for (const child of node._children) { + const childCopy = node_clone(child, document, true); + MutationAlgorithm_1.mutation_append(childCopy, copy); + } + } + /** + * 7. Return copy. + */ + return copy; +} +exports.node_clone = node_clone; +/** + * Determines if two nodes can be considered equal. + * + * @param a - node to compare + * @param b - node to compare + */ +function node_equals(a, b) { + /** + * 1. A and B’s nodeType attribute value is identical. + */ + if (a._nodeType !== b._nodeType) + return false; + /** + * 2. The following are also equal, depending on A: + * - DocumentType + * Its name, public ID, and system ID. + * - Element + * Its namespace, namespace prefix, local name, and its attribute list’s size. + * - Attr + * Its namespace, local name, and value. + * - ProcessingInstruction + * Its target and data. + * - Text + * - Comment + * Its data. + */ + if (util_1.Guard.isDocumentTypeNode(a) && util_1.Guard.isDocumentTypeNode(b)) { + if (a._name !== b._name || a._publicId !== b._publicId || + a._systemId !== b._systemId) + return false; + } + else if (util_1.Guard.isElementNode(a) && util_1.Guard.isElementNode(b)) { + if (a._namespace !== b._namespace || a._namespacePrefix !== b._namespacePrefix || + a._localName !== b._localName || + a._attributeList.length !== b._attributeList.length) + return false; + } + else if (util_1.Guard.isAttrNode(a) && util_1.Guard.isAttrNode(b)) { + if (a._namespace !== b._namespace || a._localName !== b._localName || + a._value !== b._value) + return false; + } + else if (util_1.Guard.isProcessingInstructionNode(a) && util_1.Guard.isProcessingInstructionNode(b)) { + if (a._target !== b._target || a._data !== b._data) + return false; + } + else if (util_1.Guard.isCharacterDataNode(a) && util_1.Guard.isCharacterDataNode(b)) { + if (a._data !== b._data) + return false; + } + /** + * 3. If A is an element, each attribute in its attribute list has an attribute + * that equals an attribute in B’s attribute list. + */ + if (util_1.Guard.isElementNode(a) && util_1.Guard.isElementNode(b)) { + const attrMap = {}; + for (const attrA of a._attributeList) { + attrMap[attrA._localName] = attrA; + } + for (const attrB of b._attributeList) { + const attrA = attrMap[attrB._localName]; + if (!attrA) + return false; + if (!node_equals(attrA, attrB)) + return false; + } + } + /** + * 4. A and B have the same number of children. + * 5. Each child of A equals the child of B at the identical index. + */ + if (a._children.size !== b._children.size) + return false; + const itA = a._children[Symbol.iterator](); + const itB = b._children[Symbol.iterator](); + let resultA = itA.next(); + let resultB = itB.next(); + while (!resultA.done && !resultB.done) { + const child1 = resultA.value; + const child2 = resultB.value; + if (!node_equals(child1, child2)) + return false; + resultA = itA.next(); + resultB = itB.next(); + } + return true; +} +exports.node_equals = node_equals; +/** + * Returns a collection of elements with the given qualified name which are + * descendants of the given root node. + * See: https://dom.spec.whatwg.org/#concept-getelementsbytagname + * + * @param qualifiedName - qualified name + * @param root - root node + */ +function node_listOfElementsWithQualifiedName(qualifiedName, root) { + /** + * 1. If qualifiedName is "*" (U+002A), return a HTMLCollection rooted at + * root, whose filter matches only descendant elements. + * 2. Otherwise, if root’s node document is an HTML document, return a + * HTMLCollection rooted at root, whose filter matches the following + * descendant elements: + * 2.1. Whose namespace is the HTML namespace and whose qualified name is + * qualifiedName, in ASCII lowercase. + * 2.2. Whose namespace is not the HTML namespace and whose qualified name + * is qualifiedName. + * 3. Otherwise, return a HTMLCollection rooted at root, whose filter + * matches descendant elements whose qualified name is qualifiedName. + */ + if (qualifiedName === "*") { + return CreateAlgorithm_1.create_htmlCollection(root); + } + else if (root._nodeDocument._type === "html") { + return CreateAlgorithm_1.create_htmlCollection(root, function (ele) { + if (ele._namespace === infra_1.namespace.HTML && + ele._qualifiedName === qualifiedName.toLowerCase()) { + return true; + } + else if (ele._namespace !== infra_1.namespace.HTML && + ele._qualifiedName === qualifiedName) { + return true; + } + else { + return false; + } + }); + } + else { + return CreateAlgorithm_1.create_htmlCollection(root, function (ele) { + return (ele._qualifiedName === qualifiedName); + }); + } +} +exports.node_listOfElementsWithQualifiedName = node_listOfElementsWithQualifiedName; +/** + * Returns a collection of elements with the given namespace which are + * descendants of the given root node. + * See: https://dom.spec.whatwg.org/#concept-getelementsbytagnamens + * + * @param namespace - element namespace + * @param localName - local name + * @param root - root node + */ +function node_listOfElementsWithNamespace(namespace, localName, root) { + /** + * 1. If namespace is the empty string, set it to null. + * 2. If both namespace and localName are "*" (U+002A), return a + * HTMLCollection rooted at root, whose filter matches descendant elements. + * 3. Otherwise, if namespace is "*" (U+002A), return a HTMLCollection + * rooted at root, whose filter matches descendant elements whose local + * name is localName. + * 4. Otherwise, if localName is "*" (U+002A), return a HTMLCollection + * rooted at root, whose filter matches descendant elements whose + * namespace is namespace. + * 5. Otherwise, return a HTMLCollection rooted at root, whose filter + * matches descendant elements whose namespace is namespace and local + * name is localName. + */ + if (namespace === '') + namespace = null; + if (namespace === "*" && localName === "*") { + return CreateAlgorithm_1.create_htmlCollection(root); + } + else if (namespace === "*") { + return CreateAlgorithm_1.create_htmlCollection(root, function (ele) { + return (ele._localName === localName); + }); + } + else if (localName === "*") { + return CreateAlgorithm_1.create_htmlCollection(root, function (ele) { + return (ele._namespace === namespace); + }); + } + else { + return CreateAlgorithm_1.create_htmlCollection(root, function (ele) { + return (ele._localName === localName && ele._namespace === namespace); + }); + } +} +exports.node_listOfElementsWithNamespace = node_listOfElementsWithNamespace; +/** + * Returns a collection of elements with the given class names which are + * descendants of the given root node. + * See: https://dom.spec.whatwg.org/#concept-getelementsbyclassname + * + * @param namespace - element namespace + * @param localName - local name + * @param root - root node + */ +function node_listOfElementsWithClassNames(classNames, root) { + /** + * 1. Let classes be the result of running the ordered set parser + * on classNames. + * 2. If classes is the empty set, return an empty HTMLCollection. + * 3. Return a HTMLCollection rooted at root, whose filter matches + * descendant elements that have all their classes in classes. + * The comparisons for the classes must be done in an ASCII case-insensitive + * manner if root’s node document’s mode is "quirks", and in a + * case-sensitive manner otherwise. + */ + const classes = OrderedSetAlgorithm_1.orderedSet_parse(classNames); + if (classes.size === 0) { + return CreateAlgorithm_1.create_htmlCollection(root, () => false); + } + const caseSensitive = (root._nodeDocument._mode !== "quirks"); + return CreateAlgorithm_1.create_htmlCollection(root, function (ele) { + const eleClasses = ele.classList; + return OrderedSetAlgorithm_1.orderedSet_contains(eleClasses._tokenSet, classes, caseSensitive); + }); +} +exports.node_listOfElementsWithClassNames = node_listOfElementsWithClassNames; +/** + * Searches for a namespace prefix associated with the given namespace + * starting from the given element through its ancestors. + * + * @param element - an element node to start searching at + * @param namespace - namespace to search for + */ +function node_locateANamespacePrefix(element, namespace) { + /** + * 1. If element’s namespace is namespace and its namespace prefix is not + * null, then return its namespace prefix. + */ + if (element._namespace === namespace && element._namespacePrefix !== null) { + return element._namespacePrefix; + } + /** + * 2. If element has an attribute whose namespace prefix is "xmlns" and + * value is namespace, then return element’s first such attribute’s + * local name. + */ + for (let i = 0; i < element._attributeList.length; i++) { + const attr = element._attributeList[i]; + if (attr._namespacePrefix === "xmlns" && attr._value === namespace) { + return attr._localName; + } + } + /** + * 3. If element’s parent element is not null, then return the result of + * running locate a namespace prefix on that element using namespace. + */ + if (element._parent && util_1.Guard.isElementNode(element._parent)) { + return node_locateANamespacePrefix(element._parent, namespace); + } + /** + * 4. Return null. + */ + return null; +} +exports.node_locateANamespacePrefix = node_locateANamespacePrefix; +/** + * Searches for a namespace associated with the given namespace prefix + * starting from the given node through its ancestors. + * + * @param node - a node to start searching at + * @param prefix - namespace prefix to search for + */ +function node_locateANamespace(node, prefix) { + if (util_1.Guard.isElementNode(node)) { + /** + * 1. If its namespace is not null and its namespace prefix is prefix, + * then return namespace. + */ + if (node._namespace !== null && node._namespacePrefix === prefix) { + return node._namespace; + } + /** + * 2. If it has an attribute whose namespace is the XMLNS namespace, + * namespace prefix is "xmlns", and local name is prefix, or if prefix + * is null and it has an attribute whose namespace is the XMLNS namespace, + * namespace prefix is null, and local name is "xmlns", then return its + * value if it is not the empty string, and null otherwise. + */ + for (let i = 0; i < node._attributeList.length; i++) { + const attr = node._attributeList[i]; + if (attr._namespace === infra_1.namespace.XMLNS && + attr._namespacePrefix === "xmlns" && + attr._localName === prefix) { + return attr._value || null; + } + if (prefix === null && attr._namespace === infra_1.namespace.XMLNS && + attr._namespacePrefix === null && attr._localName === "xmlns") { + return attr._value || null; + } + } + /** + * 3. If its parent element is null, then return null. + */ + if (node.parentElement === null) + return null; + /** + * 4. Return the result of running locate a namespace on its parent + * element using prefix. + */ + return node_locateANamespace(node.parentElement, prefix); + } + else if (util_1.Guard.isDocumentNode(node)) { + /** + * 1. If its document element is null, then return null. + * 2. Return the result of running locate a namespace on its document + * element using prefix. + */ + if (node.documentElement === null) + return null; + return node_locateANamespace(node.documentElement, prefix); + } + else if (util_1.Guard.isDocumentTypeNode(node) || util_1.Guard.isDocumentFragmentNode(node)) { + return null; + } + else if (util_1.Guard.isAttrNode(node)) { + /** + * 1. If its element is null, then return null. + * 2. Return the result of running locate a namespace on its element + * using prefix. + */ + if (node._element === null) + return null; + return node_locateANamespace(node._element, prefix); + } + else { + /** + * 1. If its parent element is null, then return null. + * 2. Return the result of running locate a namespace on its parent + * element using prefix. + */ + if (!node._parent || !util_1.Guard.isElementNode(node._parent)) + return null; + return node_locateANamespace(node._parent, prefix); + } +} +exports.node_locateANamespace = node_locateANamespace; +//# sourceMappingURL=NodeAlgorithm.js.map + +/***/ }), + +/***/ 551: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const interfaces_1 = __webpack_require__(625); +const util_1 = __webpack_require__(592); +const __1 = __webpack_require__(255); +const algorithm_1 = __webpack_require__(163); +const infra_1 = __webpack_require__(23); +const NamespacePrefixMap_1 = __webpack_require__(392); +const LocalNameSet_1 = __webpack_require__(575); +const util_2 = __webpack_require__(918); +const XMLCBWriter_1 = __webpack_require__(190); +const JSONCBWriter_1 = __webpack_require__(781); +const events_1 = __webpack_require__(614); +/** + * Represents a readable XML document stream. + */ +class XMLBuilderCBImpl extends events_1.EventEmitter { + /** + * Initializes a new instance of `XMLStream`. + * + * @param options - stream writer options + * @param fragment - whether to create fragment stream or a document stream + * + * @returns XML stream + */ + constructor(options, fragment = false) { + super(); + this._hasDeclaration = false; + this._docTypeName = ""; + this._hasDocumentElement = false; + this._currentElementSerialized = false; + this._openTags = []; + this._ended = false; + this._fragment = fragment; + // provide default options + this._options = util_1.applyDefaults(options || {}, interfaces_1.DefaultXMLBuilderCBOptions); + this._builderOptions = { + defaultNamespace: this._options.defaultNamespace, + namespaceAlias: this._options.namespaceAlias + }; + this._writer = this._options.format === "xml" ? new XMLCBWriter_1.XMLCBWriter(this._options) : new JSONCBWriter_1.JSONCBWriter(this._options); + // automatically create listeners for callbacks passed via options + if (this._options.data !== undefined) { + this.on("data", this._options.data); + } + if (this._options.end !== undefined) { + this.on("end", this._options.end); + } + if (this._options.error !== undefined) { + this.on("error", this._options.error); + } + this._prefixMap = new NamespacePrefixMap_1.NamespacePrefixMap(); + this._prefixMap.set("xml", infra_1.namespace.XML); + this._prefixIndex = { value: 1 }; + } + /** @inheritdoc */ + ele(p1, p2, p3) { + // parse if JS object or XML or JSON string + if (util_1.isObject(p1) || (util_1.isString(p1) && (/^\s*/g, '>') + .replace(/\r/g, ' '); + } + else { + for (let i = 0; i < node.data.length; i++) { + const c = node.data[i]; + if (c === "&") + markup += "&"; + else if (c === "<") + markup += "<"; + else if (c === ">") + markup += ">"; + else + markup += c; + } + } + this._push(this._writer.text(markup)); + return this; + } + /** @inheritdoc */ + ins(target, content = '') { + this._serializeOpenTag(true); + let node; + try { + node = __1.fragment(this._builderOptions).ins(target, content).first().node; + } + catch (err) { + /* istanbul ignore next */ + this.emit("error", err); + /* istanbul ignore next */ + return this; + } + if (this._options.wellFormed && (node.target.indexOf(":") !== -1 || (/^xml$/i).test(node.target))) { + this.emit("error", new Error("Processing instruction target contains invalid characters (well-formed required).")); + return this; + } + if (this._options.wellFormed && !algorithm_1.xml_isLegalChar(node.data)) { + this.emit("error", Error("Processing instruction data contains invalid characters (well-formed required).")); + return this; + } + this._push(this._writer.instruction(node.target, node.data)); + return this; + } + /** @inheritdoc */ + dat(content) { + this._serializeOpenTag(true); + let node; + try { + node = __1.fragment(this._builderOptions).dat(content).first().node; + } + catch (err) { + this.emit("error", err); + return this; + } + this._push(this._writer.cdata(node.data)); + return this; + } + /** @inheritdoc */ + dec(options = { version: "1.0" }) { + if (this._fragment) { + this.emit("error", Error("Cannot insert an XML declaration into a document fragment.")); + return this; + } + if (this._hasDeclaration) { + this.emit("error", Error("XML declaration is already inserted.")); + return this; + } + this._push(this._writer.declaration(options.version || "1.0", options.encoding, options.standalone)); + this._hasDeclaration = true; + return this; + } + /** @inheritdoc */ + dtd(options) { + if (this._fragment) { + this.emit("error", Error("Cannot insert a DocType declaration into a document fragment.")); + return this; + } + if (this._docTypeName !== "") { + this.emit("error", new Error("DocType declaration is already inserted.")); + return this; + } + if (this._hasDocumentElement) { + this.emit("error", new Error("Cannot insert DocType declaration after document element.")); + return this; + } + let node; + try { + node = __1.create().dtd(options).first().node; + } + catch (err) { + this.emit("error", err); + return this; + } + if (this._options.wellFormed && !algorithm_1.xml_isPubidChar(node.publicId)) { + this.emit("error", new Error("DocType public identifier does not match PubidChar construct (well-formed required).")); + return this; + } + if (this._options.wellFormed && + (!algorithm_1.xml_isLegalChar(node.systemId) || + (node.systemId.indexOf('"') !== -1 && node.systemId.indexOf("'") !== -1))) { + this.emit("error", new Error("DocType system identifier contains invalid characters (well-formed required).")); + return this; + } + this._docTypeName = options.name; + this._push(this._writer.docType(options.name, node.publicId, node.systemId)); + return this; + } + /** @inheritdoc */ + up() { + this._serializeOpenTag(false); + this._serializeCloseTag(); + return this; + } + /** @inheritdoc */ + end() { + this._serializeOpenTag(false); + while (this._openTags.length > 0) { + this._serializeCloseTag(); + } + this._push(null); + return this; + } + /** + * Serializes the opening tag of an element node. + * + * @param hasChildren - whether the element node has child nodes + */ + _serializeOpenTag(hasChildren) { + if (this._currentElementSerialized) + return; + if (this._currentElement === undefined) + return; + const node = this._currentElement.node; + if (this._options.wellFormed && (node.localName.indexOf(":") !== -1 || + !algorithm_1.xml_isName(node.localName))) { + this.emit("error", new Error("Node local name contains invalid characters (well-formed required).")); + return; + } + let qualifiedName = ""; + let ignoreNamespaceDefinitionAttribute = false; + let map = this._prefixMap.copy(); + let localPrefixesMap = {}; + let localDefaultNamespace = this._recordNamespaceInformation(node, map, localPrefixesMap); + let inheritedNS = this._openTags.length === 0 ? null : this._openTags[this._openTags.length - 1][1]; + let ns = node.namespaceURI; + if (ns === null) + ns = inheritedNS; + if (inheritedNS === ns) { + if (localDefaultNamespace !== null) { + ignoreNamespaceDefinitionAttribute = true; + } + if (ns === infra_1.namespace.XML) { + qualifiedName = "xml:" + node.localName; + } + else { + qualifiedName = node.localName; + } + this._writer.beginElement(qualifiedName); + this._push(this._writer.openTagBegin(qualifiedName)); + } + else { + let prefix = node.prefix; + let candidatePrefix = null; + if (prefix !== null || ns !== localDefaultNamespace) { + candidatePrefix = map.get(prefix, ns); + } + if (prefix === "xmlns") { + if (this._options.wellFormed) { + this.emit("error", new Error("An element cannot have the 'xmlns' prefix (well-formed required).")); + return; + } + candidatePrefix = prefix; + } + if (candidatePrefix !== null) { + qualifiedName = candidatePrefix + ':' + node.localName; + if (localDefaultNamespace !== null && localDefaultNamespace !== infra_1.namespace.XML) { + inheritedNS = localDefaultNamespace || null; + } + this._writer.beginElement(qualifiedName); + this._push(this._writer.openTagBegin(qualifiedName)); + } + else if (prefix !== null) { + if (prefix in localPrefixesMap) { + prefix = this._generatePrefix(ns, map, this._prefixIndex); + } + map.set(prefix, ns); + qualifiedName += prefix + ':' + node.localName; + this._writer.beginElement(qualifiedName); + this._push(this._writer.openTagBegin(qualifiedName)); + this._push(this._writer.attribute("xmlns:" + prefix, this._serializeAttributeValue(ns, this._options.wellFormed))); + if (localDefaultNamespace !== null) { + inheritedNS = localDefaultNamespace || null; + } + } + else if (localDefaultNamespace === null || + (localDefaultNamespace !== null && localDefaultNamespace !== ns)) { + ignoreNamespaceDefinitionAttribute = true; + qualifiedName += node.localName; + inheritedNS = ns; + this._writer.beginElement(qualifiedName); + this._push(this._writer.openTagBegin(qualifiedName)); + this._push(this._writer.attribute("xmlns", this._serializeAttributeValue(ns, this._options.wellFormed))); + } + else { + qualifiedName += node.localName; + inheritedNS = ns; + this._writer.beginElement(qualifiedName); + this._push(this._writer.openTagBegin(qualifiedName)); + } + } + this._serializeAttributes(node, map, this._prefixIndex, localPrefixesMap, ignoreNamespaceDefinitionAttribute, this._options.wellFormed); + const isHTML = (ns === infra_1.namespace.HTML); + if (isHTML && !hasChildren && + XMLBuilderCBImpl._VoidElementNames.has(node.localName)) { + this._push(this._writer.openTagEnd(qualifiedName, true, true)); + this._writer.endElement(qualifiedName); + } + else if (!isHTML && !hasChildren) { + this._push(this._writer.openTagEnd(qualifiedName, true, false)); + this._writer.endElement(qualifiedName); + } + else { + this._push(this._writer.openTagEnd(qualifiedName, false, false)); + } + this._currentElementSerialized = true; + /** + * Save qualified name, original inherited ns, original prefix map, and + * hasChildren flag. + */ + this._openTags.push([qualifiedName, inheritedNS, this._prefixMap, hasChildren]); + /** + * New values of inherited namespace and prefix map will be used while + * serializing child nodes. They will be returned to their original values + * when this node is closed using the _openTags array item we saved above. + */ + if (this._isPrefixMapModified(this._prefixMap, map)) { + this._prefixMap = map; + } + /** + * Calls following this will either serialize child nodes or close this tag. + */ + this._writer.level++; + } + /** + * Serializes the closing tag of an element node. + */ + _serializeCloseTag() { + this._writer.level--; + const lastEle = this._openTags.pop(); + /* istanbul ignore next */ + if (lastEle === undefined) { + this.emit("error", new Error("Last element is undefined.")); + return; + } + const [qualifiedName, ns, map, hasChildren] = lastEle; + /** + * Restore original values of inherited namespace and prefix map. + */ + this._prefixMap = map; + if (!hasChildren) + return; + this._push(this._writer.closeTag(qualifiedName)); + this._writer.endElement(qualifiedName); + } + /** + * Pushes data to internal buffer. + * + * @param data - data + */ + _push(data) { + if (data === null) { + this._ended = true; + this.emit("end"); + } + else if (this._ended) { + this.emit("error", new Error("Cannot push to ended stream.")); + } + else if (data.length !== 0) { + this._writer.hasData = true; + this.emit("data", data, this._writer.level); + } + } + /** + * Reads and serializes an XML tree. + * + * @param node - root node + */ + _fromNode(node) { + if (util_2.Guard.isElementNode(node)) { + const name = node.prefix ? node.prefix + ":" + node.localName : node.localName; + if (node.namespaceURI !== null) { + this.ele(node.namespaceURI, name); + } + else { + this.ele(name); + } + for (const attr of node.attributes) { + const name = attr.prefix ? attr.prefix + ":" + attr.localName : attr.localName; + if (attr.namespaceURI !== null) { + this.att(attr.namespaceURI, name, attr.value); + } + else { + this.att(name, attr.value); + } + } + for (const child of node.childNodes) { + this._fromNode(child); + } + this.up(); + } + else if (util_2.Guard.isExclusiveTextNode(node) && node.data) { + this.txt(node.data); + } + else if (util_2.Guard.isCommentNode(node)) { + this.com(node.data); + } + else if (util_2.Guard.isCDATASectionNode(node)) { + this.dat(node.data); + } + else if (util_2.Guard.isProcessingInstructionNode(node)) { + this.ins(node.target, node.data); + } + } + /** + * Produces an XML serialization of the attributes of an element node. + * + * @param node - node to serialize + * @param map - namespace prefix map + * @param prefixIndex - generated namespace prefix index + * @param localPrefixesMap - local prefixes map + * @param ignoreNamespaceDefinitionAttribute - whether to ignore namespace + * attributes + * @param requireWellFormed - whether to check conformance + */ + _serializeAttributes(node, map, prefixIndex, localPrefixesMap, ignoreNamespaceDefinitionAttribute, requireWellFormed) { + const localNameSet = requireWellFormed ? new LocalNameSet_1.LocalNameSet() : undefined; + for (const attr of node.attributes) { + // Optimize common case + if (!requireWellFormed && !ignoreNamespaceDefinitionAttribute && attr.namespaceURI === null) { + this._push(this._writer.attribute(attr.localName, this._serializeAttributeValue(attr.value, this._options.wellFormed))); + continue; + } + if (requireWellFormed && localNameSet && localNameSet.has(attr.namespaceURI, attr.localName)) { + this.emit("error", new Error("Element contains duplicate attributes (well-formed required).")); + return; + } + if (requireWellFormed && localNameSet) + localNameSet.set(attr.namespaceURI, attr.localName); + let attributeNamespace = attr.namespaceURI; + let candidatePrefix = null; + if (attributeNamespace !== null) { + candidatePrefix = map.get(attr.prefix, attributeNamespace); + if (attributeNamespace === infra_1.namespace.XMLNS) { + if (attr.value === infra_1.namespace.XML || + (attr.prefix === null && ignoreNamespaceDefinitionAttribute) || + (attr.prefix !== null && (!(attr.localName in localPrefixesMap) || + localPrefixesMap[attr.localName] !== attr.value) && + map.has(attr.localName, attr.value))) + continue; + if (requireWellFormed && attr.value === infra_1.namespace.XMLNS) { + this.emit("error", new Error("XMLNS namespace is reserved (well-formed required).")); + return; + } + if (requireWellFormed && attr.value === '') { + this.emit("error", new Error("Namespace prefix declarations cannot be used to undeclare a namespace (well-formed required).")); + return; + } + if (attr.prefix === 'xmlns') + candidatePrefix = 'xmlns'; + /** + * _Note:_ The (candidatePrefix === null) check is not in the spec. + * We deviate from the spec here. Otherwise a prefix is generated for + * all attributes with namespaces. + */ + } + else if (candidatePrefix === null) { + if (attr.prefix !== null && + (!map.hasPrefix(attr.prefix) || + map.has(attr.prefix, attributeNamespace))) { + /** + * Check if we can use the attribute's own prefix. + * We deviate from the spec here. + * TODO: This is not an efficient way of searching for prefixes. + * Follow developments to the spec. + */ + candidatePrefix = attr.prefix; + } + else { + candidatePrefix = this._generatePrefix(attributeNamespace, map, prefixIndex); + } + this._push(this._writer.attribute("xmlns:" + candidatePrefix, this._serializeAttributeValue(attributeNamespace, this._options.wellFormed))); + } + } + if (requireWellFormed && (attr.localName.indexOf(":") !== -1 || + !algorithm_1.xml_isName(attr.localName) || + (attr.localName === "xmlns" && attributeNamespace === null))) { + this.emit("error", new Error("Attribute local name contains invalid characters (well-formed required).")); + return; + } + this._push(this._writer.attribute((candidatePrefix !== null ? candidatePrefix + ":" : "") + attr.localName, this._serializeAttributeValue(attr.value, this._options.wellFormed))); + } + } + /** + * Produces an XML serialization of an attribute value. + * + * @param value - attribute value + * @param requireWellFormed - whether to check conformance + */ + _serializeAttributeValue(value, requireWellFormed) { + if (requireWellFormed && value !== null && !algorithm_1.xml_isLegalChar(value)) { + this.emit("error", new Error("Invalid characters in attribute value.")); + return ""; + } + if (value === null) + return ""; + if (this._options.noDoubleEncoding) { + return value.replace(/(?!&(lt|gt|amp|apos|quot);)&/g, '&') + .replace(/") + result += ">"; + else + result += c; + } + return result; + } + } + /** + * Records namespace information for the given element and returns the + * default namespace attribute value. + * + * @param node - element node to process + * @param map - namespace prefix map + * @param localPrefixesMap - local prefixes map + */ + _recordNamespaceInformation(node, map, localPrefixesMap) { + let defaultNamespaceAttrValue = null; + for (const attr of node.attributes) { + let attributeNamespace = attr.namespaceURI; + let attributePrefix = attr.prefix; + if (attributeNamespace === infra_1.namespace.XMLNS) { + if (attributePrefix === null) { + defaultNamespaceAttrValue = attr.value; + continue; + } + else { + let prefixDefinition = attr.localName; + let namespaceDefinition = attr.value; + if (namespaceDefinition === infra_1.namespace.XML) { + continue; + } + if (namespaceDefinition === '') { + namespaceDefinition = null; + } + if (map.has(prefixDefinition, namespaceDefinition)) { + continue; + } + map.set(prefixDefinition, namespaceDefinition); + localPrefixesMap[prefixDefinition] = namespaceDefinition || ''; + } + } + } + return defaultNamespaceAttrValue; + } + /** + * Generates a new prefix for the given namespace. + * + * @param newNamespace - a namespace to generate prefix for + * @param prefixMap - namespace prefix map + * @param prefixIndex - generated namespace prefix index + */ + _generatePrefix(newNamespace, prefixMap, prefixIndex) { + let generatedPrefix = "ns" + prefixIndex.value; + prefixIndex.value++; + prefixMap.set(generatedPrefix, newNamespace); + return generatedPrefix; + } + /** + * Determines if the namespace prefix map was modified from its original. + * + * @param originalMap - original namespace prefix map + * @param newMap - new namespace prefix map + */ + _isPrefixMapModified(originalMap, newMap) { + const items1 = originalMap._items; + const items2 = newMap._items; + const nullItems1 = originalMap._nullItems; + const nullItems2 = newMap._nullItems; + for (const key in items2) { + const arr1 = items1[key]; + if (arr1 === undefined) + return true; + const arr2 = items2[key]; + if (arr1.length !== arr2.length) + return true; + for (let i = 0; i < arr1.length; i++) { + if (arr1[i] !== arr2[i]) + return true; + } + } + if (nullItems1.length !== nullItems2.length) + return true; + for (let i = 0; i < nullItems1.length; i++) { + if (nullItems1[i] !== nullItems2[i]) + return true; + } + return false; + } +} +exports.XMLBuilderCBImpl = XMLBuilderCBImpl; +XMLBuilderCBImpl._VoidElementNames = new Set(['area', 'base', 'basefont', + 'bgsound', 'br', 'col', 'embed', 'frame', 'hr', 'img', 'input', 'keygen', + 'link', 'menuitem', 'meta', 'param', 'source', 'track', 'wbr']); +//# sourceMappingURL=XMLBuilderCBImpl.js.map + +/***/ }), + +/***/ 558: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const interfaces_1 = __webpack_require__(970); +const NodeImpl_1 = __webpack_require__(935); +const WebIDLAlgorithm_1 = __webpack_require__(495); +/** + * Represents an object providing methods which are not dependent on + * any particular document + */ +class DocumentTypeImpl extends NodeImpl_1.NodeImpl { + /** + * Initializes a new instance of `DocumentType`. + * + * @param name - name of the node + * @param publicId - `PUBLIC` identifier + * @param systemId - `SYSTEM` identifier + */ + constructor(name, publicId, systemId) { + super(); + this._name = ''; + this._publicId = ''; + this._systemId = ''; + this._name = name; + this._publicId = publicId; + this._systemId = systemId; + } + /** @inheritdoc */ + get name() { return this._name; } + /** @inheritdoc */ + get publicId() { return this._publicId; } + /** @inheritdoc */ + get systemId() { return this._systemId; } + // MIXIN: ChildNode + /* istanbul ignore next */ + before(...nodes) { throw new Error("Mixin: ChildNode not implemented."); } + /* istanbul ignore next */ + after(...nodes) { throw new Error("Mixin: ChildNode not implemented."); } + /* istanbul ignore next */ + replaceWith(...nodes) { throw new Error("Mixin: ChildNode not implemented."); } + /* istanbul ignore next */ + remove() { throw new Error("Mixin: ChildNode not implemented."); } + /** + * Creates a new `DocumentType`. + * + * @param document - owner document + * @param name - name of the node + * @param publicId - `PUBLIC` identifier + * @param systemId - `SYSTEM` identifier + */ + static _create(document, name, publicId = '', systemId = '') { + const node = new DocumentTypeImpl(name, publicId, systemId); + node._nodeDocument = document; + return node; + } +} +exports.DocumentTypeImpl = DocumentTypeImpl; +/** + * Initialize prototype properties + */ +WebIDLAlgorithm_1.idl_defineConst(DocumentTypeImpl.prototype, "_nodeType", interfaces_1.NodeType.DocumentType); +//# sourceMappingURL=DocumentTypeImpl.js.map + +/***/ }), + +/***/ 568: +/***/ (function(__unusedmodule, exports) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * Represents an object cache with a size limit. + */ +class ObjectCache { + /** + * Initializes a new instance of `ObjectCache`. + * + * @param limit - maximum number of items to keep in the cache. When the limit + * is exceeded the first item is removed from the cache. + */ + constructor(limit = 1000) { + this._items = new Set(); + this._limit = limit; + } + /** + * Adds a new item to the cache. + * + * @param item - an item + */ + add(item) { + this._items.add(item); + if (this._items.size > this._limit) { + const it = this._items.values().next(); + /* istanbul ignore else */ + if (!it.done) { + this._items.delete(it.value); + } + } + } + /** + * Removes an item from the cache. + * + * @param item - an item + */ + remove(item) { + this._items.delete(item); + } + /** + * Removes all items from the cache. + */ + clear() { + this._items.clear(); + } + /** + * Gets the number of items in the cache. + */ + get length() { return this._items.size; } + /** + * Iterates through the items in the cache. + */ + *entries() { + yield* this; + } + /** @inheritdoc */ + *[Symbol.iterator]() { + for (const item of this._items) { + yield item; + } + } +} +exports.ObjectCache = ObjectCache; +//# sourceMappingURL=ObjectCache.js.map + +/***/ }), + +/***/ 574: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const util_1 = __webpack_require__(918); +const algorithm_1 = __webpack_require__(163); +/** + * Represents a mixin that extends non-element parent nodes. This mixin + * is implemented by {@link Document} and {@link DocumentFragment}. + */ +class NonElementParentNodeImpl { + /** @inheritdoc */ + getElementById(id) { + /** + * The getElementById(elementId) method, when invoked, must return the first + * element, in tree order, within the context object’s descendants, + * whose ID is elementId, and null if there is no such element otherwise. + */ + let ele = algorithm_1.tree_getFirstDescendantNode(util_1.Cast.asNode(this), false, false, (e) => util_1.Guard.isElementNode(e)); + while (ele !== null) { + if (ele._uniqueIdentifier === id) { + return ele; + } + ele = algorithm_1.tree_getNextDescendantNode(util_1.Cast.asNode(this), ele, false, false, (e) => util_1.Guard.isElementNode(e)); + } + return null; + } +} +exports.NonElementParentNodeImpl = NonElementParentNodeImpl; +//# sourceMappingURL=NonElementParentNodeImpl.js.map + +/***/ }), + +/***/ 575: +/***/ (function(__unusedmodule, exports) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * Represents a set of unique attribute namespaceURI and localName pairs. + * This set will contain tuples of unique attribute namespaceURI and + * localName pairs, and is populated as each attr is processed. This set is + * used to [optionally] enforce the well-formed constraint that an element + * cannot have two attributes with the same namespaceURI and localName. + * This can occur when two otherwise identical attributes on the same + * element differ only by their prefix values. + */ +class LocalNameSet { + constructor() { + // tuple storage + this._items = {}; + this._nullItems = {}; + } + /** + * Adds or replaces a tuple. + * + * @param ns - namespace URI + * @param localName - attribute local name + */ + set(ns, localName) { + if (ns === null) { + this._nullItems[localName] = true; + } + else if (this._items[ns]) { + this._items[ns][localName] = true; + } + else { + this._items[ns] = {}; + this._items[ns][localName] = true; + } + } + /** + * Determines if the given tuple exists in the set. + * + * @param ns - namespace URI + * @param localName - attribute local name + */ + has(ns, localName) { + if (ns === null) { + return this._nullItems[localName] === true; + } + else if (this._items[ns]) { + return this._items[ns][localName] === true; + } + else { + return false; + } + } +} +exports.LocalNameSet = LocalNameSet; +//# sourceMappingURL=LocalNameSet.js.map + +/***/ }), + +/***/ 581: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const DocumentFragmentImpl_1 = __webpack_require__(796); +const util_1 = __webpack_require__(337); +const algorithm_1 = __webpack_require__(163); +/** + * Represents a shadow root. + */ +class ShadowRootImpl extends DocumentFragmentImpl_1.DocumentFragmentImpl { + /** + * Initializes a new instance of `ShadowRoot`. + * + * @param host - shadow root's host element + * @param mode - shadow root's mode + */ + constructor(host, mode) { + super(); + this._host = host; + this._mode = mode; + } + /** @inheritdoc */ + get mode() { return this._mode; } + /** @inheritdoc */ + get host() { return this._host; } + /** + * Gets the parent event target for the given event. + * + * @param event - an event + */ + _getTheParent(event) { + /** + * A shadow root’s get the parent algorithm, given an event, returns null + * if event’s composed flag is unset and shadow root is the root of + * event’s path’s first struct’s invocation target, and shadow root’s host + * otherwise. + */ + if (!event._composedFlag && !util_1.isEmpty(event._path) && + algorithm_1.tree_rootNode(event._path[0].invocationTarget) === this) { + return null; + } + else { + return this._host; + } + } + // MIXIN: DocumentOrShadowRoot + // No elements + /** + * Creates a new `ShadowRoot`. + * + * @param document - owner document + * @param host - shadow root's host element + */ + static _create(document, host) { + return new ShadowRootImpl(host, "closed"); + } +} +exports.ShadowRootImpl = ShadowRootImpl; +//# sourceMappingURL=ShadowRootImpl.js.map + +/***/ }), + +/***/ 592: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +var FixedSizeSet_1 = __webpack_require__(704); +exports.FixedSizeSet = FixedSizeSet_1.FixedSizeSet; +var ObjectCache_1 = __webpack_require__(889); +exports.ObjectCache = ObjectCache_1.ObjectCache; +var CompareCache_1 = __webpack_require__(524); +exports.CompareCache = CompareCache_1.CompareCache; +var Lazy_1 = __webpack_require__(947); +exports.Lazy = Lazy_1.Lazy; +/** + * Applies the mixin to a given class. + * + * @param baseClass - class to receive the mixin + * @param mixinClass - mixin class + * @param overrides - an array with names of function overrides. Base class + * functions whose names are in this array will be kept by prepending an + * underscore to their names. + */ +function applyMixin(baseClass, mixinClass, ...overrides) { + Object.getOwnPropertyNames(mixinClass.prototype).forEach(name => { + if (overrides.includes(name)) { + const orgPropDesc = Object.getOwnPropertyDescriptor(baseClass.prototype, name); + /* istanbul ignore else */ + if (orgPropDesc) { + Object.defineProperty(baseClass.prototype, "_" + name, orgPropDesc); + } + } + const propDesc = Object.getOwnPropertyDescriptor(mixinClass.prototype, name); + /* istanbul ignore else */ + if (propDesc) { + Object.defineProperty(baseClass.prototype, name, propDesc); + } + }); +} +exports.applyMixin = applyMixin; +/** + * Applies default values to the given object. + * + * @param obj - an object + * @param defaults - an object with default values + * @param overwrite - if set to `true` defaults object always overwrites object + * values, whether they are `undefined` or not. + */ +function applyDefaults(obj, defaults, overwrite = false) { + const result = clone(obj || {}); + forEachObject(defaults, (key, val) => { + if (isPlainObject(val)) { + result[key] = applyDefaults(result[key], val, overwrite); + } + else if (overwrite || result[key] === undefined) { + result[key] = val; + } + }); + return result; +} +exports.applyDefaults = applyDefaults; +/** + * Iterates over items of an array or set. + * + * @param arr - array or set to iterate + * @param callback - a callback function which receives each array item as its + * single argument + * @param thisArg - the value of this inside callback + */ +function forEachArray(arr, callback, thisArg) { + arr.forEach(callback, thisArg); +} +exports.forEachArray = forEachArray; +/** + * Iterates over key/value pairs of a map or object. + * + * @param obj - map or object to iterate + * @param callback - a callback function which receives object key as its first + * argument and object value as its second argument + * @param thisArg - the value of this inside callback + */ +function forEachObject(obj, callback, thisArg) { + if (isMap(obj)) { + obj.forEach((value, key) => callback.call(thisArg, key, value)); + } + else { + for (const key in obj) { + /* istanbul ignore else */ + if (obj.hasOwnProperty(key)) { + callback.call(thisArg, key, obj[key]); + } + } + } +} +exports.forEachObject = forEachObject; +/** + * Returns the number of entries in an array or set. + * + * @param arr - array or set + */ +function arrayLength(obj) { + if (isSet(obj)) { + return obj.size; + } + else { + return obj.length; + } +} +exports.arrayLength = arrayLength; +/** + * Returns the number of entries in a map or object. + * + * @param obj - map or object + */ +function objectLength(obj) { + if (isMap(obj)) { + return obj.size; + } + else { + return Object.keys(obj).length; + } +} +exports.objectLength = objectLength; +/** + * Gets the value of a key from a map or object. + * + * @param obj - map or object + * @param key - the key to retrieve + */ +function getObjectValue(obj, key) { + if (isMap(obj)) { + return obj.get(key); + } + else { + return obj[key]; + } +} +exports.getObjectValue = getObjectValue; +/** + * Removes a property from a map or object. + * + * @param obj - map or object + * @param key - the key to remove + */ +function removeObjectValue(obj, key) { + if (isMap(obj)) { + obj.delete(key); + } + else { + delete obj[key]; + } +} +exports.removeObjectValue = removeObjectValue; +/** + * Deep clones the given object. + * + * @param obj - an object + */ +function clone(obj) { + if (isFunction(obj)) { + return obj; + } + else if (isArray(obj)) { + const result = []; + for (const item of obj) { + result.push(clone(item)); + } + return result; + } + else if (isObject(obj)) { + const result = {}; + for (const key in obj) { + /* istanbul ignore next */ + if (obj.hasOwnProperty(key)) { + const val = obj[key]; + result[key] = clone(val); + } + } + return result; + } + else { + return obj; + } +} +exports.clone = clone; +/** + * Type guard for boolean types + * + * @param x - a variable to type check + */ +function isBoolean(x) { + return typeof x === "boolean"; +} +exports.isBoolean = isBoolean; +/** + * Type guard for numeric types + * + * @param x - a variable to type check + */ +function isNumber(x) { + return typeof x === "number"; +} +exports.isNumber = isNumber; +/** + * Type guard for strings + * + * @param x - a variable to type check + */ +function isString(x) { + return typeof x === "string"; +} +exports.isString = isString; +/** + * Type guard for function objects + * + * @param x - a variable to type check + */ +function isFunction(x) { + return !!x && Object.prototype.toString.call(x) === '[object Function]'; +} +exports.isFunction = isFunction; +/** + * Type guard for JS objects + * + * _Note:_ Functions are objects too + * + * @param x - a variable to type check + */ +function isObject(x) { + const type = typeof x; + return !!x && (type === 'function' || type === 'object'); +} +exports.isObject = isObject; +/** + * Type guard for arrays + * + * @param x - a variable to type check + */ +function isArray(x) { + return Array.isArray(x); +} +exports.isArray = isArray; +/** + * Type guard for sets. + * + * @param x - a variable to check + */ +function isSet(x) { + return x instanceof Set; +} +exports.isSet = isSet; +/** + * Type guard for maps. + * + * @param x - a variable to check + */ +function isMap(x) { + return x instanceof Map; +} +exports.isMap = isMap; +/** + * Determines if `x` is an empty Array or an Object with no own properties. + * + * @param x - a variable to check + */ +function isEmpty(x) { + if (isArray(x)) { + return !x.length; + } + else if (isSet(x)) { + return !x.size; + } + else if (isMap(x)) { + return !x.size; + } + else if (isObject(x)) { + for (const key in x) { + if (x.hasOwnProperty(key)) { + return false; + } + } + return true; + } + return false; +} +exports.isEmpty = isEmpty; +/** + * Determines if `x` is a plain Object. + * + * @param x - a variable to check + */ +function isPlainObject(x) { + if (isObject(x)) { + const proto = Object.getPrototypeOf(x); + const ctor = proto.constructor; + return proto && ctor && + (typeof ctor === 'function') && (ctor instanceof ctor) && + (Function.prototype.toString.call(ctor) === Function.prototype.toString.call(Object)); + } + return false; +} +exports.isPlainObject = isPlainObject; +/** + * Determines if `x` is an iterable Object. + * + * @param x - a variable to check + */ +function isIterable(x) { + return x && (typeof x[Symbol.iterator] === 'function'); +} +exports.isIterable = isIterable; +/** + * Gets the primitive value of an object. + */ +function getValue(obj) { + if (isFunction(obj.valueOf)) { + return obj.valueOf(); + } + else { + return obj; + } +} +exports.getValue = getValue; +/** + * UTF-8 encodes the given string. + * + * @param input - a string + */ +function utf8Encode(input) { + const bytes = new Uint8Array(input.length * 4); + let byteIndex = 0; + for (let i = 0; i < input.length; i++) { + let char = input.charCodeAt(i); + if (char < 128) { + bytes[byteIndex++] = char; + continue; + } + else if (char < 2048) { + bytes[byteIndex++] = char >> 6 | 192; + } + else { + if (char > 0xd7ff && char < 0xdc00) { + if (++i >= input.length) { + throw new Error("Incomplete surrogate pair."); + } + const c2 = input.charCodeAt(i); + if (c2 < 0xdc00 || c2 > 0xdfff) { + throw new Error("Invalid surrogate character."); + } + char = 0x10000 + ((char & 0x03ff) << 10) + (c2 & 0x03ff); + bytes[byteIndex++] = char >> 18 | 240; + bytes[byteIndex++] = char >> 12 & 63 | 128; + } + else { + bytes[byteIndex++] = char >> 12 | 224; + } + bytes[byteIndex++] = char >> 6 & 63 | 128; + } + bytes[byteIndex++] = char & 63 | 128; + } + return bytes.subarray(0, byteIndex); +} +exports.utf8Encode = utf8Encode; +/** + * UTF-8 decodes the given byte sequence into a string. + * + * @param bytes - a byte sequence + */ +function utf8Decode(bytes) { + let result = ""; + let i = 0; + while (i < bytes.length) { + var c = bytes[i++]; + if (c > 127) { + if (c > 191 && c < 224) { + if (i >= bytes.length) { + throw new Error("Incomplete 2-byte sequence."); + } + c = (c & 31) << 6 | bytes[i++] & 63; + } + else if (c > 223 && c < 240) { + if (i + 1 >= bytes.length) { + throw new Error("Incomplete 3-byte sequence."); + } + c = (c & 15) << 12 | (bytes[i++] & 63) << 6 | bytes[i++] & 63; + } + else if (c > 239 && c < 248) { + if (i + 2 >= bytes.length) { + throw new Error("Incomplete 4-byte sequence."); + } + c = (c & 7) << 18 | (bytes[i++] & 63) << 12 | (bytes[i++] & 63) << 6 | bytes[i++] & 63; + } + else { + throw new Error("Unknown multi-byte start."); + } + } + if (c <= 0xffff) { + result += String.fromCharCode(c); + } + else if (c <= 0x10ffff) { + c -= 0x10000; + result += String.fromCharCode(c >> 10 | 0xd800); + result += String.fromCharCode(c & 0x3FF | 0xdc00); + } + else { + throw new Error("Code point exceeds UTF-16 limit."); + } + } + return result; +} +exports.utf8Decode = utf8Decode; +//# sourceMappingURL=index.js.map + +/***/ }), + +/***/ 595: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const interfaces_1 = __webpack_require__(625); +const util_1 = __webpack_require__(592); +const writers_1 = __webpack_require__(95); +const interfaces_2 = __webpack_require__(970); +const util_2 = __webpack_require__(918); +const algorithm_1 = __webpack_require__(163); +const dom_1 = __webpack_require__(743); +const infra_1 = __webpack_require__(23); +/** + * Represents a wrapper that extends XML nodes to implement easy to use and + * chainable document builder methods. + */ +class XMLBuilderImpl { + /** + * Initializes a new instance of `XMLBuilderNodeImpl`. + * + * @param domNode - the DOM node to wrap + */ + constructor(domNode) { + this._domNode = domNode; + } + /** @inheritdoc */ + get node() { return this._domNode; } + /** @inheritdoc */ + set(options) { + this._options = util_1.applyDefaults(util_1.applyDefaults(this._options, options, true), // apply user settings + interfaces_1.DefaultBuilderOptions); // provide defaults + return this; + } + /** @inheritdoc */ + ele(p1, p2, p3) { + let namespace; + let name; + let attributes; + let lastChild = null; + if (util_1.isString(p1) && /^\s*" + p1 + ""; + const domParser = dom_1.createParser(); + const doc = domParser.parseFromString(dom_1.sanitizeInput(contents, this._options.invalidCharReplacement), "text/xml"); + /* istanbul ignore next */ + if (doc.documentElement === null) { + throw new Error("Document element is null."); + } + dom_1.throwIfParserError(doc); + for (const child of doc.documentElement.childNodes) { + const newChild = doc.importNode(child, true); + lastChild = new XMLBuilderImpl(newChild); + this._domNode.appendChild(newChild); + } + if (lastChild === null) { + throw new Error("Could not create any elements with: " + p1.toString() + ". " + this._debugInfo()); + } + return lastChild; + } + else if (util_1.isString(p1) && /^\s*[\{\[]/.test(p1)) { + // parse JSON string + const obj = JSON.parse(p1); + return this.ele(obj); + } + else if (util_1.isObject(p1)) { + // ele(obj: ExpandObject) + [namespace, name, attributes] = [undefined, p1, undefined]; + } + else if ((p1 === null || util_1.isString(p1)) && util_1.isString(p2)) { + // ele(namespace: string, name: string, attributes?: AttributesObject) + [namespace, name, attributes] = [p1, p2, p3]; + } + else if (p1 !== null) { + // ele(name: string, attributes?: AttributesObject) + [namespace, name, attributes] = [undefined, p1, util_1.isObject(p2) ? p2 : undefined]; + } + else { + throw new Error("Element name cannot be null. " + this._debugInfo()); + } + if (attributes) { + attributes = util_1.getValue(attributes); + } + if (util_1.isFunction(name)) { + // evaluate if function + lastChild = this.ele(name.apply(this)); + } + else if (util_1.isArray(name) || util_1.isSet(name)) { + util_1.forEachArray(name, item => lastChild = this.ele(item), this); + } + else if (util_1.isMap(name) || util_1.isObject(name)) { + // expand if object + util_1.forEachObject(name, (key, val) => { + if (util_1.isFunction(val)) { + // evaluate if function + val = val.apply(this); + } + if (!this._options.ignoreConverters && key.indexOf(this._options.convert.att) === 0) { + // assign attributes + if (key === this._options.convert.att) { + lastChild = this.att(val); + } + else { + lastChild = this.att(key.substr(this._options.convert.att.length), val); + } + } + else if (!this._options.ignoreConverters && key.indexOf(this._options.convert.text) === 0) { + // text node + if (util_1.isMap(val) || util_1.isObject(val)) { + // if the key is #text expand child nodes under this node to support mixed content + lastChild = this.ele(val); + } + else { + lastChild = this.txt(val); + } + } + else if (!this._options.ignoreConverters && key.indexOf(this._options.convert.cdata) === 0) { + // cdata node + if (util_1.isArray(val) || util_1.isSet(val)) { + util_1.forEachArray(val, item => lastChild = this.dat(item), this); + } + else { + lastChild = this.dat(val); + } + } + else if (!this._options.ignoreConverters && key.indexOf(this._options.convert.comment) === 0) { + // comment node + if (util_1.isArray(val) || util_1.isSet(val)) { + util_1.forEachArray(val, item => lastChild = this.com(item), this); + } + else { + lastChild = this.com(val); + } + } + else if (!this._options.ignoreConverters && key.indexOf(this._options.convert.ins) === 0) { + // processing instruction + if (util_1.isString(val)) { + const insIndex = val.indexOf(' '); + const insTarget = (insIndex === -1 ? val : val.substr(0, insIndex)); + const insValue = (insIndex === -1 ? '' : val.substr(insIndex + 1)); + lastChild = this.ins(insTarget, insValue); + } + else { + lastChild = this.ins(val); + } + } + else if ((util_1.isArray(val) || util_1.isSet(val)) && util_1.isEmpty(val)) { + // skip empty arrays + lastChild = this._dummy(); + } + else if ((util_1.isMap(val) || util_1.isObject(val)) && util_1.isEmpty(val)) { + // empty objects produce one node + lastChild = this.ele(key); + } + else if (!this._options.keepNullNodes && (val == null)) { + // skip null and undefined nodes + lastChild = this._dummy(); + } + else if (util_1.isArray(val) || util_1.isSet(val)) { + // expand list by creating child nodes + util_1.forEachArray(val, item => { + const childNode = {}; + childNode[key] = item; + lastChild = this.ele(childNode); + }, this); + } + else if (util_1.isMap(val) || util_1.isObject(val)) { + // create a parent node + lastChild = this.ele(key); + // expand child nodes under parent + lastChild.ele(val); + } + else if (val) { + // leaf element node with a single text node + lastChild = this.ele(key); + lastChild.txt(val); + } + else { + // leaf element node + lastChild = this.ele(key); + } + }, this); + } + else { + [namespace, name] = this._extractNamespace(dom_1.sanitizeInput(namespace, this._options.invalidCharReplacement), dom_1.sanitizeInput(name, this._options.invalidCharReplacement), true); + // inherit namespace from parent + if (namespace === undefined) { + const [prefix] = algorithm_1.namespace_extractQName(name); + namespace = this.node.lookupNamespaceURI(prefix); + } + // create a child element node + const childNode = (namespace !== undefined && namespace !== null ? + this._doc.createElementNS(namespace, name) : + this._doc.createElement(name)); + this.node.appendChild(childNode); + lastChild = new XMLBuilderImpl(childNode); + // update doctype node if the new node is the document element node + const oldDocType = this._doc.doctype; + if (childNode === this._doc.documentElement && oldDocType !== null) { + const docType = this._doc.implementation.createDocumentType(this._doc.documentElement.tagName, oldDocType.publicId, oldDocType.systemId); + this._doc.replaceChild(docType, oldDocType); + } + // create attributes + if (attributes && !util_1.isEmpty(attributes)) { + lastChild.att(attributes); + } + } + if (lastChild === null) { + throw new Error("Could not create any elements with: " + name.toString() + ". " + this._debugInfo()); + } + return lastChild; + } + /** @inheritdoc */ + remove() { + const parent = this.up(); + parent.node.removeChild(this.node); + return parent; + } + /** @inheritdoc */ + att(p1, p2, p3) { + if (util_1.isMap(p1) || util_1.isObject(p1)) { + // att(obj: AttributesObject) + // expand if object + util_1.forEachObject(p1, (attName, attValue) => this.att(attName, attValue), this); + return this; + } + // get primitive values + if (p1 !== undefined && p1 !== null) + p1 = util_1.getValue(p1 + ""); + if (p2 !== undefined && p2 !== null) + p2 = util_1.getValue(p2 + ""); + if (p3 !== undefined && p3 !== null) + p3 = util_1.getValue(p3 + ""); + let namespace; + let name; + let value; + if ((p1 === null || util_1.isString(p1)) && util_1.isString(p2) && (p3 === null || util_1.isString(p3))) { + // att(namespace: string, name: string, value: string) + [namespace, name, value] = [p1, p2, p3]; + } + else if (util_1.isString(p1) && (p2 == null || util_1.isString(p2))) { + // ele(name: string, value: string) + [namespace, name, value] = [undefined, p1, p2]; + } + else { + throw new Error("Attribute name and value not specified. " + this._debugInfo()); + } + if (this._options.keepNullAttributes && (value == null)) { + // keep null attributes + value = ""; + } + else if (value == null) { + // skip null|undefined attributes + return this; + } + if (!util_2.Guard.isElementNode(this.node)) { + throw new Error("An attribute can only be assigned to an element node."); + } + let ele = this.node; + [namespace, name] = this._extractNamespace(namespace, name, false); + name = dom_1.sanitizeInput(name, this._options.invalidCharReplacement); + namespace = dom_1.sanitizeInput(namespace, this._options.invalidCharReplacement); + value = dom_1.sanitizeInput(value, this._options.invalidCharReplacement); + const [prefix, localName] = algorithm_1.namespace_extractQName(name); + const [elePrefix, eleLocalName] = algorithm_1.namespace_extractQName(ele.prefix ? ele.prefix + ':' + ele.localName : ele.localName); + // check if this is a namespace declaration attribute + // assign a new element namespace if it wasn't previously assigned + let eleNamespace = null; + if (prefix === "xmlns") { + namespace = infra_1.namespace.XMLNS; + if (ele.namespaceURI === null && elePrefix === localName) { + eleNamespace = value; + } + } + else if (prefix === null && localName === "xmlns" && elePrefix === null) { + namespace = infra_1.namespace.XMLNS; + eleNamespace = value; + } + // re-create the element node if its namespace changed + // we can't simply change the namespaceURI since its read-only + if (eleNamespace !== null) { + const newEle = algorithm_1.create_element(this._doc, eleLocalName, eleNamespace, elePrefix); + for (const attr of ele.attributes) { + newEle.setAttributeNodeNS(attr.cloneNode()); + } + for (const childNode of ele.childNodes) { + newEle.appendChild(childNode.cloneNode()); + } + const parent = ele.parentNode; + /* istanbul ignore next */ + if (parent === null) { + throw new Error("Parent node is null." + this._debugInfo()); + } + parent.replaceChild(newEle, ele); + this._domNode = newEle; + ele = newEle; + } + if (namespace !== undefined) { + ele.setAttributeNS(namespace, name, value); + } + else { + ele.setAttribute(name, value); + } + return this; + } + /** @inheritdoc */ + removeAtt(p1, p2) { + if (!util_2.Guard.isElementNode(this.node)) { + throw new Error("An attribute can only be removed from an element node."); + } + // get primitive values + p1 = util_1.getValue(p1); + if (p2 !== undefined) { + p2 = util_1.getValue(p2); + } + let namespace; + let name; + if (p1 !== null && p2 === undefined) { + name = p1; + } + else if ((p1 === null || util_1.isString(p1)) && p2 !== undefined) { + namespace = p1; + name = p2; + } + else { + throw new Error("Attribute namespace must be a string. " + this._debugInfo()); + } + if (util_1.isArray(name) || util_1.isSet(name)) { + // removeAtt(names: string[]) + // removeAtt(namespace: string, names: string[]) + util_1.forEachArray(name, attName => namespace === undefined ? this.removeAtt(attName) : this.removeAtt(namespace, attName), this); + } + else if (namespace !== undefined) { + // removeAtt(namespace: string, name: string) + name = dom_1.sanitizeInput(name, this._options.invalidCharReplacement); + namespace = dom_1.sanitizeInput(namespace, this._options.invalidCharReplacement); + this.node.removeAttributeNS(namespace, name); + } + else { + // removeAtt(name: string) + name = dom_1.sanitizeInput(name, this._options.invalidCharReplacement); + this.node.removeAttribute(name); + } + return this; + } + /** @inheritdoc */ + txt(content) { + const child = this._doc.createTextNode(dom_1.sanitizeInput(content, this._options.invalidCharReplacement)); + this.node.appendChild(child); + return this; + } + /** @inheritdoc */ + com(content) { + const child = this._doc.createComment(dom_1.sanitizeInput(content, this._options.invalidCharReplacement)); + this.node.appendChild(child); + return this; + } + /** @inheritdoc */ + dat(content) { + const child = this._doc.createCDATASection(dom_1.sanitizeInput(content, this._options.invalidCharReplacement)); + this.node.appendChild(child); + return this; + } + /** @inheritdoc */ + ins(target, content = '') { + if (util_1.isArray(target) || util_1.isSet(target)) { + util_1.forEachArray(target, item => { + item += ""; + const insIndex = item.indexOf(' '); + const insTarget = (insIndex === -1 ? item : item.substr(0, insIndex)); + const insValue = (insIndex === -1 ? '' : item.substr(insIndex + 1)); + this.ins(insTarget, insValue); + }, this); + } + else if (util_1.isMap(target) || util_1.isObject(target)) { + util_1.forEachObject(target, (insTarget, insValue) => this.ins(insTarget, insValue), this); + } + else { + const child = this._doc.createProcessingInstruction(dom_1.sanitizeInput(target, this._options.invalidCharReplacement), dom_1.sanitizeInput(content, this._options.invalidCharReplacement)); + this.node.appendChild(child); + } + return this; + } + /** @inheritdoc */ + dec(options) { + this._options.version = options.version || "1.0"; + this._options.encoding = options.encoding; + this._options.standalone = options.standalone; + return this; + } + /** @inheritdoc */ + dtd(options) { + const name = dom_1.sanitizeInput((options && options.name) || (this._doc.documentElement ? this._doc.documentElement.tagName : "ROOT"), this._options.invalidCharReplacement); + const pubID = dom_1.sanitizeInput((options && options.pubID) || "", this._options.invalidCharReplacement); + const sysID = dom_1.sanitizeInput((options && options.sysID) || "", this._options.invalidCharReplacement); + // name must match document element + if (this._doc.documentElement !== null && name !== this._doc.documentElement.tagName) { + throw new Error("DocType name does not match document element name."); + } + // create doctype node + const docType = this._doc.implementation.createDocumentType(name, pubID, sysID); + if (this._doc.doctype !== null) { + // replace existing doctype + this._doc.replaceChild(docType, this._doc.doctype); + } + else { + // insert before document element node or append to end + this._doc.insertBefore(docType, this._doc.documentElement); + } + return this; + } + /** @inheritdoc */ + import(node) { + const hostNode = this._domNode; + const hostDoc = this._doc; + const importedNode = node.node; + if (util_2.Guard.isDocumentNode(importedNode)) { + // import document node + const elementNode = importedNode.documentElement; + if (elementNode === null) { + throw new Error("Imported document has no document element node. " + this._debugInfo()); + } + const clone = hostDoc.importNode(elementNode, true); + hostNode.appendChild(clone); + } + else if (util_2.Guard.isDocumentFragmentNode(importedNode)) { + // import child nodes + for (const childNode of importedNode.childNodes) { + const clone = hostDoc.importNode(childNode, true); + hostNode.appendChild(clone); + } + } + else { + // import node + const clone = hostDoc.importNode(importedNode, true); + hostNode.appendChild(clone); + } + return this; + } + /** @inheritdoc */ + doc() { + if (this._doc._isFragment) { + let node = this.node; + while (node && node.nodeType !== interfaces_2.NodeType.DocumentFragment) { + node = node.parentNode; + } + /* istanbul ignore next */ + if (node === null) { + throw new Error("Node has no parent node while searching for document fragment ancestor."); + } + return new XMLBuilderImpl(node); + } + else { + return new XMLBuilderImpl(this._doc); + } + } + /** @inheritdoc */ + root() { + const ele = this._doc.documentElement; + if (!ele) { + throw new Error("Document root element is null. " + this._debugInfo()); + } + return new XMLBuilderImpl(ele); + } + /** @inheritdoc */ + up() { + const parent = this._domNode.parentNode; + if (!parent) { + throw new Error("Parent node is null. " + this._debugInfo()); + } + return new XMLBuilderImpl(parent); + } + /** @inheritdoc */ + prev() { + const node = this._domNode.previousSibling; + if (!node) { + throw new Error("Previous sibling node is null. " + this._debugInfo()); + } + return new XMLBuilderImpl(node); + } + /** @inheritdoc */ + next() { + const node = this._domNode.nextSibling; + if (!node) { + throw new Error("Next sibling node is null. " + this._debugInfo()); + } + return new XMLBuilderImpl(node); + } + /** @inheritdoc */ + first() { + const node = this._domNode.firstChild; + if (!node) { + throw new Error("First child node is null. " + this._debugInfo()); + } + return new XMLBuilderImpl(node); + } + /** @inheritdoc */ + last() { + const node = this._domNode.lastChild; + if (!node) { + throw new Error("Last child node is null. " + this._debugInfo()); + } + return new XMLBuilderImpl(node); + } + /** @inheritdoc */ + each(callback, self = false, recursive = false, thisArg) { + let result = this._getFirstDescendantNode(this._domNode, self, recursive); + while (result[0]) { + callback.call(thisArg, new XMLBuilderImpl(result[0]), result[1], result[2]); + result = this._getNextDescendantNode(this._domNode, result[0], recursive, result[1], result[2]); + } + return this; + } + /** @inheritdoc */ + map(callback, self = false, recursive = false, thisArg) { + let result = []; + this.each((node, index, level) => result.push(callback.call(thisArg, node, index, level)), self, recursive); + return result; + } + /** @inheritdoc */ + reduce(callback, initialValue, self = false, recursive = false, thisArg) { + let value = initialValue; + this.each((node, index, level) => value = callback.call(thisArg, value, node, index, level), self, recursive); + return value; + } + /** @inheritdoc */ + find(predicate, self = false, recursive = false, thisArg) { + let result = this._getFirstDescendantNode(this._domNode, self, recursive); + while (result[0]) { + const builder = new XMLBuilderImpl(result[0]); + if (predicate.call(thisArg, builder, result[1], result[2])) { + return builder; + } + result = this._getNextDescendantNode(this._domNode, result[0], recursive, result[1], result[2]); + } + return undefined; + } + /** @inheritdoc */ + filter(predicate, self = false, recursive = false, thisArg) { + let result = []; + this.each((node, index, level) => { + if (predicate.call(thisArg, node, index, level)) { + result.push(node); + } + }, self, recursive); + return result; + } + /** @inheritdoc */ + every(predicate, self = false, recursive = false, thisArg) { + let result = this._getFirstDescendantNode(this._domNode, self, recursive); + while (result[0]) { + const builder = new XMLBuilderImpl(result[0]); + if (!predicate.call(thisArg, builder, result[1], result[2])) { + return false; + } + result = this._getNextDescendantNode(this._domNode, result[0], recursive, result[1], result[2]); + } + return true; + } + /** @inheritdoc */ + some(predicate, self = false, recursive = false, thisArg) { + let result = this._getFirstDescendantNode(this._domNode, self, recursive); + while (result[0]) { + const builder = new XMLBuilderImpl(result[0]); + if (predicate.call(thisArg, builder, result[1], result[2])) { + return true; + } + result = this._getNextDescendantNode(this._domNode, result[0], recursive, result[1], result[2]); + } + return false; + } + /** @inheritdoc */ + toArray(self = false, recursive = false) { + let result = []; + this.each(node => result.push(node), self, recursive); + return result; + } + /** @inheritdoc */ + toString(writerOptions) { + writerOptions = writerOptions || {}; + if (writerOptions.format === undefined) { + writerOptions.format = "xml"; + } + return this._serialize(writerOptions); + } + /** @inheritdoc */ + toObject(writerOptions) { + writerOptions = writerOptions || {}; + if (writerOptions.format === undefined) { + writerOptions.format = "object"; + } + return this._serialize(writerOptions); + } + /** @inheritdoc */ + end(writerOptions) { + writerOptions = writerOptions || {}; + if (writerOptions.format === undefined) { + writerOptions.format = "xml"; + } + return this.doc()._serialize(writerOptions); + } + /** + * Gets the next descendant of the given node of the tree rooted at `root` + * in depth-first pre-order. Returns a three-tuple with + * [descendant, descendant_index, descendant_level]. + * + * @param root - root node of the tree + * @param self - whether to visit the current node along with child nodes + * @param recursive - whether to visit all descendant nodes in tree-order or + * only the immediate child nodes + */ + _getFirstDescendantNode(root, self, recursive) { + if (self) + return [this._domNode, 0, 0]; + else if (recursive) + return this._getNextDescendantNode(root, root, recursive, 0, 0); + else + return [this._domNode.firstChild, 0, 1]; + } + /** + * Gets the next descendant of the given node of the tree rooted at `root` + * in depth-first pre-order. Returns a three-tuple with + * [descendant, descendant_index, descendant_level]. + * + * @param root - root node of the tree + * @param node - current node + * @param recursive - whether to visit all descendant nodes in tree-order or + * only the immediate child nodes + * @param index - child node index + * @param level - current depth of the XML tree + */ + _getNextDescendantNode(root, node, recursive, index, level) { + if (recursive) { + // traverse child nodes + if (node.firstChild) + return [node.firstChild, 0, level + 1]; + if (node === root) + return [null, -1, -1]; + // traverse siblings + if (node.nextSibling) + return [node.nextSibling, index + 1, level]; + // traverse parent's next sibling + let parent = node.parentNode; + while (parent && parent !== root) { + if (parent.nextSibling) + return [parent.nextSibling, algorithm_1.tree_index(parent.nextSibling), level - 1]; + parent = parent.parentNode; + level--; + } + } + else { + if (root === node) + return [node.firstChild, 0, level + 1]; + else + return [node.nextSibling, index + 1, level]; + } + return [null, -1, -1]; + } + /** + * Converts the node into its string or object representation. + * + * @param options - serialization options + */ + _serialize(writerOptions) { + if (writerOptions.format === "xml") { + const writer = new writers_1.XMLWriter(this._options); + return writer.serialize(this.node, writerOptions); + } + else if (writerOptions.format === "map") { + const writer = new writers_1.MapWriter(this._options); + return writer.serialize(this.node, writerOptions); + } + else if (writerOptions.format === "object") { + const writer = new writers_1.ObjectWriter(this._options); + return writer.serialize(this.node, writerOptions); + } + else if (writerOptions.format === "json") { + const writer = new writers_1.JSONWriter(this._options); + return writer.serialize(this.node, writerOptions); + } + else { + throw new Error("Invalid writer format: " + writerOptions.format + ". " + this._debugInfo()); + } + } + /** + * Creates a dummy element node without adding it to the list of child nodes. + * + * Dummy nodes are special nodes representing a node with a `null` value. + * Dummy nodes are created while recursively building the XML tree. Simply + * skipping `null` values doesn't work because that would break the recursive + * chain. + * + * @returns the new dummy element node + */ + _dummy() { + return new XMLBuilderImpl(this._doc.createElement('dummy_node')); + } + /** + * Extracts a namespace and name from the given string. + * + * @param namespace - namespace + * @param name - a string containing both a name and namespace separated by an + * '@' character + * @param ele - `true` if this is an element namespace; otherwise `false` + */ + _extractNamespace(namespace, name, ele) { + // extract from name + const atIndex = name.indexOf("@"); + if (atIndex > 0) { + if (namespace === undefined) + namespace = name.slice(atIndex + 1); + name = name.slice(0, atIndex); + } + if (namespace === undefined) { + // look-up default namespace + namespace = (ele ? this._options.defaultNamespace.ele : this._options.defaultNamespace.att); + } + else if (namespace !== null && namespace[0] === "@") { + // look-up namespace aliases + const alias = namespace.slice(1); + namespace = this._options.namespaceAlias[alias]; + if (namespace === undefined) { + throw new Error("Namespace alias `" + alias + "` is not defined. " + this._debugInfo()); + } + } + return [namespace, name]; + } + /** + * Returns the document owning this node. + */ + get _doc() { + const node = this.node; + if (util_2.Guard.isDocumentNode(node)) { + return node; + } + else { + const docNode = node.ownerDocument; + /* istanbul ignore next */ + if (!docNode) + throw new Error("Owner document is null. " + this._debugInfo()); + return docNode; + } + } + /** + * Returns debug information for this node. + * + * @param name - node name + */ + _debugInfo(name) { + const node = this.node; + const parentNode = node.parentNode; + name = name || node.nodeName; + const parentName = parentNode ? parentNode.nodeName : ''; + if (!parentName) { + return "node: <" + name + ">"; + } + else { + return "node: <" + name + ">, parent: <" + parentName + ">"; + } + } + /** + * Gets or sets builder options. + */ + get _options() { + const doc = this._doc; + /* istanbul ignore next */ + if (doc._xmlBuilderOptions === undefined) { + throw new Error("Builder options is not set."); + } + return doc._xmlBuilderOptions; + } + set _options(value) { + const doc = this._doc; + doc._xmlBuilderOptions = value; + } +} +exports.XMLBuilderImpl = XMLBuilderImpl; +//# sourceMappingURL=XMLBuilderImpl.js.map + +/***/ }), + +/***/ 597: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const DOMException_1 = __webpack_require__(35); +const util_1 = __webpack_require__(918); +const algorithm_1 = __webpack_require__(163); +/** + * Represents a target to which an event can be dispatched. + */ +class EventTargetImpl { + /** + * Initializes a new instance of `EventTarget`. + */ + constructor() { } + get _eventListenerList() { + return this.__eventListenerList || (this.__eventListenerList = []); + } + get _eventHandlerMap() { + return this.__eventHandlerMap || (this.__eventHandlerMap = {}); + } + /** @inheritdoc */ + addEventListener(type, callback, options = { passive: false, once: false, capture: false }) { + /** + * 1. Let capture, passive, and once be the result of flattening more options. + */ + const [capture, passive, once] = algorithm_1.eventTarget_flattenMore(options); + // convert callback function to EventListener, return if null + let listenerCallback; + if (!callback) { + return; + } + else if (util_1.Guard.isEventListener(callback)) { + listenerCallback = callback; + } + else { + listenerCallback = { handleEvent: callback }; + } + /** + * 2. Add an event listener with the context object and an event listener + * whose type is type, callback is callback, capture is capture, passive is + * passive, and once is once. + */ + algorithm_1.eventTarget_addEventListener(this, { + type: type, + callback: listenerCallback, + capture: capture, + passive: passive, + once: once, + removed: false + }); + } + /** @inheritdoc */ + removeEventListener(type, callback, options = { capture: false }) { + /** + * TODO: Implement realms + * 1. If the context object’s relevant global object is a + * ServiceWorkerGlobalScope object and its associated service worker’s + * script resource’s has ever been evaluated flag is set, then throw + * a TypeError. [SERVICE-WORKERS] + */ + /** + * 2. Let capture be the result of flattening options. + */ + const capture = algorithm_1.eventTarget_flatten(options); + if (!callback) + return; + /** + * 3. If the context object’s event listener list contains an event listener + * whose type is type, callback is callback, and capture is capture, then + * remove an event listener with the context object and that event listener. + */ + for (let i = 0; i < this._eventListenerList.length; i++) { + const entry = this._eventListenerList[i]; + if (entry.type !== type || entry.capture !== capture) + continue; + if (util_1.Guard.isEventListener(callback) && entry.callback === callback) { + algorithm_1.eventTarget_removeEventListener(this, entry, i); + break; + } + else if (callback && entry.callback.handleEvent === callback) { + algorithm_1.eventTarget_removeEventListener(this, entry, i); + break; + } + } + } + /** @inheritdoc */ + dispatchEvent(event) { + /** + * 1. If event’s dispatch flag is set, or if its initialized flag is not + * set, then throw an "InvalidStateError" DOMException. + * 2. Initialize event’s isTrusted attribute to false. + * 3. Return the result of dispatching event to the context object. + */ + if (event._dispatchFlag || !event._initializedFlag) { + throw new DOMException_1.InvalidStateError(); + } + event._isTrusted = false; + return algorithm_1.event_dispatch(event, this); + } + /** @inheritdoc */ + _getTheParent(event) { + return null; + } +} +exports.EventTargetImpl = EventTargetImpl; +//# sourceMappingURL=EventTargetImpl.js.map + +/***/ }), + +/***/ 605: +/***/ (function(module) { + +module.exports = require("http"); + +/***/ }), + +/***/ 609: +/***/ (function(__unusedmodule, exports) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +exports.HTML = "http://www.w3.org/1999/xhtml"; +exports.XML = "http://www.w3.org/XML/1998/namespace"; +exports.XMLNS = "http://www.w3.org/2000/xmlns/"; +exports.MathML = "http://www.w3.org/1998/Math/MathML"; +exports.SVG = "http://www.w3.org/2000/svg"; +exports.XLink = "http://www.w3.org/1999/xlink"; +//# sourceMappingURL=Namespace.js.map + +/***/ }), + +/***/ 614: +/***/ (function(module) { + +module.exports = require("events"); + +/***/ }), + +/***/ 619: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const interfaces_1 = __webpack_require__(970); +const CharacterDataImpl_1 = __webpack_require__(43); +const WebIDLAlgorithm_1 = __webpack_require__(495); +/** + * Represents a processing instruction node. + */ +class ProcessingInstructionImpl extends CharacterDataImpl_1.CharacterDataImpl { + /** + * Initializes a new instance of `ProcessingInstruction`. + */ + constructor(target, data) { + super(data); + this._target = target; + } + /** + * Gets the target of the {@link ProcessingInstruction} node. + */ + get target() { return this._target; } + /** + * Creates a new `ProcessingInstruction`. + * + * @param document - owner document + * @param target - instruction target + * @param data - node contents + */ + static _create(document, target, data) { + const node = new ProcessingInstructionImpl(target, data); + node._nodeDocument = document; + return node; + } +} +exports.ProcessingInstructionImpl = ProcessingInstructionImpl; +/** + * Initialize prototype properties + */ +WebIDLAlgorithm_1.idl_defineConst(ProcessingInstructionImpl.prototype, "_nodeType", interfaces_1.NodeType.ProcessingInstruction); +//# sourceMappingURL=ProcessingInstructionImpl.js.map + +/***/ }), + +/***/ 622: +/***/ (function(module) { + +module.exports = require("path"); + +/***/ }), + +/***/ 625: +/***/ (function(__unusedmodule, exports) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * Defines default values for builder options. + */ +exports.DefaultBuilderOptions = { + version: "1.0", + encoding: undefined, + standalone: undefined, + keepNullNodes: false, + keepNullAttributes: false, + ignoreConverters: false, + convert: { + att: "@", + ins: "?", + text: "#", + cdata: "$", + comment: "!" + }, + defaultNamespace: { + ele: undefined, + att: undefined + }, + namespaceAlias: { + html: "http://www.w3.org/1999/xhtml", + xml: "http://www.w3.org/XML/1998/namespace", + xmlns: "http://www.w3.org/2000/xmlns/", + mathml: "http://www.w3.org/1998/Math/MathML", + svg: "http://www.w3.org/2000/svg", + xlink: "http://www.w3.org/1999/xlink" + }, + invalidCharReplacement: undefined +}; +/** + * Contains keys of `XMLBuilderOptions`. + */ +exports.XMLBuilderOptionKeys = new Set(Object.keys(exports.DefaultBuilderOptions)); +/** + * Defines default values for builder options. + */ +exports.DefaultXMLBuilderCBOptions = { + format: "xml", + wellFormed: false, + prettyPrint: false, + indent: " ", + newline: "\n", + offset: 0, + width: 0, + allowEmptyTags: false, + spaceBeforeSlash: false, + keepNullNodes: false, + keepNullAttributes: false, + ignoreConverters: false, + convert: { + att: "@", + ins: "?", + text: "#", + cdata: "$", + comment: "!" + }, + defaultNamespace: { + ele: undefined, + att: undefined + }, + namespaceAlias: { + html: "http://www.w3.org/1999/xhtml", + xml: "http://www.w3.org/XML/1998/namespace", + xmlns: "http://www.w3.org/2000/xmlns/", + mathml: "http://www.w3.org/1998/Math/MathML", + svg: "http://www.w3.org/2000/svg", + xlink: "http://www.w3.org/1999/xlink" + } +}; +//# sourceMappingURL=interfaces.js.map + +/***/ }), + +/***/ 631: +/***/ (function(module) { + +module.exports = require("net"); + +/***/ }), + +/***/ 636: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const _1 = __webpack_require__(113); +const util_1 = __webpack_require__(337); +const algorithm_1 = __webpack_require__(163); +/** + * Represents an ordered set of nodes. + */ +class NodeListImpl { + /** + * Initializes a new instance of `NodeList`. + * + * @param root - root node + */ + constructor(root) { + this._live = true; + this._filter = null; + this._length = 0; + this._root = root; + return new Proxy(this, this); + } + /** @inheritdoc */ + get length() { + /** + * The length attribute must return the number of nodes represented + * by the collection. + */ + return this._root._children.size; + } + /** @inheritdoc */ + item(index) { + /** + * The item(index) method must return the indexth node in the collection. + * If there is no indexth node in the collection, then the method must + * return null. + */ + if (index < 0 || index > this.length - 1) + return null; + if (index < this.length / 2) { + let i = 0; + let node = this._root._firstChild; + while (node !== null && i !== index) { + node = node._nextSibling; + i++; + } + return node; + } + else { + let i = this.length - 1; + let node = this._root._lastChild; + while (node !== null && i !== index) { + node = node._previousSibling; + i--; + } + return node; + } + } + /** @inheritdoc */ + keys() { + return { + [Symbol.iterator]: function () { + let index = 0; + return { + next: function () { + if (index === this.length) { + return { done: true, value: null }; + } + else { + return { done: false, value: index++ }; + } + }.bind(this) + }; + }.bind(this) + }; + } + /** @inheritdoc */ + values() { + return { + [Symbol.iterator]: function () { + const it = this[Symbol.iterator](); + return { + next() { + return it.next(); + } + }; + }.bind(this) + }; + } + /** @inheritdoc */ + entries() { + return { + [Symbol.iterator]: function () { + const it = this[Symbol.iterator](); + let index = 0; + return { + next() { + const itResult = it.next(); + if (itResult.done) { + return { done: true, value: null }; + } + else { + return { done: false, value: [index++, itResult.value] }; + } + } + }; + }.bind(this) + }; + } + /** @inheritdoc */ + [Symbol.iterator]() { + return this._root._children[Symbol.iterator](); + } + /** @inheritdoc */ + forEach(callback, thisArg) { + if (thisArg === undefined) { + thisArg = _1.dom.window; + } + let index = 0; + for (const node of this._root._children) { + callback.call(thisArg, node, index++, this); + } + } + /** + * Implements a proxy get trap to provide array-like access. + */ + get(target, key, receiver) { + if (!util_1.isString(key)) { + return Reflect.get(target, key, receiver); + } + const index = Number(key); + if (isNaN(index)) { + return Reflect.get(target, key, receiver); + } + return target.item(index) || undefined; + } + /** + * Implements a proxy set trap to provide array-like access. + */ + set(target, key, value, receiver) { + if (!util_1.isString(key)) { + return Reflect.set(target, key, value, receiver); + } + const index = Number(key); + if (isNaN(index)) { + return Reflect.set(target, key, value, receiver); + } + const node = target.item(index) || undefined; + if (!node) + return false; + if (node._parent) { + algorithm_1.mutation_replace(node, value, node._parent); + return true; + } + else { + return false; + } + } + /** + * Creates a new `NodeList`. + * + * @param root - root node + */ + static _create(root) { + return new NodeListImpl(root); + } +} +exports.NodeListImpl = NodeListImpl; +//# sourceMappingURL=NodeListImpl.js.map + +/***/ }), + +/***/ 642: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const algorithm_1 = __webpack_require__(163); +const XMLParserImpl_1 = __webpack_require__(468); +/** + * Represents a parser for XML and HTML content. + * + * See: https://w3c.github.io/DOM-Parsing/#the-domparser-interface + */ +class DOMParserImpl { + /** @inheritdoc */ + parseFromString(source, mimeType) { + if (mimeType === "text/html") + throw new Error('HTML parser not implemented.'); + try { + const parser = new XMLParserImpl_1.XMLParserImpl(); + const doc = parser.parse(source); + doc._contentType = mimeType; + return doc; + } + catch (e) { + const errorNS = "http://www.mozilla.org/newlayout/xml/parsererror.xml"; + const doc = algorithm_1.create_xmlDocument(); + const root = doc.createElementNS(errorNS, "parsererror"); + const ele = doc.createElementNS(errorNS, "error"); + ele.setAttribute("message", e.message); + root.appendChild(ele); + doc.appendChild(root); + return doc; + } + } +} +exports.DOMParserImpl = DOMParserImpl; +//# sourceMappingURL=DOMParserImpl.js.map + +/***/ }), + +/***/ 646: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const interfaces_1 = __webpack_require__(970); +const TraverserImpl_1 = __webpack_require__(487); +const algorithm_1 = __webpack_require__(163); +/** + * Represents the nodes of a subtree and a position within them. + */ +class TreeWalkerImpl extends TraverserImpl_1.TraverserImpl { + /** + * Initializes a new instance of `TreeWalker`. + */ + constructor(root, current) { + super(root); + this._current = current; + } + /** @inheritdoc */ + get currentNode() { return this._current; } + set currentNode(value) { this._current = value; } + /** @inheritdoc */ + parentNode() { + /** + * 1. Let node be the context object’s current. + * 2. While node is non-null and is not the context object’s root: + */ + let node = this._current; + while (node !== null && node !== this._root) { + /** + * 2.1. Set node to node’s parent. + * 2.2. If node is non-null and filtering node within the context object + * returns FILTER_ACCEPT, then set the context object’s current to node + * and return node. + */ + node = node._parent; + if (node !== null && + algorithm_1.traversal_filter(this, node) === interfaces_1.FilterResult.Accept) { + this._current = node; + return node; + } + } + /** + * 3. Return null. + */ + return null; + } + /** @inheritdoc */ + firstChild() { + /** + * The firstChild() method, when invoked, must traverse children with the + * context object and first. + */ + return algorithm_1.treeWalker_traverseChildren(this, true); + } + /** @inheritdoc */ + lastChild() { + /** + * The lastChild() method, when invoked, must traverse children with the + * context object and last. + */ + return algorithm_1.treeWalker_traverseChildren(this, false); + } + /** @inheritdoc */ + nextSibling() { + /** + * The nextSibling() method, when invoked, must traverse siblings with the + * context object and next. + */ + return algorithm_1.treeWalker_traverseSiblings(this, true); + } + /** @inheritdoc */ + previousNode() { + /** + * 1. Let node be the context object’s current. + * 2. While node is not the context object’s root: + */ + let node = this._current; + while (node !== this._root) { + /** + * 2.1. Let sibling be node’s previous sibling. + * 2.2. While sibling is non-null: + */ + let sibling = node._previousSibling; + while (sibling) { + /** + * 2.2.1. Set node to sibling. + * 2.2.2. Let result be the result of filtering node within the context + * object. + */ + node = sibling; + let result = algorithm_1.traversal_filter(this, node); + /** + * 2.2.3. While result is not FILTER_REJECT and node has a child: + */ + while (result !== interfaces_1.FilterResult.Reject && node._lastChild) { + /** + * 2.2.3.1. Set node to node’s last child. + * 2.2.3.2. Set result to the result of filtering node within the + * context object. + */ + node = node._lastChild; + result = algorithm_1.traversal_filter(this, node); + } + /** + * 2.2.4. If result is FILTER_ACCEPT, then set the context object’s + * current to node and return node. + */ + if (result === interfaces_1.FilterResult.Accept) { + this._current = node; + return node; + } + /** + * 2.2.5. Set sibling to node’s previous sibling. + */ + sibling = node._previousSibling; + } + /** + * 2.3. If node is the context object’s root or node’s parent is null, + * then return null. + */ + if (node === this._root || node._parent === null) { + return null; + } + /** + * 2.4. Set node to node’s parent. + */ + node = node._parent; + /** + * 2.5. If the return value of filtering node within the context object is + * FILTER_ACCEPT, then set the context object’s current to node and + * return node. + */ + if (algorithm_1.traversal_filter(this, node) === interfaces_1.FilterResult.Accept) { + this._current = node; + return node; + } + } + /** + * 3. Return null. + */ + return null; + } + /** @inheritdoc */ + previousSibling() { + /** + * The previousSibling() method, when invoked, must traverse siblings with + * the context object and previous. + */ + return algorithm_1.treeWalker_traverseSiblings(this, false); + } + /** @inheritdoc */ + nextNode() { + /** + * 1. Let node be the context object’s current. + * 2. Let result be FILTER_ACCEPT. + * 3. While true: + */ + let node = this._current; + let result = interfaces_1.FilterResult.Accept; + while (true) { + /** + * 3.1. While result is not FILTER_REJECT and node has a child: + */ + while (result !== interfaces_1.FilterResult.Reject && node._firstChild) { + /** + * 3.1.1. Set node to its first child. + * 3.1.2. Set result to the result of filtering node within the context + * object. + * 3.1.3. If result is FILTER_ACCEPT, then set the context object’s + * current to node and return node. + */ + node = node._firstChild; + result = algorithm_1.traversal_filter(this, node); + if (result === interfaces_1.FilterResult.Accept) { + this._current = node; + return node; + } + } + /** + * 3.2. Let sibling be null. + * 3.3. Let temporary be node. + * 3.4. While temporary is non-null: + */ + let sibling = null; + let temporary = node; + while (temporary !== null) { + /** + * 3.4.1. If temporary is the context object’s root, then return null. + */ + if (temporary === this._root) { + return null; + } + /** + * 3.4.2. Set sibling to temporary’s next sibling. + * 3.4.3. If sibling is non-null, then break. + */ + sibling = temporary._nextSibling; + if (sibling !== null) { + node = sibling; + break; + } + /** + * 3.4.4. Set temporary to temporary’s parent. + */ + temporary = temporary._parent; + } + /** + * 3.5. Set result to the result of filtering node within the context object. + * 3.6. If result is FILTER_ACCEPT, then set the context object’s current + * to node and return node. + */ + result = algorithm_1.traversal_filter(this, node); + if (result === interfaces_1.FilterResult.Accept) { + this._current = node; + return node; + } + } + } + /** + * Creates a new `TreeWalker`. + * + * @param root - iterator's root node + * @param current - current node + */ + static _create(root, current) { + return new TreeWalkerImpl(root, current); + } +} +exports.TreeWalkerImpl = TreeWalkerImpl; +//# sourceMappingURL=TreeWalkerImpl.js.map + +/***/ }), + +/***/ 648: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const util_1 = __webpack_require__(337); +const algorithm_1 = __webpack_require__(163); +/** + * Represents an object implementing DOM algorithms. + */ +class DOMImpl { + /** + * Initializes a new instance of `DOM`. + */ + constructor() { + this._features = { + mutationObservers: true, + customElements: true, + slots: true, + steps: true + }; + this._window = null; + this._compareCache = new util_1.CompareCache(); + this._rangeList = new util_1.FixedSizeSet(); + } + /** + * Sets DOM algorithm features. + * + * @param features - DOM features supported by algorithms. All features are + * enabled by default unless explicity disabled. + */ + setFeatures(features) { + if (features === undefined) + features = true; + if (util_1.isObject(features)) { + for (const key in features) { + this._features[key] = features[key] || false; + } + } + else { + // enable/disable all features + for (const key in this._features) { + this._features[key] = features; + } + } + } + /** + * Gets DOM algorithm features. + */ + get features() { return this._features; } + /** + * Gets the DOM window. + */ + get window() { + if (this._window === null) { + this._window = algorithm_1.create_window(); + } + return this._window; + } + /** + * Gets the global node compare cache. + */ + get compareCache() { return this._compareCache; } + /** + * Gets the global range list. + */ + get rangeList() { return this._rangeList; } + /** + * Returns the instance of `DOM`. + */ + static get instance() { + if (!DOMImpl._instance) { + DOMImpl._instance = new DOMImpl(); + } + return DOMImpl._instance; + } +} +/** + * Represents an object implementing DOM algorithms. + */ +exports.dom = DOMImpl.instance; +//# sourceMappingURL=DOMImpl.js.map + +/***/ }), + +/***/ 657: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const util_1 = __webpack_require__(68); +/** + * Adds the given item to the end of the list. + * + * @param list - a list + * @param item - an item + */ +function append(list, item) { + list.push(item); +} +exports.append = append; +/** + * Extends a list by appending all items from another list. + * + * @param listA - a list to extend + * @param listB - a list containing items to append to `listA` + */ +function extend(listA, listB) { + listA.push(...listB); +} +exports.extend = extend; +/** + * Inserts the given item to the start of the list. + * + * @param list - a list + * @param item - an item + */ +function prepend(list, item) { + list.unshift(item); +} +exports.prepend = prepend; +/** + * Replaces the given item or all items matching condition with a new item. + * + * @param list - a list + * @param conditionOrItem - an item to replace or a condition matching items + * to replace + * @param item - an item + */ +function replace(list, conditionOrItem, newItem) { + let i = 0; + for (const oldItem of list) { + if (util_1.isFunction(conditionOrItem)) { + if (!!conditionOrItem.call(null, oldItem)) { + list[i] = newItem; + } + } + else if (oldItem === conditionOrItem) { + list[i] = newItem; + return; + } + i++; + } +} +exports.replace = replace; +/** + * Inserts the given item before the given index. + * + * @param list - a list + * @param item - an item + */ +function insert(list, item, index) { + list.splice(index, 0, item); +} +exports.insert = insert; +/** + * Removes the given item or all items matching condition. + * + * @param list - a list + * @param conditionOrItem - an item to remove or a condition matching items + * to remove + */ +function remove(list, conditionOrItem) { + let i = list.length; + while (i--) { + const oldItem = list[i]; + if (util_1.isFunction(conditionOrItem)) { + if (!!conditionOrItem.call(null, oldItem)) { + list.splice(i, 1); + } + } + else if (oldItem === conditionOrItem) { + list.splice(i, 1); + return; + } + } +} +exports.remove = remove; +/** + * Removes all items from the list. + */ +function empty(list) { + list.length = 0; +} +exports.empty = empty; +/** + * Determines if the list contains the given item or any items matching + * condition. + * + * @param list - a list + * @param conditionOrItem - an item to a condition to match + */ +function contains(list, conditionOrItem) { + for (const oldItem of list) { + if (util_1.isFunction(conditionOrItem)) { + if (!!conditionOrItem.call(null, oldItem)) { + return true; + } + } + else if (oldItem === conditionOrItem) { + return true; + } + } + return false; +} +exports.contains = contains; +/** + * Returns the count of items in the list matching the given condition. + * + * @param list - a list + * @param condition - an optional condition to match + */ +function size(list, condition) { + if (condition === undefined) { + return list.length; + } + else { + let count = 0; + for (const item of list) { + if (!!condition.call(null, item)) { + count++; + } + } + return count; + } +} +exports.size = size; +/** + * Determines if the list is empty. + * + * @param list - a list + */ +function isEmpty(list) { + return list.length === 0; +} +exports.isEmpty = isEmpty; +/** + * Returns an iterator for the items of the list. + * + * @param list - a list + * @param condition - an optional condition to match + */ +function* forEach(list, condition) { + if (condition === undefined) { + yield* list; + } + else { + for (const item of list) { + if (!!condition.call(null, item)) { + yield item; + } + } + } +} +exports.forEach = forEach; +/** + * Creates and returns a shallow clone of list. + * + * @param list - a list + */ +function clone(list) { + return new Array(...list); +} +exports.clone = clone; +/** + * Returns a new list containing items from the list sorted in ascending + * order. + * + * @param list - a list + * @param lessThanAlgo - a function that returns `true` if its first argument + * is less than its second argument, and `false` otherwise. + */ +function sortInAscendingOrder(list, lessThanAlgo) { + return list.sort((itemA, itemB) => lessThanAlgo.call(null, itemA, itemB) ? -1 : 1); +} +exports.sortInAscendingOrder = sortInAscendingOrder; +/** + * Returns a new list containing items from the list sorted in descending + * order. + * + * @param list - a list + * @param lessThanAlgo - a function that returns `true` if its first argument + * is less than its second argument, and `false` otherwise. + */ +function sortInDescendingOrder(list, lessThanAlgo) { + return list.sort((itemA, itemB) => lessThanAlgo.call(null, itemA, itemB) ? 1 : -1); +} +exports.sortInDescendingOrder = sortInDescendingOrder; +//# sourceMappingURL=List.js.map + +/***/ }), + +/***/ 661: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const DocumentImpl_1 = __webpack_require__(488); +/** + * Represents an XML document. + */ +class XMLDocumentImpl extends DocumentImpl_1.DocumentImpl { + /** + * Initializes a new instance of `XMLDocument`. + */ + constructor() { + super(); + } +} +exports.XMLDocumentImpl = XMLDocumentImpl; +//# sourceMappingURL=XMLDocumentImpl.js.map + +/***/ }), + +/***/ 664: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const DOMException_1 = __webpack_require__(35); +const infra_1 = __webpack_require__(23); +const XMLAlgorithm_1 = __webpack_require__(442); +/** + * Validates the given qualified name. + * + * @param qualifiedName - qualified name + */ +function namespace_validate(qualifiedName) { + /** + * To validate a qualifiedName, throw an "InvalidCharacterError" + * DOMException if qualifiedName does not match the Name or QName + * production. + */ + if (!XMLAlgorithm_1.xml_isName(qualifiedName)) + throw new DOMException_1.InvalidCharacterError(`Invalid XML name: ${qualifiedName}`); + if (!XMLAlgorithm_1.xml_isQName(qualifiedName)) + throw new DOMException_1.InvalidCharacterError(`Invalid XML qualified name: ${qualifiedName}.`); +} +exports.namespace_validate = namespace_validate; +/** + * Validates and extracts a namespace, prefix and localName from the + * given namespace and qualified name. + * See: https://dom.spec.whatwg.org/#validate-and-extract. + * + * @param namespace - namespace + * @param qualifiedName - qualified name + * + * @returns a tuple with `namespace`, `prefix` and `localName`. + */ +function namespace_validateAndExtract(namespace, qualifiedName) { + /** + * 1. If namespace is the empty string, set it to null. + * 2. Validate qualifiedName. + * 3. Let prefix be null. + * 4. Let localName be qualifiedName. + * 5. If qualifiedName contains a ":" (U+003E), then split the string on it + * and set prefix to the part before and localName to the part after. + * 6. If prefix is non-null and namespace is null, then throw a + * "NamespaceError" DOMException. + * 7. If prefix is "xml" and namespace is not the XML namespace, then throw + * a "NamespaceError" DOMException. + * 8. If either qualifiedName or prefix is "xmlns" and namespace is not the + * XMLNS namespace, then throw a "NamespaceError" DOMException. + * 9. If namespace is the XMLNS namespace and neither qualifiedName nor + * prefix is "xmlns", then throw a "NamespaceError" DOMException. + * 10. Return namespace, prefix, and localName. + */ + if (!namespace) + namespace = null; + namespace_validate(qualifiedName); + const parts = qualifiedName.split(':'); + const prefix = (parts.length === 2 ? parts[0] : null); + const localName = (parts.length === 2 ? parts[1] : qualifiedName); + if (prefix && namespace === null) + throw new DOMException_1.NamespaceError("Qualified name includes a prefix but the namespace is null."); + if (prefix === "xml" && namespace !== infra_1.namespace.XML) + throw new DOMException_1.NamespaceError(`Qualified name includes the "xml" prefix but the namespace is not the XML namespace.`); + if (namespace !== infra_1.namespace.XMLNS && + (prefix === "xmlns" || qualifiedName === "xmlns")) + throw new DOMException_1.NamespaceError(`Qualified name includes the "xmlns" prefix but the namespace is not the XMLNS namespace.`); + if (namespace === infra_1.namespace.XMLNS && + (prefix !== "xmlns" && qualifiedName !== "xmlns")) + throw new DOMException_1.NamespaceError(`Qualified name does not include the "xmlns" prefix but the namespace is the XMLNS namespace.`); + return [namespace, prefix, localName]; +} +exports.namespace_validateAndExtract = namespace_validateAndExtract; +/** + * Extracts a prefix and localName from the given qualified name. + * + * @param qualifiedName - qualified name + * + * @returns an tuple with `prefix` and `localName`. + */ +function namespace_extractQName(qualifiedName) { + namespace_validate(qualifiedName); + const parts = qualifiedName.split(':'); + const prefix = (parts.length === 2 ? parts[0] : null); + const localName = (parts.length === 2 ? parts[1] : qualifiedName); + return [prefix, localName]; +} +exports.namespace_extractQName = namespace_extractQName; +//# sourceMappingURL=NamespaceAlgorithm.js.map + +/***/ }), + +/***/ 665: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const CodePoints_1 = __webpack_require__(780); +const ByteSequence_1 = __webpack_require__(425); +const Byte_1 = __webpack_require__(15); +const util_1 = __webpack_require__(42); +/** + * Determines if the string `a` is a code unit prefix of string `b`. + * + * @param a - a string + * @param b - a string + */ +function isCodeUnitPrefix(a, b) { + /** + * 1. Let i be 0. + * 2. While true: + * 2.1. Let aCodeUnit be the ith code unit of a if i is less than a’s length; + * otherwise null. + * 2.2. Let bCodeUnit be the ith code unit of b if i is less than b’s length; + * otherwise null. + * 2.3. If bCodeUnit is null, then return true. + * 2.4. Return false if aCodeUnit is different from bCodeUnit. + * 2.5. Set i to i + 1. + */ + let i = 0; + while (true) { + const aCodeUnit = i < a.length ? a.charCodeAt(i) : null; + const bCodeUnit = i < b.length ? b.charCodeAt(i) : null; + if (aCodeUnit === null) + return true; + if (aCodeUnit !== bCodeUnit) + return false; + i++; + } +} +exports.isCodeUnitPrefix = isCodeUnitPrefix; +/** + * Determines if the string `a` is a code unit less than string `b`. + * + * @param a - a string + * @param b - a string + */ +function isCodeUnitLessThan(a, b) { + /** + * 1. If b is a code unit prefix of a, then return false. + * 2. If a is a code unit prefix of b, then return true. + * 3. Let n be the smallest index such that the nth code unit of a is + * different from the nth code unit of b. (There has to be such an index, + * since neither string is a prefix of the other.) + * 4. If the nth code unit of a is less than the nth code unit of b, then + * return true. + * 5. Return false. + */ + if (isCodeUnitPrefix(b, a)) + return false; + if (isCodeUnitPrefix(a, b)) + return true; + for (let i = 0; i < Math.min(a.length, b.length); i++) { + const aCodeUnit = a.charCodeAt(i); + const bCodeUnit = b.charCodeAt(i); + if (aCodeUnit === bCodeUnit) + continue; + return (aCodeUnit < bCodeUnit); + } + /* istanbul ignore next */ + return false; +} +exports.isCodeUnitLessThan = isCodeUnitLessThan; +/** + * Isomorphic encodes the given string. + * + * @param str - a string + */ +function isomorphicEncode(str) { + /** + * 1. Assert: input contains no code points greater than U+00FF. + * 2. Return a byte sequence whose length is equal to input’s length and whose + * bytes have the same values as input’s code points, in the same order. + */ + const codePoints = Array.from(str); + const bytes = new Uint8Array(codePoints.length); + let i = 0; + for (const codePoint of str) { + const byte = codePoint.codePointAt(0); + console.assert(byte !== undefined && byte <= 0x00FF, "isomorphicEncode requires string bytes to be less than or equal to 0x00FF."); + if (byte !== undefined && byte <= 0x00FF) { + bytes[i++] = byte; + } + } + return bytes; +} +exports.isomorphicEncode = isomorphicEncode; +/** + * Determines if the given string is An ASCII string. + * + * @param str - a string + */ +function isASCIIString(str) { + /** + * An ASCII string is a string whose code points are all ASCII code points. + */ + return /^[\u0000-\u007F]*$/.test(str); +} +exports.isASCIIString = isASCIIString; +/** + * Converts all uppercase ASCII code points to lowercase. + * + * @param str - a string + */ +function asciiLowercase(str) { + /** + * To ASCII lowercase a string, replace all ASCII upper alphas in the string + * with their corresponding code point in ASCII lower alpha. + */ + let result = ""; + for (const c of str) { + const code = c.codePointAt(0); + if (code !== undefined && code >= 0x41 && code <= 0x5A) { + result += String.fromCodePoint(code + 0x20); + } + else { + result += c; + } + } + return result; +} +exports.asciiLowercase = asciiLowercase; +/** + * Converts all uppercase ASCII code points to uppercase. + * + * @param str - a string + */ +function asciiUppercase(str) { + /** + * To ASCII uppercase a string, replace all ASCII lower alphas in the string + * with their corresponding code point in ASCII upper alpha. + */ + let result = ""; + for (const c of str) { + const code = c.codePointAt(0); + if (code !== undefined && code >= 0x61 && code <= 0x7A) { + result += String.fromCodePoint(code - 0x20); + } + else { + result += c; + } + } + return result; +} +exports.asciiUppercase = asciiUppercase; +/** + * Compares two ASCII strings case-insensitively. + * + * @param a - a string + * @param b - a string + */ +function asciiCaseInsensitiveMatch(a, b) { + /** + * A string A is an ASCII case-insensitive match for a string B, if the ASCII + * lowercase of A is the ASCII lowercase of B. + */ + return asciiLowercase(a) === asciiLowercase(b); +} +exports.asciiCaseInsensitiveMatch = asciiCaseInsensitiveMatch; +/** + * ASCII encodes a string. + * + * @param str - a string + */ +function asciiEncode(str) { + /** + * 1. Assert: input is an ASCII string. + * 2. Return the isomorphic encoding of input. + */ + console.assert(isASCIIString(str), "asciiEncode requires an ASCII string."); + return isomorphicEncode(str); +} +exports.asciiEncode = asciiEncode; +/** + * ASCII decodes a byte sequence. + * + * @param bytes - a byte sequence + */ +function asciiDecode(bytes) { + /** + * 1. Assert: All bytes in input are ASCII bytes. + * 2. Return the isomorphic decoding of input. + */ + for (const byte of bytes) { + console.assert(Byte_1.isASCIIByte(byte), "asciiDecode requires an ASCII byte sequence."); + } + return ByteSequence_1.isomorphicDecode(bytes); +} +exports.asciiDecode = asciiDecode; +/** + * Strips newline characters from a string. + * + * @param str - a string + */ +function stripNewlines(str) { + /** + * To strip newlines from a string, remove any U+000A LF and U+000D CR code + * points from the string. + */ + return str.replace(/[\n\r]/g, ""); +} +exports.stripNewlines = stripNewlines; +/** + * Normalizes newline characters in a string by converting consecutive + * carriage-return newline characters and also single carriage return characters + * into a single newline. + * + * @param str - a string + */ +function normalizeNewlines(str) { + /** + * To normalize newlines in a string, replace every U+000D CR U+000A LF code + * point pair with a single U+000A LF code point, and then replace every + * remaining U+000D CR code point with a U+000A LF code point. + */ + return str.replace(/\r\n/g, "\n").replace(/\r/g, "\n"); +} +exports.normalizeNewlines = normalizeNewlines; +/** + * Removes leading and trailing whitespace characters from a string. + * + * @param str - a string + */ +function stripLeadingAndTrailingASCIIWhitespace(str) { + /** + * To strip leading and trailing ASCII whitespace from a string, remove all + * ASCII whitespace that are at the start or the end of the string. + */ + return str.replace(/^[\t\n\f\r ]+/, "").replace(/[\t\n\f\r ]+$/, ""); +} +exports.stripLeadingAndTrailingASCIIWhitespace = stripLeadingAndTrailingASCIIWhitespace; +/** + * Removes consecutive newline characters from a string. + * + * @param str - a string + */ +function stripAndCollapseASCIIWhitespace(str) { + /** + * To strip and collapse ASCII whitespace in a string, replace any sequence of + * one or more consecutive code points that are ASCII whitespace in the string + * with a single U+0020 SPACE code point, and then remove any leading and + * trailing ASCII whitespace from that string. + */ + return stripLeadingAndTrailingASCIIWhitespace(str.replace(/[\t\n\f\r ]{2,}/g, " ")); +} +exports.stripAndCollapseASCIIWhitespace = stripAndCollapseASCIIWhitespace; +/** + * Collects a sequence of code points matching a given condition from the input + * string. + * + * @param condition - a condition to match + * @param input - a string + * @param options - starting position + */ +function collectASequenceOfCodePoints(condition, input, options) { + /** + * 1. Let result be the empty string. + * 2. While position doesn’t point past the end of input and the code point at + * position within input meets the condition condition: + * 2.1. Append that code point to the end of result. + * 2.2. Advance position by 1. + * 3. Return result. + */ + if (!util_1.isArray(input)) + return collectASequenceOfCodePoints(condition, Array.from(input), options); + let result = ""; + while (options.position < input.length && !!condition.call(null, input[options.position])) { + result += input[options.position]; + options.position++; + } + return result; +} +exports.collectASequenceOfCodePoints = collectASequenceOfCodePoints; +/** + * Skips over ASCII whitespace. + * + * @param input - input string + * @param options - starting position + */ +function skipASCIIWhitespace(input, options) { + /** + * To skip ASCII whitespace within a string input given a position variable + * position, collect a sequence of code points that are ASCII whitespace from + * input given position. The collected code points are not used, but position + * is still updated. + */ + collectASequenceOfCodePoints(str => CodePoints_1.ASCIIWhiteSpace.test(str), input, options); +} +exports.skipASCIIWhitespace = skipASCIIWhitespace; +/** + * Solits a string at the given delimiter. + * + * @param input - input string + * @param delimiter - a delimiter string + */ +function strictlySplit(input, delimiter) { + /** + * 1. Let position be a position variable for input, initially pointing at the + * start of input. + * 2. Let tokens be a list of strings, initially empty. + * 3. Let token be the result of collecting a sequence of code points that are + * not equal to delimiter from input, given position. + * 4. Append token to tokens. + * 5. While position is not past the end of input: + * 5.1. Assert: the code point at position within input is delimiter. + * 5.2. Advance position by 1. + * 5.3. Let token be the result of collecting a sequence of code points that + * are not equal to delimiter from input, given position. + * 5.4. Append token to tokens. + * 6. Return tokens. + */ + if (!util_1.isArray(input)) + return strictlySplit(Array.from(input), delimiter); + const options = { position: 0 }; + const tokens = []; + let token = collectASequenceOfCodePoints(str => delimiter !== str, input, options); + tokens.push(token); + while (options.position < input.length) { + console.assert(input[options.position] === delimiter, "strictlySplit found no delimiter in input string."); + options.position++; + token = collectASequenceOfCodePoints(str => delimiter !== str, input, options); + tokens.push(token); + } + return tokens; +} +exports.strictlySplit = strictlySplit; +/** + * Splits a string on ASCII whitespace. + * + * @param input - a string + */ +function splitAStringOnASCIIWhitespace(input) { + /** + * 1. Let position be a position variable for input, initially pointing at the + * start of input. + * 2. Let tokens be a list of strings, initially empty. + * 3. Skip ASCII whitespace within input given position. + * 4. While position is not past the end of input: + * 4.1. Let token be the result of collecting a sequence of code points that + * are not ASCII whitespace from input, given position. + * 4.2. Append token to tokens. + * 4.3. Skip ASCII whitespace within input given position. + * 5. Return tokens. + */ + if (!util_1.isArray(input)) + return splitAStringOnASCIIWhitespace(Array.from(input)); + const options = { position: 0 }; + const tokens = []; + skipASCIIWhitespace(input, options); + while (options.position < input.length) { + const token = collectASequenceOfCodePoints(str => !CodePoints_1.ASCIIWhiteSpace.test(str), input, options); + tokens.push(token); + skipASCIIWhitespace(input, options); + } + return tokens; +} +exports.splitAStringOnASCIIWhitespace = splitAStringOnASCIIWhitespace; +/** + * Splits a string on commas. + * + * @param input - a string + */ +function splitAStringOnCommas(input) { + /** + * 1. Let position be a position variable for input, initially pointing at the + * start of input. + * 2. Let tokens be a list of strings, initially empty. + * 3. While position is not past the end of input: + * 3.1. Let token be the result of collecting a sequence of code points that + * are not U+002C (,) from input, given position. + * 3.2. Strip leading and trailing ASCII whitespace from token. + * 3.3. Append token to tokens. + * 3.4. If position is not past the end of input, then: + * 3.4.1. Assert: the code point at position within input is U+002C (,). + * 3.4.2. Advance position by 1. + * 4. Return tokens. + */ + if (!util_1.isArray(input)) + return splitAStringOnCommas(Array.from(input)); + const options = { position: 0 }; + const tokens = []; + while (options.position < input.length) { + const token = collectASequenceOfCodePoints(str => str !== ',', input, options); + tokens.push(stripLeadingAndTrailingASCIIWhitespace(token)); + if (options.position < input.length) { + console.assert(input[options.position] === ',', "splitAStringOnCommas found no delimiter in input string."); + options.position++; + } + } + return tokens; +} +exports.splitAStringOnCommas = splitAStringOnCommas; +/** + * Concatenates a list of strings with the given separator. + * + * @param list - a list of strings + * @param separator - a separator string + */ +function concatenate(list, separator = "") { + /** + * 1. If list is empty, then return the empty string. + * 2. If separator is not given, then set separator to the empty string. + * 3. Return a string whose contents are list’s items, in order, separated + * from each other by separator. + */ + if (list.length === 0) + return ""; + return list.join(separator); +} +exports.concatenate = concatenate; +//# sourceMappingURL=String.js.map + +/***/ }), + +/***/ 669: +/***/ (function(module) { + +module.exports = require("util"); + +/***/ }), + +/***/ 672: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var _a; +Object.defineProperty(exports, "__esModule", { value: true }); +const assert_1 = __webpack_require__(357); +const fs = __webpack_require__(747); +const path = __webpack_require__(622); +_a = fs.promises, exports.chmod = _a.chmod, exports.copyFile = _a.copyFile, exports.lstat = _a.lstat, exports.mkdir = _a.mkdir, exports.readdir = _a.readdir, exports.readlink = _a.readlink, exports.rename = _a.rename, exports.rmdir = _a.rmdir, exports.stat = _a.stat, exports.symlink = _a.symlink, exports.unlink = _a.unlink; +exports.IS_WINDOWS = process.platform === 'win32'; +function exists(fsPath) { + return __awaiter(this, void 0, void 0, function* () { + try { + yield exports.stat(fsPath); + } + catch (err) { + if (err.code === 'ENOENT') { + return false; + } + throw err; + } + return true; + }); +} +exports.exists = exists; +function isDirectory(fsPath, useStat = false) { + return __awaiter(this, void 0, void 0, function* () { + const stats = useStat ? yield exports.stat(fsPath) : yield exports.lstat(fsPath); + return stats.isDirectory(); + }); +} +exports.isDirectory = isDirectory; +/** + * On OSX/Linux, true if path starts with '/'. On Windows, true for paths like: + * \, \hello, \\hello\share, C:, and C:\hello (and corresponding alternate separator cases). + */ +function isRooted(p) { + p = normalizeSeparators(p); + if (!p) { + throw new Error('isRooted() parameter "p" cannot be empty'); + } + if (exports.IS_WINDOWS) { + return (p.startsWith('\\') || /^[A-Z]:/i.test(p) // e.g. \ or \hello or \\hello + ); // e.g. C: or C:\hello + } + return p.startsWith('/'); +} +exports.isRooted = isRooted; +/** + * Recursively create a directory at `fsPath`. + * + * This implementation is optimistic, meaning it attempts to create the full + * path first, and backs up the path stack from there. + * + * @param fsPath The path to create + * @param maxDepth The maximum recursion depth + * @param depth The current recursion depth + */ +function mkdirP(fsPath, maxDepth = 1000, depth = 1) { + return __awaiter(this, void 0, void 0, function* () { + assert_1.ok(fsPath, 'a path argument must be provided'); + fsPath = path.resolve(fsPath); + if (depth >= maxDepth) + return exports.mkdir(fsPath); + try { + yield exports.mkdir(fsPath); + return; + } + catch (err) { + switch (err.code) { + case 'ENOENT': { + yield mkdirP(path.dirname(fsPath), maxDepth, depth + 1); + yield exports.mkdir(fsPath); + return; + } + default: { + let stats; + try { + stats = yield exports.stat(fsPath); + } + catch (err2) { + throw err; + } + if (!stats.isDirectory()) + throw err; + } + } + } + }); +} +exports.mkdirP = mkdirP; +/** + * Best effort attempt to determine whether a file exists and is executable. + * @param filePath file path to check + * @param extensions additional file extensions to try + * @return if file exists and is executable, returns the file path. otherwise empty string. + */ +function tryGetExecutablePath(filePath, extensions) { + return __awaiter(this, void 0, void 0, function* () { + let stats = undefined; + try { + // test file exists + stats = yield exports.stat(filePath); + } + catch (err) { + if (err.code !== 'ENOENT') { + // eslint-disable-next-line no-console + console.log(`Unexpected error attempting to determine if executable file exists '${filePath}': ${err}`); + } + } + if (stats && stats.isFile()) { + if (exports.IS_WINDOWS) { + // on Windows, test for valid extension + const upperExt = path.extname(filePath).toUpperCase(); + if (extensions.some(validExt => validExt.toUpperCase() === upperExt)) { + return filePath; + } + } + else { + if (isUnixExecutable(stats)) { + return filePath; + } + } + } + // try each extension + const originalFilePath = filePath; + for (const extension of extensions) { + filePath = originalFilePath + extension; + stats = undefined; + try { + stats = yield exports.stat(filePath); + } + catch (err) { + if (err.code !== 'ENOENT') { + // eslint-disable-next-line no-console + console.log(`Unexpected error attempting to determine if executable file exists '${filePath}': ${err}`); + } + } + if (stats && stats.isFile()) { + if (exports.IS_WINDOWS) { + // preserve the case of the actual file (since an extension was appended) + try { + const directory = path.dirname(filePath); + const upperName = path.basename(filePath).toUpperCase(); + for (const actualName of yield exports.readdir(directory)) { + if (upperName === actualName.toUpperCase()) { + filePath = path.join(directory, actualName); + break; + } + } + } + catch (err) { + // eslint-disable-next-line no-console + console.log(`Unexpected error attempting to determine the actual case of the file '${filePath}': ${err}`); + } + return filePath; + } + else { + if (isUnixExecutable(stats)) { + return filePath; + } + } + } + } + return ''; + }); +} +exports.tryGetExecutablePath = tryGetExecutablePath; +function normalizeSeparators(p) { + p = p || ''; + if (exports.IS_WINDOWS) { + // convert slashes on Windows + p = p.replace(/\//g, '\\'); + // remove redundant slashes + return p.replace(/\\\\+/g, '\\'); + } + // remove redundant slashes + return p.replace(/\/\/+/g, '/'); +} +// on Mac/Linux, test the execute bit +// R W X R W X R W X +// 256 128 64 32 16 8 4 2 1 +function isUnixExecutable(stats) { + return ((stats.mode & 1) > 0 || + ((stats.mode & 8) > 0 && stats.gid === process.getgid()) || + ((stats.mode & 64) > 0 && stats.uid === process.getuid())); +} +//# sourceMappingURL=io-util.js.map + +/***/ }), + +/***/ 686: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +// Export classes +var XMLSerializerImpl_1 = __webpack_require__(98); +exports.XMLSerializer = XMLSerializerImpl_1.XMLSerializerImpl; +//# sourceMappingURL=index.js.map + +/***/ }), + +/***/ 688: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const AbstractRangeImpl_1 = __webpack_require__(537); +const DOMException_1 = __webpack_require__(35); +const util_1 = __webpack_require__(918); +/** + * Represents a static range. + */ +class StaticRangeImpl extends AbstractRangeImpl_1.AbstractRangeImpl { + /** + * Initializes a new instance of `StaticRange`. + */ + constructor(init) { + super(); + /** + * 1. If init’s startContainer or endContainer is a DocumentType or Attr + * node, then throw an "InvalidNodeTypeError" DOMException. + * 2. Let staticRange be a new StaticRange object. + * 3. Set staticRange’s start to (init’s startContainer, init’s startOffset) + * and end to (init’s endContainer, init’s endOffset). + * 4. Return staticRange. + */ + if (util_1.Guard.isDocumentTypeNode(init.startContainer) || util_1.Guard.isAttrNode(init.startContainer) || + util_1.Guard.isDocumentTypeNode(init.endContainer) || util_1.Guard.isAttrNode(init.endContainer)) { + throw new DOMException_1.InvalidNodeTypeError(); + } + this._start = [init.startContainer, init.startOffset]; + this._end = [init.endContainer, init.endOffset]; + } +} +exports.StaticRangeImpl = StaticRangeImpl; +//# sourceMappingURL=StaticRangeImpl.js.map + +/***/ }), + +/***/ 693: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const util_1 = __webpack_require__(42); +/** + * Adds the given item to the end of the set. + * + * @param set - a set + * @param item - an item + */ +function append(set, item) { + set.add(item); +} +exports.append = append; +/** + * Extends a set by appending all items from another set. + * + * @param setA - a list to extend + * @param setB - a list containing items to append to `setA` + */ +function extend(setA, setB) { + setB.forEach(setA.add, setA); +} +exports.extend = extend; +/** + * Inserts the given item to the start of the set. + * + * @param set - a set + * @param item - an item + */ +function prepend(set, item) { + const cloned = new Set(set); + set.clear(); + set.add(item); + cloned.forEach(set.add, set); +} +exports.prepend = prepend; +/** + * Replaces the given item or all items matching condition with a new item. + * + * @param set - a set + * @param conditionOrItem - an item to replace or a condition matching items + * to replace + * @param item - an item + */ +function replace(set, conditionOrItem, newItem) { + const newSet = new Set(); + for (const oldItem of set) { + if (util_1.isFunction(conditionOrItem)) { + if (!!conditionOrItem.call(null, oldItem)) { + newSet.add(newItem); + } + else { + newSet.add(oldItem); + } + } + else if (oldItem === conditionOrItem) { + newSet.add(newItem); + } + else { + newSet.add(oldItem); + } + } + set.clear(); + newSet.forEach(set.add, set); +} +exports.replace = replace; +/** + * Inserts the given item before the given index. + * + * @param set - a set + * @param item - an item + */ +function insert(set, item, index) { + const newSet = new Set(); + let i = 0; + for (const oldItem of set) { + if (i === index) + newSet.add(item); + newSet.add(oldItem); + i++; + } + set.clear(); + newSet.forEach(set.add, set); +} +exports.insert = insert; +/** + * Removes the given item or all items matching condition. + * + * @param set - a set + * @param conditionOrItem - an item to remove or a condition matching items + * to remove + */ +function remove(set, conditionOrItem) { + if (!util_1.isFunction(conditionOrItem)) { + set.delete(conditionOrItem); + } + else { + const toRemove = []; + for (const item of set) { + if (!!conditionOrItem.call(null, item)) { + toRemove.push(item); + } + } + for (const oldItem of toRemove) { + set.delete(oldItem); + } + } +} +exports.remove = remove; +/** + * Removes all items from the set. + */ +function empty(set) { + set.clear(); +} +exports.empty = empty; +/** + * Determines if the set contains the given item or any items matching + * condition. + * + * @param set - a set + * @param conditionOrItem - an item to a condition to match + */ +function contains(set, conditionOrItem) { + if (!util_1.isFunction(conditionOrItem)) { + return set.has(conditionOrItem); + } + else { + for (const oldItem of set) { + if (!!conditionOrItem.call(null, oldItem)) { + return true; + } + } + } + return false; +} +exports.contains = contains; +/** + * Returns the count of items in the set matching the given condition. + * + * @param set - a set + * @param condition - an optional condition to match + */ +function size(set, condition) { + if (condition === undefined) { + return set.size; + } + else { + let count = 0; + for (const item of set) { + if (!!condition.call(null, item)) { + count++; + } + } + return count; + } +} +exports.size = size; +/** + * Determines if the set is empty. + * + * @param set - a set + */ +function isEmpty(set) { + return set.size === 0; +} +exports.isEmpty = isEmpty; +/** + * Returns an iterator for the items of the set. + * + * @param set - a set + * @param condition - an optional condition to match + */ +function* forEach(set, condition) { + if (condition === undefined) { + yield* set; + } + else { + for (const item of set) { + if (!!condition.call(null, item)) { + yield item; + } + } + } +} +exports.forEach = forEach; +/** + * Creates and returns a shallow clone of set. + * + * @param set - a set + */ +function clone(set) { + return new Set(set); +} +exports.clone = clone; +/** + * Returns a new set containing items from the set sorted in ascending + * order. + * + * @param set - a set + * @param lessThanAlgo - a function that returns `true` if its first argument + * is less than its second argument, and `false` otherwise. + */ +function sortInAscendingOrder(set, lessThanAlgo) { + const list = new Array(...set); + list.sort((itemA, itemB) => lessThanAlgo.call(null, itemA, itemB) ? -1 : 1); + return new Set(list); +} +exports.sortInAscendingOrder = sortInAscendingOrder; +/** + * Returns a new set containing items from the set sorted in descending + * order. + * + * @param set - a set + * @param lessThanAlgo - a function that returns `true` if its first argument + * is less than its second argument, and `false` otherwise. + */ +function sortInDescendingOrder(set, lessThanAlgo) { + const list = new Array(...set); + list.sort((itemA, itemB) => lessThanAlgo.call(null, itemA, itemB) ? 1 : -1); + return new Set(list); +} +exports.sortInDescendingOrder = sortInDescendingOrder; +/** + * Determines if a set is a subset of another set. + * + * @param subset - a set + * @param superset - a superset possibly containing all items from `subset`. + */ +function isSubsetOf(subset, superset) { + for (const item of subset) { + if (!superset.has(item)) + return false; + } + return true; +} +exports.isSubsetOf = isSubsetOf; +/** + * Determines if a set is a superset of another set. + * + * @param superset - a set + * @param subset - a subset possibly contained within `superset`. + */ +function isSupersetOf(superset, subset) { + return isSubsetOf(subset, superset); +} +exports.isSupersetOf = isSupersetOf; +/** + * Returns a new set with items that are contained in both sets. + * + * @param setA - a set + * @param setB - a set + */ +function intersection(setA, setB) { + const newSet = new Set(); + for (const item of setA) { + if (setB.has(item)) + newSet.add(item); + } + return newSet; +} +exports.intersection = intersection; +/** + * Returns a new set with items from both sets. + * + * @param setA - a set + * @param setB - a set + */ +function union(setA, setB) { + const newSet = new Set(setA); + setB.forEach(newSet.add, newSet); + return newSet; +} +exports.union = union; +/** + * Returns a set of integers from `n` to `m` inclusive. + * + * @param n - starting number + * @param m - ending number + */ +function range(n, m) { + const newSet = new Set(); + for (let i = n; i <= m; i++) { + newSet.add(i); + } + return newSet; +} +exports.range = range; +//# sourceMappingURL=Set.js.map + +/***/ }), + +/***/ 695: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const interfaces_1 = __webpack_require__(970); +const NodeImpl_1 = __webpack_require__(935); +const DOMException_1 = __webpack_require__(35); +const infra_1 = __webpack_require__(23); +const algorithm_1 = __webpack_require__(163); +const WebIDLAlgorithm_1 = __webpack_require__(495); +/** + * Represents an element node. + */ +class ElementImpl extends NodeImpl_1.NodeImpl { + /** + * Initializes a new instance of `Element`. + */ + constructor() { + super(); + this._children = new Set(); + this._namespace = null; + this._namespacePrefix = null; + this._localName = ""; + this._customElementState = "undefined"; + this._customElementDefinition = null; + this._is = null; + this._shadowRoot = null; + this._attributeList = algorithm_1.create_namedNodeMap(this); + this._attributeChangeSteps = []; + this._name = ''; + this._assignedSlot = null; + } + /** @inheritdoc */ + get namespaceURI() { return this._namespace; } + /** @inheritdoc */ + get prefix() { return this._namespacePrefix; } + /** @inheritdoc */ + get localName() { return this._localName; } + /** @inheritdoc */ + get tagName() { return this._htmlUppercasedQualifiedName; } + /** @inheritdoc */ + get id() { + return algorithm_1.element_getAnAttributeValue(this, "id"); + } + set id(value) { + algorithm_1.element_setAnAttributeValue(this, "id", value); + } + /** @inheritdoc */ + get className() { + return algorithm_1.element_getAnAttributeValue(this, "class"); + } + set className(value) { + algorithm_1.element_setAnAttributeValue(this, "class", value); + } + /** @inheritdoc */ + get classList() { + let attr = algorithm_1.element_getAnAttributeByName("class", this); + if (attr === null) { + attr = algorithm_1.create_attr(this._nodeDocument, "class"); + } + return algorithm_1.create_domTokenList(this, attr); + } + /** @inheritdoc */ + get slot() { + return algorithm_1.element_getAnAttributeValue(this, "slot"); + } + set slot(value) { + algorithm_1.element_setAnAttributeValue(this, "slot", value); + } + /** @inheritdoc */ + hasAttributes() { + return this._attributeList.length !== 0; + } + /** @inheritdoc */ + get attributes() { return this._attributeList; } + /** @inheritdoc */ + getAttributeNames() { + /** + * The getAttributeNames() method, when invoked, must return the qualified + * names of the attributes in context object’s attribute list, in order, + * and a new list otherwise. + */ + const names = []; + for (const attr of this._attributeList) { + names.push(attr._qualifiedName); + } + return names; + } + /** @inheritdoc */ + getAttribute(qualifiedName) { + /** + * 1. Let attr be the result of getting an attribute given qualifiedName + * and the context object. + * 2. If attr is null, return null. + * 3. Return attr’s value. + */ + const attr = algorithm_1.element_getAnAttributeByName(qualifiedName, this); + return (attr ? attr._value : null); + } + /** @inheritdoc */ + getAttributeNS(namespace, localName) { + /** + * 1. Let attr be the result of getting an attribute given namespace, + * localName, and the context object. + * 2. If attr is null, return null. + * 3. Return attr’s value. + */ + const attr = algorithm_1.element_getAnAttributeByNamespaceAndLocalName(namespace, localName, this); + return (attr ? attr._value : null); + } + /** @inheritdoc */ + setAttribute(qualifiedName, value) { + /** + * 1. If qualifiedName does not match the Name production in XML, then + * throw an "InvalidCharacterError" DOMException. + */ + if (!algorithm_1.xml_isName(qualifiedName)) + throw new DOMException_1.InvalidCharacterError(); + /** + * 2. If the context object is in the HTML namespace and its node document + * is an HTML document, then set qualifiedName to qualifiedName in ASCII + * lowercase. + */ + if (this._namespace === infra_1.namespace.HTML && this._nodeDocument._type === "html") { + qualifiedName = qualifiedName.toLowerCase(); + } + /** + * 3. Let attribute be the first attribute in context object’s attribute + * list whose qualified name is qualifiedName, and null otherwise. + */ + let attribute = null; + for (let i = 0; i < this._attributeList.length; i++) { + const attr = this._attributeList[i]; + if (attr._qualifiedName === qualifiedName) { + attribute = attr; + break; + } + } + /** + * 4. If attribute is null, create an attribute whose local name is + * qualifiedName, value is value, and node document is context object’s + * node document, then append this attribute to context object, and + * then return. + */ + if (attribute === null) { + attribute = algorithm_1.create_attr(this._nodeDocument, qualifiedName); + attribute._value = value; + algorithm_1.element_append(attribute, this); + return; + } + /** + * 5. Change attribute from context object to value. + */ + algorithm_1.element_change(attribute, this, value); + } + /** @inheritdoc */ + setAttributeNS(namespace, qualifiedName, value) { + /** + * 1. Let namespace, prefix, and localName be the result of passing + * namespace and qualifiedName to validate and extract. + * 2. Set an attribute value for the context object using localName, value, + * and also prefix and namespace. + */ + const [ns, prefix, localName] = algorithm_1.namespace_validateAndExtract(namespace, qualifiedName); + algorithm_1.element_setAnAttributeValue(this, localName, value, prefix, ns); + } + /** @inheritdoc */ + removeAttribute(qualifiedName) { + /** + * The removeAttribute(qualifiedName) method, when invoked, must remove an + * attribute given qualifiedName and the context object, and then return + * undefined. + */ + algorithm_1.element_removeAnAttributeByName(qualifiedName, this); + } + /** @inheritdoc */ + removeAttributeNS(namespace, localName) { + /** + * The removeAttributeNS(namespace, localName) method, when invoked, must + * remove an attribute given namespace, localName, and context object, and + * then return undefined. + */ + algorithm_1.element_removeAnAttributeByNamespaceAndLocalName(namespace, localName, this); + } + /** @inheritdoc */ + hasAttribute(qualifiedName) { + /** + * 1. If the context object is in the HTML namespace and its node document + * is an HTML document, then set qualifiedName to qualifiedName in ASCII + * lowercase. + * 2. Return true if the context object has an attribute whose qualified + * name is qualifiedName, and false otherwise. + */ + if (this._namespace === infra_1.namespace.HTML && this._nodeDocument._type === "html") { + qualifiedName = qualifiedName.toLowerCase(); + } + for (let i = 0; i < this._attributeList.length; i++) { + const attr = this._attributeList[i]; + if (attr._qualifiedName === qualifiedName) { + return true; + } + } + return false; + } + /** @inheritdoc */ + toggleAttribute(qualifiedName, force) { + /** + * 1. If qualifiedName does not match the Name production in XML, then + * throw an "InvalidCharacterError" DOMException. + */ + if (!algorithm_1.xml_isName(qualifiedName)) + throw new DOMException_1.InvalidCharacterError(); + /** + * 2. If the context object is in the HTML namespace and its node document + * is an HTML document, then set qualifiedName to qualifiedName in ASCII + * lowercase. + */ + if (this._namespace === infra_1.namespace.HTML && this._nodeDocument._type === "html") { + qualifiedName = qualifiedName.toLowerCase(); + } + /** + * 3. Let attribute be the first attribute in the context object’s attribute + * list whose qualified name is qualifiedName, and null otherwise. + */ + let attribute = null; + for (let i = 0; i < this._attributeList.length; i++) { + const attr = this._attributeList[i]; + if (attr._qualifiedName === qualifiedName) { + attribute = attr; + break; + } + } + if (attribute === null) { + /** + * 4. If attribute is null, then: + * 4.1. If force is not given or is true, create an attribute whose local + * name is qualifiedName, value is the empty string, and node document is + * the context object’s node document, then append this attribute to the + * context object, and then return true. + * 4.2. Return false. + */ + if (force === undefined || force === true) { + attribute = algorithm_1.create_attr(this._nodeDocument, qualifiedName); + attribute._value = ''; + algorithm_1.element_append(attribute, this); + return true; + } + return false; + } + else if (force === undefined || force === false) { + /** + * 5. Otherwise, if force is not given or is false, remove an attribute + * given qualifiedName and the context object, and then return false. + */ + algorithm_1.element_removeAnAttributeByName(qualifiedName, this); + return false; + } + /** + * 6. Return true. + */ + return true; + } + /** @inheritdoc */ + hasAttributeNS(namespace, localName) { + /** + * 1. If namespace is the empty string, set it to null. + * 2. Return true if the context object has an attribute whose namespace is + * namespace and local name is localName, and false otherwise. + */ + const ns = namespace || null; + for (let i = 0; i < this._attributeList.length; i++) { + const attr = this._attributeList[i]; + if (attr._namespace === ns && attr._localName === localName) { + return true; + } + } + return false; + } + /** @inheritdoc */ + getAttributeNode(qualifiedName) { + /** + * The getAttributeNode(qualifiedName) method, when invoked, must return the + * result of getting an attribute given qualifiedName and context object. + */ + return algorithm_1.element_getAnAttributeByName(qualifiedName, this); + } + /** @inheritdoc */ + getAttributeNodeNS(namespace, localName) { + /** + * The getAttributeNodeNS(namespace, localName) method, when invoked, must + * return the result of getting an attribute given namespace, localName, and + * the context object. + */ + return algorithm_1.element_getAnAttributeByNamespaceAndLocalName(namespace, localName, this); + } + /** @inheritdoc */ + setAttributeNode(attr) { + /** + * The setAttributeNode(attr) and setAttributeNodeNS(attr) methods, when + * invoked, must return the result of setting an attribute given attr and + * the context object. + */ + return algorithm_1.element_setAnAttribute(attr, this); + } + /** @inheritdoc */ + setAttributeNodeNS(attr) { + return algorithm_1.element_setAnAttribute(attr, this); + } + /** @inheritdoc */ + removeAttributeNode(attr) { + /** + * 1. If context object’s attribute list does not contain attr, then throw + * a "NotFoundError" DOMException. + * 2. Remove attr from context object. + * 3. Return attr. + */ + let found = false; + for (let i = 0; i < this._attributeList.length; i++) { + const attribute = this._attributeList[i]; + if (attribute === attr) { + found = true; + break; + } + } + if (!found) + throw new DOMException_1.NotFoundError(); + algorithm_1.element_remove(attr, this); + return attr; + } + /** @inheritdoc */ + attachShadow(init) { + /** + * 1. If context object’s namespace is not the HTML namespace, then throw a + * "NotSupportedError" DOMException. + */ + if (this._namespace !== infra_1.namespace.HTML) + throw new DOMException_1.NotSupportedError(); + /** + * 2. If context object’s local name is not a valid custom element name, + * "article", "aside", "blockquote", "body", "div", "footer", "h1", "h2", + * "h3", "h4", "h5", "h6", "header", "main" "nav", "p", "section", + * or "span", then throw a "NotSupportedError" DOMException. + */ + if (!algorithm_1.customElement_isValidCustomElementName(this._localName) && + !algorithm_1.customElement_isValidShadowHostName(this._localName)) + throw new DOMException_1.NotSupportedError(); + /** + * 3. If context object’s local name is a valid custom element name, + * or context object’s is value is not null, then: + * 3.1. Let definition be the result of looking up a custom element + * definition given context object’s node document, its namespace, its + * local name, and its is value. + * 3.2. If definition is not null and definition’s disable shadow is true, + * then throw a "NotSupportedError" DOMException. + */ + if (algorithm_1.customElement_isValidCustomElementName(this._localName) || this._is !== null) { + const definition = algorithm_1.customElement_lookUpACustomElementDefinition(this._nodeDocument, this._namespace, this._localName, this._is); + if (definition !== null && definition.disableShadow === true) { + throw new DOMException_1.NotSupportedError(); + } + } + /** + * 4. If context object is a shadow host, then throw an "NotSupportedError" + * DOMException. + */ + if (this._shadowRoot !== null) + throw new DOMException_1.NotSupportedError(); + /** + * 5. Let shadow be a new shadow root whose node document is context + * object’s node document, host is context object, and mode is init’s mode. + * 6. Set context object’s shadow root to shadow. + * 7. Return shadow. + */ + const shadow = algorithm_1.create_shadowRoot(this._nodeDocument, this); + shadow._mode = init.mode; + this._shadowRoot = shadow; + return shadow; + } + /** @inheritdoc */ + get shadowRoot() { + /** + * 1. Let shadow be context object’s shadow root. + * 2. If shadow is null or its mode is "closed", then return null. + * 3. Return shadow. + */ + const shadow = this._shadowRoot; + if (shadow === null || shadow.mode === "closed") + return null; + else + return shadow; + } + /** @inheritdoc */ + closest(selectors) { + /** + * TODO: Selectors + * 1. Let s be the result of parse a selector from selectors. [SELECTORS4] + * 2. If s is failure, throw a "SyntaxError" DOMException. + * 3. Let elements be context object’s inclusive ancestors that are + * elements, in reverse tree order. + * 4. For each element in elements, if match a selector against an element, + * using s, element, and :scope element context object, returns success, + * return element. [SELECTORS4] + * 5. Return null. + */ + throw new DOMException_1.NotImplementedError(); + } + /** @inheritdoc */ + matches(selectors) { + /** + * TODO: Selectors + * 1. Let s be the result of parse a selector from selectors. [SELECTORS4] + * 2. If s is failure, throw a "SyntaxError" DOMException. + * 3. Return true if the result of match a selector against an element, + * using s, element, and :scope element context object, returns success, + * and false otherwise. [SELECTORS4] + */ + throw new DOMException_1.NotImplementedError(); + } + /** @inheritdoc */ + webkitMatchesSelector(selectors) { + return this.matches(selectors); + } + /** @inheritdoc */ + getElementsByTagName(qualifiedName) { + /** + * The getElementsByTagName(qualifiedName) method, when invoked, must return + * the list of elements with qualified name qualifiedName for context + * object. + */ + return algorithm_1.node_listOfElementsWithQualifiedName(qualifiedName, this); + } + /** @inheritdoc */ + getElementsByTagNameNS(namespace, localName) { + /** + * The getElementsByTagNameNS(namespace, localName) method, when invoked, + * must return the list of elements with namespace namespace and local name + * localName for context object. + */ + return algorithm_1.node_listOfElementsWithNamespace(namespace, localName, this); + } + /** @inheritdoc */ + getElementsByClassName(classNames) { + /** + * The getElementsByClassName(classNames) method, when invoked, must return + * the list of elements with class names classNames for context object. + */ + return algorithm_1.node_listOfElementsWithClassNames(classNames, this); + } + /** @inheritdoc */ + insertAdjacentElement(where, element) { + /** + * The insertAdjacentElement(where, element) method, when invoked, must + * return the result of running insert adjacent, given context object, + * where, and element. + */ + return algorithm_1.element_insertAdjacent(this, where, element); + } + /** @inheritdoc */ + insertAdjacentText(where, data) { + /** + * 1. Let text be a new Text node whose data is data and node document is + * context object’s node document. + * 2. Run insert adjacent, given context object, where, and text. + */ + const text = algorithm_1.create_text(this._nodeDocument, data); + algorithm_1.element_insertAdjacent(this, where, text); + } + /** + * Returns the qualified name. + */ + get _qualifiedName() { + /** + * An element’s qualified name is its local name if its namespace prefix is + * null, and its namespace prefix, followed by ":", followed by its + * local name, otherwise. + */ + return (this._namespacePrefix ? + this._namespacePrefix + ':' + this._localName : + this._localName); + } + /** + * Returns the upper-cased qualified name for a html element. + */ + get _htmlUppercasedQualifiedName() { + /** + * 1. Let qualifiedName be context object’s qualified name. + * 2. If the context object is in the HTML namespace and its node document + * is an HTML document, then set qualifiedName to qualifiedName in ASCII + * uppercase. + * 3. Return qualifiedName. + */ + let qualifiedName = this._qualifiedName; + if (this._namespace === infra_1.namespace.HTML && this._nodeDocument._type === "html") { + qualifiedName = qualifiedName.toUpperCase(); + } + return qualifiedName; + } + // MIXIN: ParentNode + /* istanbul ignore next */ + get children() { throw new Error("Mixin: ParentNode not implemented."); } + /* istanbul ignore next */ + get firstElementChild() { throw new Error("Mixin: ParentNode not implemented."); } + /* istanbul ignore next */ + get lastElementChild() { throw new Error("Mixin: ParentNode not implemented."); } + /* istanbul ignore next */ + get childElementCount() { throw new Error("Mixin: ParentNode not implemented."); } + /* istanbul ignore next */ + prepend(...nodes) { throw new Error("Mixin: ParentNode not implemented."); } + /* istanbul ignore next */ + append(...nodes) { throw new Error("Mixin: ParentNode not implemented."); } + /* istanbul ignore next */ + querySelector(selectors) { throw new Error("Mixin: ParentNode not implemented."); } + /* istanbul ignore next */ + querySelectorAll(selectors) { throw new Error("Mixin: ParentNode not implemented."); } + // MIXIN: NonDocumentTypeChildNode + /* istanbul ignore next */ + get previousElementSibling() { throw new Error("Mixin: NonDocumentTypeChildNode not implemented."); } + /* istanbul ignore next */ + get nextElementSibling() { throw new Error("Mixin: NonDocumentTypeChildNode not implemented."); } + // MIXIN: ChildNode + /* istanbul ignore next */ + before(...nodes) { throw new Error("Mixin: ChildNode not implemented."); } + /* istanbul ignore next */ + after(...nodes) { throw new Error("Mixin: ChildNode not implemented."); } + /* istanbul ignore next */ + replaceWith(...nodes) { throw new Error("Mixin: ChildNode not implemented."); } + /* istanbul ignore next */ + remove() { throw new Error("Mixin: ChildNode not implemented."); } + // MIXIN: Slotable + /* istanbul ignore next */ + get assignedSlot() { throw new Error("Mixin: Slotable not implemented."); } + /** + * Creates a new `Element`. + * + * @param document - owner document + * @param localName - local name + * @param namespace - namespace + * @param prefix - namespace prefix + */ + static _create(document, localName, namespace = null, namespacePrefix = null) { + const node = new ElementImpl(); + node._localName = localName; + node._namespace = namespace; + node._namespacePrefix = namespacePrefix; + node._nodeDocument = document; + return node; + } +} +exports.ElementImpl = ElementImpl; +/** + * Initialize prototype properties + */ +WebIDLAlgorithm_1.idl_defineConst(ElementImpl.prototype, "_nodeType", interfaces_1.NodeType.Element); +//# sourceMappingURL=ElementImpl.js.map + +/***/ }), + +/***/ 699: +/***/ (function(__unusedmodule, exports) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * Represents a cache for storing order between equal objects. + * + * This cache is used when an algorithm compares two objects and finds them to + * be equal but still needs to establish an order between those two objects. + * When two such objects `a` and `b` are passed to the `check` method, a random + * number is generated with `Math.random()`. If the random number is less than + * `0.5` it is assumed that `a < b` otherwise `a > b`. The random number along + * with `a` and `b` is stored in the cache, so that subsequent checks result + * in the same consistent result. + * + * The cache has a size limit which is defined on initialization. + */ +class CompareCache { + /** + * Initializes a new instance of `CompareCache`. + * + * @param limit - maximum number of items to keep in the cache. When the limit + * is exceeded the first item is removed from the cache. + */ + constructor(limit = 1000) { + this._items = new Map(); + this._limit = limit; + } + /** + * Compares and caches the given objects. Returns `true` if `objA < objB` and + * `false` otherwise. + * + * @param objA - an item to compare + * @param objB - an item to compare + */ + check(objA, objB) { + if (this._items.get(objA) === objB) + return true; + else if (this._items.get(objB) === objA) + return false; + const result = (Math.random() < 0.5); + if (result) { + this._items.set(objA, objB); + } + else { + this._items.set(objB, objA); + } + if (this._items.size > this._limit) { + const it = this._items.keys().next(); + /* istanbul ignore else */ + if (!it.done) { + this._items.delete(it.value); + } + } + return result; + } +} +exports.CompareCache = CompareCache; +//# sourceMappingURL=CompareCache.js.map + +/***/ }), + +/***/ 704: +/***/ (function(__unusedmodule, exports) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * Represents a set of objects with a size limit. + */ +class FixedSizeSet { + /** + * Initializes a new instance of `FixedSizeSet`. + * + * @param limit - maximum number of items to keep in the set. When the limit + * is exceeded the first item is removed from the set. + */ + constructor(limit = 1000) { + this._items = new Set(); + this._limit = limit; + } + /** + * Adds a new item to the set. + * + * @param item - an item + */ + add(item) { + this._items.add(item); + if (this._items.size > this._limit) { + const it = this._items.values().next(); + /* istanbul ignore else */ + if (!it.done) { + this._items.delete(it.value); + } + } + return this; + } + /** + * Removes an item from the set. + * + * @param item - an item + */ + delete(item) { + return this._items.delete(item); + } + /** + * Determines if an item is in the set. + * + * @param item - an item + */ + has(item) { + return this._items.has(item); + } + /** + * Removes all items from the set. + */ + clear() { + this._items.clear(); + } + /** + * Gets the number of items in the set. + */ + get size() { return this._items.size; } + /** + * Applies the given callback function to all elements of the set. + */ + forEach(callback, thisArg) { + this._items.forEach(e => callback.call(thisArg, e, e, this)); + } + /** + * Iterates through the items in the set. + */ + *keys() { + yield* this._items.keys(); + } + /** + * Iterates through the items in the set. + */ + *values() { + yield* this._items.values(); + } + /** + * Iterates through the items in the set. + */ + *entries() { + yield* this._items.entries(); + } + /** + * Iterates through the items in the set. + */ + *[Symbol.iterator]() { + yield* this._items; + } + /** + * Returns the string tag of the set. + */ + get [Symbol.toStringTag]() { + return "FixedSizeSet"; + } +} +exports.FixedSizeSet = FixedSizeSet; +//# sourceMappingURL=FixedSizeSet.js.map + +/***/ }), + +/***/ 705: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const interfaces_1 = __webpack_require__(970); +const TraversalAlgorithm_1 = __webpack_require__(464); +/** + * Returns the first or last child node, or `null` if there are none. + * + * @param walker - the `TreeWalker` instance + * @param first - `true` to return the first child node, or `false` to + * return the last child node. + */ +function treeWalker_traverseChildren(walker, first) { + /** + * 1. Let node be walker’s current. + * 2. Set node to node’s first child if type is first, and node’s last child + * if type is last. + * 3. While node is non-null: + */ + let node = (first ? walker._current._firstChild : walker._current._lastChild); + while (node !== null) { + /** + * 3.1. Let result be the result of filtering node within walker. + */ + const result = TraversalAlgorithm_1.traversal_filter(walker, node); + if (result === interfaces_1.FilterResult.Accept) { + /** + * 3.2. If result is FILTER_ACCEPT, then set walker’s current to node and + * return node. + */ + walker._current = node; + return node; + } + else if (result === interfaces_1.FilterResult.Skip) { + /** + * 3.3. If result is FILTER_SKIP, then: + * 3.3.1. Let child be node’s first child if type is first, and node’s + * last child if type is last. + * 3.3.2. If child is non-null, then set node to child and continue. + */ + const child = (first ? node._firstChild : node._lastChild); + if (child !== null) { + node = child; + continue; + } + } + /** + * 3.4. While node is non-null: + */ + while (node !== null) { + /** + * 3.4.1. Let sibling be node’s next sibling if type is first, and + * node’s previous sibling if type is last. + * 3.4.2. If sibling is non-null, then set node to sibling and break. + */ + const sibling = (first ? node._nextSibling : node._previousSibling); + if (sibling !== null) { + node = sibling; + break; + } + /** + * 3.4.3. Let parent be node’s parent. + * 3.4.4. If parent is null, walker’s root, or walker’s current, then + * return null. + */ + const parent = node._parent; + if (parent === null || parent === walker._root || parent === walker._current) { + return null; + } + /** + * 3.4.5. Set node to parent. + */ + node = parent; + } + } + /** + * 5. Return null + */ + return null; +} +exports.treeWalker_traverseChildren = treeWalker_traverseChildren; +/** + * Returns the next or previous sibling node, or `null` if there are none. + * + * @param walker - the `TreeWalker` instance + * @param next - `true` to return the next sibling node, or `false` to + * return the previous sibling node. + */ +function treeWalker_traverseSiblings(walker, next) { + /** + * 1. Let node be walker’s current. + * 2. If node is root, then return null. + * 3. While node is non-null: + */ + let node = walker._current; + if (node === walker._root) + return null; + while (true) { + /** + * 3.1. Let sibling be node’s next sibling if type is next, and node’s + * previous sibling if type is previous. + * 3.2. While sibling is non-null: + */ + let sibling = (next ? node._nextSibling : node._previousSibling); + while (sibling !== null) { + /** + * 3.2.1. Set node to sibling. + * 3.2.2. Let result be the result of filtering node within walker. + * 3.2.3. If result is FILTER_ACCEPT, then set walker’s current to node + * and return node. + */ + node = sibling; + const result = TraversalAlgorithm_1.traversal_filter(walker, node); + if (result === interfaces_1.FilterResult.Accept) { + walker._current = node; + return node; + } + /** + * 3.2.4. Set sibling to node’s first child if type is next, and node’s + * last child if type is previous. + * 3.2.5. If result is FILTER_REJECT or sibling is null, then set + * sibling to node’s next sibling if type is next, and node’s previous + * sibling if type is previous. + */ + sibling = (next ? node._firstChild : node._lastChild); + if (result === interfaces_1.FilterResult.Reject || sibling === null) { + sibling = (next ? node._nextSibling : node._previousSibling); + } + } + /** + * 3.3. Set node to node’s parent. + * 3.4. If node is null or walker’s root, then return null. + */ + node = node._parent; + if (node === null || node === walker._root) { + return null; + } + /** + * 3.5. If the return value of filtering node within walker is FILTER_ACCEPT, + * then return null. + */ + if (TraversalAlgorithm_1.traversal_filter(walker, node) === interfaces_1.FilterResult.Accept) { + return null; + } + } +} +exports.treeWalker_traverseSiblings = treeWalker_traverseSiblings; +//# sourceMappingURL=TreeWalkerAlgorithm.js.map + +/***/ }), + +/***/ 710: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const EventAlgorithm_1 = __webpack_require__(108); +/** + * Adds an algorithm to the given abort signal. + * + * @param algorithm - an algorithm + * @param signal - abort signal + */ +function abort_add(algorithm, signal) { + /** + * 1. If signal’s aborted flag is set, then return. + * 2. Append algorithm to signal’s abort algorithms. + */ + if (signal._abortedFlag) + return; + signal._abortAlgorithms.add(algorithm); +} +exports.abort_add = abort_add; +/** + * Removes an algorithm from the given abort signal. + * + * @param algorithm - an algorithm + * @param signal - abort signal + */ +function abort_remove(algorithm, signal) { + /** + * To remove an algorithm algorithm from an AbortSignal signal, remove + * algorithm from signal’s abort algorithms. + */ + signal._abortAlgorithms.delete(algorithm); +} +exports.abort_remove = abort_remove; +/** + * Signals abort on the given abort signal. + * + * @param signal - abort signal + */ +function abort_signalAbort(signal) { + /** + * 1. If signal’s aborted flag is set, then return. + * 2. Set signal’s aborted flag. + * 3. For each algorithm in signal’s abort algorithms: run algorithm. + * 4. Empty signal’s abort algorithms. + * 5. Fire an event named abort at signal. + */ + if (signal._abortedFlag) + return; + signal._abortedFlag = true; + for (const algorithm of signal._abortAlgorithms) { + algorithm.call(signal); + } + signal._abortAlgorithms.clear(); + EventAlgorithm_1.event_fireAnEvent("abort", signal); +} +exports.abort_signalAbort = abort_signalAbort; +//# sourceMappingURL=AbortAlgorithm.js.map + +/***/ }), + +/***/ 722: +/***/ (function(module) { + +/** + * Convert array of 16 byte values to UUID string format of the form: + * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX + */ +var byteToHex = []; +for (var i = 0; i < 256; ++i) { + byteToHex[i] = (i + 0x100).toString(16).substr(1); +} + +function bytesToUuid(buf, offset) { + var i = offset || 0; + var bth = byteToHex; + // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4 + return ([ + bth[buf[i++]], bth[buf[i++]], + bth[buf[i++]], bth[buf[i++]], '-', + bth[buf[i++]], bth[buf[i++]], '-', + bth[buf[i++]], bth[buf[i++]], '-', + bth[buf[i++]], bth[buf[i++]], '-', + bth[buf[i++]], bth[buf[i++]], + bth[buf[i++]], bth[buf[i++]], + bth[buf[i++]], bth[buf[i++]] + ]).join(''); +} + +module.exports = bytesToUuid; + + +/***/ }), + +/***/ 724: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +var ObjectCache_1 = __webpack_require__(326); +exports.ObjectCache = ObjectCache_1.ObjectCache; +var CompareCache_1 = __webpack_require__(699); +exports.CompareCache = CompareCache_1.CompareCache; +var StringWalker_1 = __webpack_require__(260); +exports.StringWalker = StringWalker_1.StringWalker; +/** + * Applies the mixin to a given class. + * + * @param baseClass - class to receive the mixin + * @param mixinClass - mixin class + * @param overrides - an array with names of function overrides. Base class + * functions whose names are in this array will be kept by prepending an + * underscore to their names. + */ +function applyMixin(baseClass, mixinClass, ...overrides) { + Object.getOwnPropertyNames(mixinClass.prototype).forEach(name => { + if (overrides.includes(name)) { + const orgPropDesc = Object.getOwnPropertyDescriptor(baseClass.prototype, name); + /* istanbul ignore else */ + if (orgPropDesc) { + Object.defineProperty(baseClass.prototype, "_" + name, orgPropDesc); + } + } + const propDesc = Object.getOwnPropertyDescriptor(mixinClass.prototype, name); + /* istanbul ignore else */ + if (propDesc) { + Object.defineProperty(baseClass.prototype, name, propDesc); + } + }); +} +exports.applyMixin = applyMixin; +/** + * Applies default values to the given object. + * + * @param obj - an object + * @param defaults - an object with default values + * @param overwrite - if set to `true` defaults object always overwrites object + * values, whether they are `undefined` or not. + */ +function applyDefaults(obj, defaults, overwrite = false) { + const result = clone(obj || {}); + for (const [key, val] of forEachObject(defaults)) { + if (isObject(val)) { + result[key] = applyDefaults(result[key], val); + } + else if (overwrite || result[key] === undefined) { + result[key] = val; + } + } + return result; +} +exports.applyDefaults = applyDefaults; +/** + * Iterates over items pairs of an array. + * + * @param arr - array to iterate + */ +function* forEachArray(arr) { + yield* arr; +} +exports.forEachArray = forEachArray; +/** + * Iterates over key/value pairs of a map or object. + * + * @param obj - map or object to iterate + */ +function* forEachObject(obj) { + if (isMap(obj)) { + yield* obj; + } + else { + for (const key in obj) { + /* istanbul ignore next */ + if (!obj.hasOwnProperty(key)) + continue; + yield [key, obj[key]]; + } + } +} +exports.forEachObject = forEachObject; +/** + * Returns the number of entries in a map or object. + * + * @param obj - map or object + */ +function objectLength(obj) { + if (isMap(obj)) { + return obj.size; + } + else { + return Object.keys(obj).length; + } +} +exports.objectLength = objectLength; +/** + * Gets the value of a key from a map or object. + * + * @param obj - map or object + * @param key - the key to retrieve + */ +function getObjectValue(obj, key) { + if (isMap(obj)) { + return obj.get(key); + } + else { + return obj[key]; + } +} +exports.getObjectValue = getObjectValue; +/** + * Removes a property from a map or object. + * + * @param obj - map or object + * @param key - the key to remove + */ +function removeObjectValue(obj, key) { + if (isMap(obj)) { + obj.delete(key); + } + else { + delete obj[key]; + } +} +exports.removeObjectValue = removeObjectValue; +/** + * Deep clones the given object. + * + * @param obj - an object + */ +function clone(obj) { + if (isFunction(obj)) { + return obj; + } + else if (isArray(obj)) { + const result = []; + for (const item of obj) { + result.push(clone(item)); + } + return result; + } + else if (isObject(obj)) { + const result = {}; + for (const key in obj) { + /* istanbul ignore next */ + if (obj.hasOwnProperty(key)) { + const val = obj[key]; + result[key] = clone(val); + } + } + return result; + } + else { + return obj; + } +} +exports.clone = clone; +/** + * Type guard for boolean types + * + * @param x - a variable to type check + */ +function isBoolean(x) { + return typeof x === "boolean"; +} +exports.isBoolean = isBoolean; +/** + * Type guard for numeric types + * + * @param x - a variable to type check + */ +function isNumber(x) { + return typeof x === "number"; +} +exports.isNumber = isNumber; +/** + * Type guard for strings + * + * @param x - a variable to type check + */ +function isString(x) { + return typeof x === "string"; +} +exports.isString = isString; +/** + * Type guard for function objects + * + * @param x - a variable to type check + */ +function isFunction(x) { + return !!x && Object.prototype.toString.call(x) === '[object Function]'; +} +exports.isFunction = isFunction; +/** + * Type guard for JS objects + * + * _Note:_ Functions are objects too + * + * @param x - a variable to type check + */ +function isObject(x) { + const type = typeof x; + return !!x && (type === 'function' || type === 'object'); +} +exports.isObject = isObject; +/** + * Type guard for arrays + * + * @param x - a variable to type check + */ +function isArray(x) { + return Array.isArray(x); +} +exports.isArray = isArray; +/** + * Type guard for maps. + * + * @param x - a variable to check + */ +function isMap(x) { + return x instanceof Map; +} +exports.isMap = isMap; +/** + * Determines if `x` is an empty Array or an Object with no own properties. + * + * @param x - a variable to check + */ +function isEmpty(x) { + if (isArray(x)) { + return !x.length; + } + else if (isObject(x)) { + for (const key in x) { + if (x.hasOwnProperty(key)) { + return false; + } + } + return true; + } + return false; +} +exports.isEmpty = isEmpty; +/** + * Determines if `x` is a plain Object. + * + * @param x - a variable to check + */ +function isPlainObject(x) { + if (isObject(x)) { + const proto = Object.getPrototypeOf(x); + const ctor = proto.constructor; + return proto && ctor && + (typeof ctor === 'function') && (ctor instanceof ctor) && + (Function.prototype.toString.call(ctor) === Function.prototype.toString.call(Object)); + } + return false; +} +exports.isPlainObject = isPlainObject; +/** + * Determines if `x` is an iterable Object. + * + * @param x - a variable to check + */ +function isIterable(x) { + return x && (typeof x[Symbol.iterator] === 'function'); +} +exports.isIterable = isIterable; +/** + * Gets the primitive value of an object. + */ +function getValue(obj) { + if (isFunction(obj.valueOf)) { + return obj.valueOf(); + } + else { + return obj; + } +} +exports.getValue = getValue; +/** + * UTF-8 encodes the given string. + * + * @param input - a string + */ +function utf8Encode(input) { + const bytes = new Uint8Array(input.length * 4); + let byteIndex = 0; + for (let i = 0; i < input.length; i++) { + let char = input.charCodeAt(i); + if (char < 128) { + bytes[byteIndex++] = char; + continue; + } + else if (char < 2048) { + bytes[byteIndex++] = char >> 6 | 192; + } + else { + if (char > 0xd7ff && char < 0xdc00) { + if (++i >= input.length) { + throw new Error("Incomplete surrogate pair."); + } + const c2 = input.charCodeAt(i); + if (c2 < 0xdc00 || c2 > 0xdfff) { + throw new Error("Invalid surrogate character."); + } + char = 0x10000 + ((char & 0x03ff) << 10) + (c2 & 0x03ff); + bytes[byteIndex++] = char >> 18 | 240; + bytes[byteIndex++] = char >> 12 & 63 | 128; + } + else { + bytes[byteIndex++] = char >> 12 | 224; + } + bytes[byteIndex++] = char >> 6 & 63 | 128; + } + bytes[byteIndex++] = char & 63 | 128; + } + return bytes.subarray(0, byteIndex); +} +exports.utf8Encode = utf8Encode; +/** + * UTF-8 decodes the given byte sequence into a string. + * + * @param bytes - a byte sequence + */ +function utf8Decode(bytes) { + let result = ""; + let i = 0; + while (i < bytes.length) { + var c = bytes[i++]; + if (c > 127) { + if (c > 191 && c < 224) { + if (i >= bytes.length) { + throw new Error("Incomplete 2-byte sequence."); + } + c = (c & 31) << 6 | bytes[i++] & 63; + } + else if (c > 223 && c < 240) { + if (i + 1 >= bytes.length) { + throw new Error("Incomplete 3-byte sequence."); + } + c = (c & 15) << 12 | (bytes[i++] & 63) << 6 | bytes[i++] & 63; + } + else if (c > 239 && c < 248) { + if (i + 2 >= bytes.length) { + throw new Error("Incomplete 4-byte sequence."); + } + c = (c & 7) << 18 | (bytes[i++] & 63) << 12 | (bytes[i++] & 63) << 6 | bytes[i++] & 63; + } + else { + throw new Error("Unknown multi-byte start."); + } + } + if (c <= 0xffff) { + result += String.fromCharCode(c); + } + else if (c <= 0x10ffff) { + c -= 0x10000; + result += String.fromCharCode(c >> 10 | 0xd800); + result += String.fromCharCode(c & 0x3FF | 0xdc00); + } + else { + throw new Error("Code point exceeds UTF-16 limit."); + } + } + return result; +} +exports.utf8Decode = utf8Decode; +//# sourceMappingURL=index.js.map + +/***/ }), + +/***/ 730: +/***/ (function(__unusedmodule, exports) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * Represents a mutation record. + */ +class MutationRecordImpl { + /** + * Initializes a new instance of `MutationRecord`. + * + * @param type - type of mutation: `"attributes"` for an attribute + * mutation, `"characterData"` for a mutation to a CharacterData node + * and `"childList"` for a mutation to the tree of nodes. + * @param target - node affected by the mutation. + * @param addedNodes - list of added nodes. + * @param removedNodes - list of removed nodes. + * @param previousSibling - previous sibling of added or removed nodes. + * @param nextSibling - next sibling of added or removed nodes. + * @param attributeName - local name of the changed attribute, + * and `null` otherwise. + * @param attributeNamespace - namespace of the changed attribute, + * and `null` otherwise. + * @param oldValue - value before mutation: attribute value for an attribute + * mutation, node `data` for a mutation to a CharacterData node and `null` + * for a mutation to the tree of nodes. + */ + constructor(type, target, addedNodes, removedNodes, previousSibling, nextSibling, attributeName, attributeNamespace, oldValue) { + this._type = type; + this._target = target; + this._addedNodes = addedNodes; + this._removedNodes = removedNodes; + this._previousSibling = previousSibling; + this._nextSibling = nextSibling; + this._attributeName = attributeName; + this._attributeNamespace = attributeNamespace; + this._oldValue = oldValue; + } + /** @inheritdoc */ + get type() { return this._type; } + /** @inheritdoc */ + get target() { return this._target; } + /** @inheritdoc */ + get addedNodes() { return this._addedNodes; } + /** @inheritdoc */ + get removedNodes() { return this._removedNodes; } + /** @inheritdoc */ + get previousSibling() { return this._previousSibling; } + /** @inheritdoc */ + get nextSibling() { return this._nextSibling; } + /** @inheritdoc */ + get attributeName() { return this._attributeName; } + /** @inheritdoc */ + get attributeNamespace() { return this._attributeNamespace; } + /** @inheritdoc */ + get oldValue() { return this._oldValue; } + /** + * Creates a new `MutationRecord`. + * + * @param type - type of mutation: `"attributes"` for an attribute + * mutation, `"characterData"` for a mutation to a CharacterData node + * and `"childList"` for a mutation to the tree of nodes. + * @param target - node affected by the mutation. + * @param addedNodes - list of added nodes. + * @param removedNodes - list of removed nodes. + * @param previousSibling - previous sibling of added or removed nodes. + * @param nextSibling - next sibling of added or removed nodes. + * @param attributeName - local name of the changed attribute, + * and `null` otherwise. + * @param attributeNamespace - namespace of the changed attribute, + * and `null` otherwise. + * @param oldValue - value before mutation: attribute value for an attribute + * mutation, node `data` for a mutation to a CharacterData node and `null` + * for a mutation to the tree of nodes. + */ + static _create(type, target, addedNodes, removedNodes, previousSibling, nextSibling, attributeName, attributeNamespace, oldValue) { + return new MutationRecordImpl(type, target, addedNodes, removedNodes, previousSibling, nextSibling, attributeName, attributeNamespace, oldValue); + } +} +exports.MutationRecordImpl = MutationRecordImpl; +//# sourceMappingURL=MutationRecordImpl.js.map + +/***/ }), + +/***/ 742: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const _1 = __webpack_require__(113); +const DOMException_1 = __webpack_require__(35); +const infra_1 = __webpack_require__(23); +const algorithm_1 = __webpack_require__(163); +/** + * Represents a token set. + */ +class DOMTokenListImpl { + /** + * Initializes a new instance of `DOMTokenList`. + * + * @param element - associated element + * @param attribute - associated attribute + */ + constructor(element, attribute) { + /** + * 1. Let element be associated element. + * 2. Let localName be associated attribute’s local name. + * 3. Let value be the result of getting an attribute value given element + * and localName. + * 4. Run the attribute change steps for element, localName, value, value, + * and null. + */ + this._element = element; + this._attribute = attribute; + this._tokenSet = new Set(); + const localName = attribute._localName; + const value = algorithm_1.element_getAnAttributeValue(element, localName); + // define a closure to be called when the associated attribute's value changes + const thisObj = this; + function updateTokenSet(element, localName, oldValue, value, namespace) { + /** + * 1. If localName is associated attribute’s local name, namespace is null, + * and value is null, then empty token set. + * 2. Otherwise, if localName is associated attribute’s local name, + * namespace is null, then set token set to value, parsed. + */ + if (localName === thisObj._attribute._localName && namespace === null) { + if (!value) + thisObj._tokenSet.clear(); + else + thisObj._tokenSet = algorithm_1.orderedSet_parse(value); + } + } + // add the closure to the associated element's attribute change steps + this._element._attributeChangeSteps.push(updateTokenSet); + if (_1.dom.features.steps) { + algorithm_1.dom_runAttributeChangeSteps(element, localName, value, value, null); + } + } + /** @inheritdoc */ + get length() { + /** + * The length attribute' getter must return context object’s token set’s + * size. + */ + return this._tokenSet.size; + } + /** @inheritdoc */ + item(index) { + /** + * 1. If index is equal to or greater than context object’s token set’s + * size, then return null. + * 2. Return context object’s token set[index]. + */ + let i = 0; + for (const token of this._tokenSet) { + if (i === index) + return token; + i++; + } + return null; + } + /** @inheritdoc */ + contains(token) { + /** + * The contains(token) method, when invoked, must return true if context + * object’s token set[token] exists, and false otherwise. + */ + return this._tokenSet.has(token); + } + /** @inheritdoc */ + add(...tokens) { + /** + * 1. For each token in tokens: + * 1.1. If token is the empty string, then throw a "SyntaxError" + * DOMException. + * 1.2. If token contains any ASCII whitespace, then throw an + * "InvalidCharacterError" DOMException. + * 2. For each token in tokens, append token to context object’s token set. + * 3. Run the update steps. + */ + for (const token of tokens) { + if (token === '') { + throw new DOMException_1.SyntaxError("Cannot add an empty token."); + } + else if (infra_1.codePoint.ASCIIWhiteSpace.test(token)) { + throw new DOMException_1.InvalidCharacterError("Token cannot contain whitespace."); + } + else { + this._tokenSet.add(token); + } + } + algorithm_1.tokenList_updateSteps(this); + } + /** @inheritdoc */ + remove(...tokens) { + /** + * 1. For each token in tokens: + * 1.1. If token is the empty string, then throw a "SyntaxError" + * DOMException. + * 1.2. If token contains any ASCII whitespace, then throw an + * "InvalidCharacterError" DOMException. + * 2. For each token in tokens, remove token from context object’s token set. + * 3. Run the update steps. + */ + for (const token of tokens) { + if (token === '') { + throw new DOMException_1.SyntaxError("Cannot remove an empty token."); + } + else if (infra_1.codePoint.ASCIIWhiteSpace.test(token)) { + throw new DOMException_1.InvalidCharacterError("Token cannot contain whitespace."); + } + else { + this._tokenSet.delete(token); + } + } + algorithm_1.tokenList_updateSteps(this); + } + /** @inheritdoc */ + toggle(token, force = undefined) { + /** + * 1. If token is the empty string, then throw a "SyntaxError" DOMException. + * 2. If token contains any ASCII whitespace, then throw an + * "InvalidCharacterError" DOMException. + */ + if (token === '') { + throw new DOMException_1.SyntaxError("Cannot toggle an empty token."); + } + else if (infra_1.codePoint.ASCIIWhiteSpace.test(token)) { + throw new DOMException_1.InvalidCharacterError("Token cannot contain whitespace."); + } + /** + * 3. If context object’s token set[token] exists, then: + */ + if (this._tokenSet.has(token)) { + /** + * 3.1. If force is either not given or is false, then remove token from + * context object’s token set, run the update steps and return false. + * 3.2. Return true. + */ + if (force === undefined || force === false) { + this._tokenSet.delete(token); + algorithm_1.tokenList_updateSteps(this); + return false; + } + return true; + } + /** + * 4. Otherwise, if force not given or is true, append token to context + * object’s token set, run the update steps, and return true. + */ + if (force === undefined || force === true) { + this._tokenSet.add(token); + algorithm_1.tokenList_updateSteps(this); + return true; + } + /** + * 5. Return false. + */ + return false; + } + /** @inheritdoc */ + replace(token, newToken) { + /** + * 1. If either token or newToken is the empty string, then throw a + * "SyntaxError" DOMException. + * 2. If either token or newToken contains any ASCII whitespace, then throw + * an "InvalidCharacterError" DOMException. + */ + if (token === '' || newToken === '') { + throw new DOMException_1.SyntaxError("Cannot replace an empty token."); + } + else if (infra_1.codePoint.ASCIIWhiteSpace.test(token) || infra_1.codePoint.ASCIIWhiteSpace.test(newToken)) { + throw new DOMException_1.InvalidCharacterError("Token cannot contain whitespace."); + } + /** + * 3. If context object’s token set does not contain token, then return + * false. + */ + if (!this._tokenSet.has(token)) + return false; + /** + * 4. Replace token in context object’s token set with newToken. + * 5. Run the update steps. + * 6. Return true. + */ + infra_1.set.replace(this._tokenSet, token, newToken); + algorithm_1.tokenList_updateSteps(this); + return true; + } + /** @inheritdoc */ + supports(token) { + /** + * 1. Let result be the return value of validation steps called with token. + * 2. Return result. + */ + return algorithm_1.tokenList_validationSteps(this, token); + } + /** @inheritdoc */ + get value() { + /** + * The value attribute must return the result of running context object’s + * serialize steps. + */ + return algorithm_1.tokenList_serializeSteps(this); + } + set value(value) { + /** + * Setting the value attribute must set an attribute value for the + * associated element using associated attribute’s local name and the given + * value. + */ + algorithm_1.element_setAnAttributeValue(this._element, this._attribute._localName, value); + } + /** + * Returns an iterator for the token set. + */ + [Symbol.iterator]() { + const it = this._tokenSet[Symbol.iterator](); + return { + next() { + return it.next(); + } + }; + } + /** + * Creates a new `DOMTokenList`. + * + * @param element - associated element + * @param attribute - associated attribute + */ + static _create(element, attribute) { + return new DOMTokenListImpl(element, attribute); + } +} +exports.DOMTokenListImpl = DOMTokenListImpl; +//# sourceMappingURL=DOMTokenListImpl.js.map + +/***/ }), + +/***/ 743: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const dom_1 = __webpack_require__(252); +const dom_2 = __webpack_require__(113); +const util_1 = __webpack_require__(669); +dom_2.dom.setFeatures(false); +/** + * Throws an error if the parser returned an error document. + */ +function throwIfParserError(doc) { + const root = doc.documentElement; + if (root !== null && + root.localName === "parsererror" && + root.namespaceURI === "http://www.mozilla.org/newlayout/xml/parsererror.xml") { + const msgElement = root.firstElementChild; + /* istanbul ignore next */ + if (msgElement === null) + throw new Error("Error parsing XML string."); + const msg = msgElement.getAttribute("message"); + /* istanbul ignore next */ + if (msg === null) + throw new Error("Error parsing XML string."); + throw new Error(msg); + } +} +exports.throwIfParserError = throwIfParserError; +/** + * Creates an XML document without any child nodes. + */ +function createDocument() { + const impl = new dom_1.DOMImplementation(); + const doc = impl.createDocument(null, 'root', null); + /* istanbul ignore else */ + if (doc.documentElement) { + doc.removeChild(doc.documentElement); + } + return doc; +} +exports.createDocument = createDocument; +/** + * Creates a DOM parser. + */ +function createParser() { + return new dom_1.DOMParser(); +} +exports.createParser = createParser; +/** + * Sanitizes input strings with user supplied replacement characters. + * + * @param str - input string + */ +function sanitizeInput(str, replacement) { + if (str == null) { + return str; + } + else if (replacement === undefined) { + return str + ""; + } + else { + let result = ""; + str = str + ""; + for (let i = 0; i < str.length; i++) { + let n = str.charCodeAt(i); + // #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF] + if (n === 0x9 || n === 0xA || n === 0xD || + (n >= 0x20 && n <= 0xD7FF) || + (n >= 0xE000 && n <= 0xFFFD)) { + // valid character - not surrogate pair + result += str.charAt(i); + } + else if (n >= 0xD800 && n <= 0xDBFF && i < str.length - 1) { + const n2 = str.charCodeAt(i + 1); + if (n2 >= 0xDC00 && n2 <= 0xDFFF) { + n = (n - 0xD800) * 0x400 + n2 - 0xDC00 + 0x10000; + if (n >= 0x10000 && n <= 0x10FFFF) { + // valid surrogate pair + result += String.fromCodePoint(n); + } + else { + // invalid surrogate pair + result += util_1.isString(replacement) ? replacement : replacement(String.fromCodePoint(n), i, str); + } + i++; + } + else { + // invalid lone surrogate + result += util_1.isString(replacement) ? replacement : replacement(str.charAt(i), i, str); + } + } + else { + // invalid character + result += util_1.isString(replacement) ? replacement : replacement(str.charAt(i), i, str); + } + } + return result; + } +} +exports.sanitizeInput = sanitizeInput; +//# sourceMappingURL=dom.js.map + +/***/ }), + +/***/ 747: +/***/ (function(module) { + +module.exports = require("fs"); + +/***/ }), + +/***/ 750: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const util_1 = __webpack_require__(592); +const ObjectWriter_1 = __webpack_require__(419); +const BaseWriter_1 = __webpack_require__(462); +/** + * Serializes XML nodes into ES6 maps and arrays. + */ +class MapWriter extends BaseWriter_1.BaseWriter { + /** + * Produces an XML serialization of the given node. + * + * @param node - node to serialize + * @param writerOptions - serialization options + */ + serialize(node, writerOptions) { + const options = util_1.applyDefaults(writerOptions, { + format: "map", + wellFormed: false, + noDoubleEncoding: false, + group: false + }); + // convert to object + const objectWriterOptions = util_1.applyDefaults(options, { + format: "object", + wellFormed: false, + noDoubleEncoding: false + }); + const objectWriter = new ObjectWriter_1.ObjectWriter(this._builderOptions); + const val = objectWriter.serialize(node, objectWriterOptions); + // recursively convert object into Map + return this._convertObject(val); + } + /** + * Recursively converts a JS object into an ES5 map. + * + * @param obj - a JS object + */ + _convertObject(obj) { + if (util_1.isArray(obj)) { + for (let i = 0; i < obj.length; i++) { + obj[i] = this._convertObject(obj[i]); + } + return obj; + } + else if (util_1.isObject(obj)) { + const map = new Map(); + for (const key in obj) { + map.set(key, this._convertObject(obj[key])); + } + return map; + } + else { + return obj; + } + } +} +exports.MapWriter = MapWriter; +//# sourceMappingURL=MapWriter.js.map + +/***/ }), + +/***/ 760: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const interfaces_1 = __webpack_require__(970); +const CharacterDataImpl_1 = __webpack_require__(43); +const WebIDLAlgorithm_1 = __webpack_require__(495); +/** + * Represents a comment node. + */ +class CommentImpl extends CharacterDataImpl_1.CharacterDataImpl { + /** + * Initializes a new instance of `Comment`. + * + * @param data - the text content + */ + constructor(data = '') { + super(data); + } + /** + * Creates a new `Comment`. + * + * @param document - owner document + * @param data - node contents + */ + static _create(document, data = '') { + const node = new CommentImpl(data); + node._nodeDocument = document; + return node; + } +} +exports.CommentImpl = CommentImpl; +/** + * Initialize prototype properties + */ +WebIDLAlgorithm_1.idl_defineConst(CommentImpl.prototype, "_nodeType", interfaces_1.NodeType.Comment); +//# sourceMappingURL=CommentImpl.js.map + +/***/ }), + +/***/ 763: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const CodePoints_1 = __webpack_require__(11); +/** + * Base-64 encodes the given string. + * + * @param input - a string + */ +function forgivingBase64Encode(input) { + /** + * To forgiving-base64 encode given a byte sequence data, apply the base64 + * algorithm defined in section 4 of RFC 4648 to data and return the result. + * [RFC4648] + */ + return Buffer.from(input).toString('base64'); +} +exports.forgivingBase64Encode = forgivingBase64Encode; +/** + * Decodes a base-64 string. + * + * @param input - a string + */ +function forgivingBase64Decode(input) { + if (input === "") + return ""; + /** + * 1. Remove all ASCII whitespace from data. + */ + input = input.replace(CodePoints_1.ASCIIWhiteSpace, ''); + /** + * 2. If data’s length divides by 4 leaving no remainder, then: + * 2.1. If data ends with one or two U+003D (=) code points, then remove them from data. + */ + if (input.length % 4 === 0) { + if (input.endsWith("==")) { + input = input.substr(0, input.length - 2); + } + else if (input.endsWith("=")) { + input = input.substr(0, input.length - 1); + } + } + /** + * 3. If data’s length divides by 4 leaving a remainder of 1, then return failure. + */ + if (input.length % 4 === 1) + return null; + /** + * 4. If data contains a code point that is not one of + * - U+002B (+) + * - U+002F (/) + * - ASCII alphanumeric + * then return failure. + */ + if (!/[0-9A-Za-z+/]/.test(input)) + return null; + /** + * 5. Let output be an empty byte sequence. + * 6. Let buffer be an empty buffer that can have bits appended to it. + * 7. Let position be a position variable for data, initially pointing at the + * start of data. + * 8. While position does not point past the end of data: + * 8.1. Find the code point pointed to by position in the second column of + * Table 1: The Base 64 Alphabet of RFC 4648. Let n be the number given in the + * first cell of the same row. [RFC4648] + * 8.2. Append the six bits corresponding to n, most significant bit first, + * to buffer. + * 8.3. If buffer has accumulated 24 bits, interpret them as three 8-bit + * big-endian numbers. Append three bytes with values equal to those numbers + * to output, in the same order, and then empty buffer. + * 8.4. Advance position by 1. + * 9. If buffer is not empty, it contains either 12 or 18 bits. If it contains + * 12 bits, then discard the last four and interpret the remaining eight as an + * 8-bit big-endian number. If it contains 18 bits, then discard the last two + * and interpret the remaining 16 as two 8-bit big-endian numbers. Append the + * one or two bytes with values equal to those one or two numbers to output, + * in the same order. + * 10. Return output. + */ + return Buffer.from(input, 'base64').toString('utf8'); +} +exports.forgivingBase64Decode = forgivingBase64Decode; +//# sourceMappingURL=Base64.js.map + +/***/ }), + +/***/ 764: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const util_1 = __webpack_require__(592); +const interfaces_1 = __webpack_require__(970); +const BaseWriter_1 = __webpack_require__(462); +const util_2 = __webpack_require__(918); +/** + * Serializes XML nodes into strings. + */ +class XMLWriter extends BaseWriter_1.BaseWriter { + constructor() { + super(...arguments); + this._indentation = {}; + this._lengthToLastNewline = 0; + } + /** + * Produces an XML serialization of the given node. + * + * @param node - node to serialize + * @param writerOptions - serialization options + */ + serialize(node, writerOptions) { + // provide default options + this._options = util_1.applyDefaults(writerOptions, { + wellFormed: false, + noDoubleEncoding: false, + headless: false, + prettyPrint: false, + indent: " ", + newline: "\n", + offset: 0, + width: 0, + allowEmptyTags: false, + indentTextOnlyNodes: false, + spaceBeforeSlash: false + }); + this._refs = { suppressPretty: false, emptyNode: false, markup: "" }; + // Serialize XML declaration since base serializer does not serialize it + if (node.nodeType === interfaces_1.NodeType.Document && !this._options.headless) { + this._beginLine(); + this._refs.markup = ""; + this._endLine(); + } + this.serializeNode(node, this._options.wellFormed, this._options.noDoubleEncoding); + // remove trailing newline + if (this._options.prettyPrint && + this._refs.markup.slice(-this._options.newline.length) === this._options.newline) { + this._refs.markup = this._refs.markup.slice(0, -this._options.newline.length); + } + return this._refs.markup; + } + /** @inheritdoc */ + docType(name, publicId, systemId) { + this._beginLine(); + if (publicId && systemId) { + this._refs.markup += ""; + } + else if (publicId) { + this._refs.markup += ""; + } + else if (systemId) { + this._refs.markup += ""; + } + else { + this._refs.markup += ""; + } + this._endLine(); + } + /** @inheritdoc */ + openTagBegin(name) { + this._beginLine(); + this._refs.markup += "<" + name; + } + /** @inheritdoc */ + openTagEnd(name, selfClosing, voidElement) { + // do not indent text only elements or elements with empty text nodes + this._refs.suppressPretty = false; + this._refs.emptyNode = false; + if (this._options.prettyPrint && !selfClosing && !voidElement) { + let textOnlyNode = true; + let emptyNode = true; + let childNode = this.currentNode.firstChild; + let cdataCount = 0; + let textCount = 0; + while (childNode) { + if (util_2.Guard.isExclusiveTextNode(childNode)) { + textCount++; + } + else if (util_2.Guard.isCDATASectionNode(childNode)) { + cdataCount++; + } + else { + textOnlyNode = false; + emptyNode = false; + break; + } + if (childNode.data !== '') { + emptyNode = false; + } + childNode = childNode.nextSibling; + } + this._refs.suppressPretty = !this._options.indentTextOnlyNodes && textOnlyNode && ((cdataCount <= 1 && textCount === 0) || cdataCount === 0); + this._refs.emptyNode = emptyNode; + } + if ((voidElement || selfClosing || this._refs.emptyNode) && this._options.allowEmptyTags) { + this._refs.markup += ">"; + } + else { + this._refs.markup += voidElement ? " />" : + (selfClosing || this._refs.emptyNode) ? (this._options.spaceBeforeSlash ? " />" : "/>") : ">"; + } + this._endLine(); + } + /** @inheritdoc */ + closeTag(name) { + if (!this._refs.emptyNode) { + this._beginLine(); + this._refs.markup += ""; + } + this._refs.suppressPretty = false; + this._refs.emptyNode = false; + this._endLine(); + } + /** @inheritdoc */ + attribute(name, value) { + const str = name + "=\"" + value + "\""; + if (this._options.prettyPrint && this._options.width > 0 && + this._refs.markup.length - this._lengthToLastNewline + 1 + str.length > this._options.width) { + this._endLine(); + this._beginLine(); + this._refs.markup += this._indent(1) + str; + } + else { + this._refs.markup += " " + str; + } + } + /** @inheritdoc */ + text(data) { + if (data !== '') { + this._beginLine(); + this._refs.markup += data; + this._endLine(); + } + } + /** @inheritdoc */ + cdata(data) { + if (data !== '') { + this._beginLine(); + this._refs.markup += ""; + this._endLine(); + } + } + /** @inheritdoc */ + comment(data) { + this._beginLine(); + this._refs.markup += ""; + this._endLine(); + } + /** @inheritdoc */ + instruction(target, data) { + this._beginLine(); + this._refs.markup += ""; + this._endLine(); + } + /** + * Produces characters to be prepended to a line of string in pretty-print + * mode. + */ + _beginLine() { + if (this._options.prettyPrint && !this._refs.suppressPretty) { + this._refs.markup += this._indent(this._options.offset + this.level); + } + } + /** + * Produces characters to be appended to a line of string in pretty-print + * mode. + */ + _endLine() { + if (this._options.prettyPrint && !this._refs.suppressPretty) { + this._refs.markup += this._options.newline; + this._lengthToLastNewline = this._refs.markup.length; + } + } + /** + * Produces an indentation string. + * + * @param level - depth of the tree + */ + _indent(level) { + if (level <= 0) { + return ""; + } + else if (this._indentation[level] !== undefined) { + return this._indentation[level]; + } + else { + const str = this._options.indent.repeat(level); + this._indentation[level] = str; + return str; + } + } +} +exports.XMLWriter = XMLWriter; +//# sourceMappingURL=XMLWriter.js.map + +/***/ }), + +/***/ 774: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const interfaces_1 = __webpack_require__(970); +const WebIDLAlgorithm_1 = __webpack_require__(495); +/** + * Represents a node filter. + */ +class NodeFilterImpl { + /** + * Initializes a new instance of `NodeFilter`. + */ + constructor() { + } + /** + * Callback function. + */ + acceptNode(node) { + return interfaces_1.FilterResult.Accept; + } + /** + * Creates a new `NodeFilter`. + */ + static _create() { + return new NodeFilterImpl(); + } +} +exports.NodeFilterImpl = NodeFilterImpl; +NodeFilterImpl.FILTER_ACCEPT = 1; +NodeFilterImpl.FILTER_REJECT = 2; +NodeFilterImpl.FILTER_SKIP = 3; +NodeFilterImpl.SHOW_ALL = 0xffffffff; +NodeFilterImpl.SHOW_ELEMENT = 0x1; +NodeFilterImpl.SHOW_ATTRIBUTE = 0x2; +NodeFilterImpl.SHOW_TEXT = 0x4; +NodeFilterImpl.SHOW_CDATA_SECTION = 0x8; +NodeFilterImpl.SHOW_ENTITY_REFERENCE = 0x10; +NodeFilterImpl.SHOW_ENTITY = 0x20; +NodeFilterImpl.SHOW_PROCESSING_INSTRUCTION = 0x40; +NodeFilterImpl.SHOW_COMMENT = 0x80; +NodeFilterImpl.SHOW_DOCUMENT = 0x100; +NodeFilterImpl.SHOW_DOCUMENT_TYPE = 0x200; +NodeFilterImpl.SHOW_DOCUMENT_FRAGMENT = 0x400; +NodeFilterImpl.SHOW_NOTATION = 0x800; +/** + * Define constants on prototype. + */ +WebIDLAlgorithm_1.idl_defineConst(NodeFilterImpl.prototype, "FILTER_ACCEPT", 1); +WebIDLAlgorithm_1.idl_defineConst(NodeFilterImpl.prototype, "FILTER_REJECT", 2); +WebIDLAlgorithm_1.idl_defineConst(NodeFilterImpl.prototype, "FILTER_SKIP", 3); +WebIDLAlgorithm_1.idl_defineConst(NodeFilterImpl.prototype, "SHOW_ALL", 0xffffffff); +WebIDLAlgorithm_1.idl_defineConst(NodeFilterImpl.prototype, "SHOW_ELEMENT", 0x1); +WebIDLAlgorithm_1.idl_defineConst(NodeFilterImpl.prototype, "SHOW_ATTRIBUTE", 0x2); +WebIDLAlgorithm_1.idl_defineConst(NodeFilterImpl.prototype, "SHOW_TEXT", 0x4); +WebIDLAlgorithm_1.idl_defineConst(NodeFilterImpl.prototype, "SHOW_CDATA_SECTION", 0x8); +WebIDLAlgorithm_1.idl_defineConst(NodeFilterImpl.prototype, "SHOW_ENTITY_REFERENCE", 0x10); +WebIDLAlgorithm_1.idl_defineConst(NodeFilterImpl.prototype, "SHOW_ENTITY", 0x20); +WebIDLAlgorithm_1.idl_defineConst(NodeFilterImpl.prototype, "SHOW_PROCESSING_INSTRUCTION", 0x40); +WebIDLAlgorithm_1.idl_defineConst(NodeFilterImpl.prototype, "SHOW_COMMENT", 0x80); +WebIDLAlgorithm_1.idl_defineConst(NodeFilterImpl.prototype, "SHOW_DOCUMENT", 0x100); +WebIDLAlgorithm_1.idl_defineConst(NodeFilterImpl.prototype, "SHOW_DOCUMENT_TYPE", 0x200); +WebIDLAlgorithm_1.idl_defineConst(NodeFilterImpl.prototype, "SHOW_DOCUMENT_FRAGMENT", 0x400); +WebIDLAlgorithm_1.idl_defineConst(NodeFilterImpl.prototype, "SHOW_NOTATION", 0x800); +//# sourceMappingURL=NodeFilterImpl.js.map + +/***/ }), + +/***/ 780: +/***/ (function(__unusedmodule, exports) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * A surrogate is a code point that is in the range U+D800 to U+DFFF, inclusive. + */ +exports.Surrogate = /[\uD800-\uDFFF]/; +/** + * A scalar value is a code point that is not a surrogate. + */ +exports.ScalarValue = /[\uD800-\uDFFF]/; +/** + * A noncharacter is a code point that is in the range U+FDD0 to U+FDEF, + * inclusive, or U+FFFE, U+FFFF, U+1FFFE, U+1FFFF, U+2FFFE, U+2FFFF, U+3FFFE, + * U+3FFFF, U+4FFFE, U+4FFFF, U+5FFFE, U+5FFFF, U+6FFFE, U+6FFFF, U+7FFFE, + * U+7FFFF, U+8FFFE, U+8FFFF, U+9FFFE, U+9FFFF, U+AFFFE, U+AFFFF, U+BFFFE, + * U+BFFFF, U+CFFFE, U+CFFFF, U+DFFFE, U+DFFFF, U+EFFFE, U+EFFFF, U+FFFFE, + * U+FFFFF, U+10FFFE, or U+10FFFF. + */ +exports.NonCharacter = /[\uFDD0-\uFDEF\uFFFE\uFFFF]|[\uD83F\uD87F\uD8BF\uD8FF\uD93F\uD97F\uD9BF\uD9FF\uDA3F\uDA7F\uDABF\uDAFF\uDB3F\uDB7F\uDBBF\uDBFF][\uDFFE\uDFFF]/; +/** + * An ASCII code point is a code point in the range U+0000 NULL to U+007F + * DELETE, inclusive. + */ +exports.ASCIICodePoint = /[\u0000-\u007F]/; +/** + * An ASCII tab or newline is U+0009 TAB, U+000A LF, or U+000D CR. + */ +exports.ASCIITabOrNewLine = /[\t\n\r]/; +/** + * ASCII whitespace is U+0009 TAB, U+000A LF, U+000C FF, U+000D CR, or + * U+0020 SPACE. + */ +exports.ASCIIWhiteSpace = /[\t\n\f\r ]/; +/** + * A C0 control is a code point in the range U+0000 NULL to U+001F + * INFORMATION SEPARATOR ONE, inclusive. + */ +exports.C0Control = /[\u0000-\u001F]/; +/** + * A C0 control or space is a C0 control or U+0020 SPACE. + */ +exports.C0ControlOrSpace = /[\u0000-\u001F ]/; +/** + * A control is a C0 control or a code point in the range U+007F DELETE to + * U+009F APPLICATION PROGRAM COMMAND, inclusive. + */ +exports.Control = /[\u0000-\u001F\u007F-\u009F]/; +/** + * An ASCII digit is a code point in the range U+0030 (0) to U+0039 (9), + * inclusive. + */ +exports.ASCIIDigit = /[0-9]/; +/** + * An ASCII upper hex digit is an ASCII digit or a code point in the range + * U+0041 (A) to U+0046 (F), inclusive. + */ +exports.ASCIIUpperHexDigit = /[0-9A-F]/; +/** + * An ASCII lower hex digit is an ASCII digit or a code point in the range + * U+0061 (a) to U+0066 (f), inclusive. + */ +exports.ASCIILowerHexDigit = /[0-9a-f]/; +/** + * An ASCII hex digit is an ASCII upper hex digit or ASCII lower hex digit. + */ +exports.ASCIIHexDigit = /[0-9A-Fa-f]/; +/** + * An ASCII upper alpha is a code point in the range U+0041 (A) to U+005A (Z), + * inclusive. + */ +exports.ASCIIUpperAlpha = /[A-Z]/; +/** + * An ASCII lower alpha is a code point in the range U+0061 (a) to U+007A (z), + * inclusive. + */ +exports.ASCIILowerAlpha = /[a-z]/; +/** + * An ASCII alpha is an ASCII upper alpha or ASCII lower alpha. + */ +exports.ASCIIAlpha = /[A-Za-z]/; +/** + * An ASCII alphanumeric is an ASCII digit or ASCII alpha. + */ +exports.ASCIIAlphanumeric = /[0-9A-Za-z]/; +//# sourceMappingURL=CodePoints.js.map + +/***/ }), + +/***/ 781: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const BaseCBWriter_1 = __webpack_require__(512); +/** + * Serializes XML nodes. + */ +class JSONCBWriter extends BaseCBWriter_1.BaseCBWriter { + /** + * Initializes a new instance of `BaseCBWriter`. + * + * @param builderOptions - XML builder options + */ + constructor(builderOptions) { + super(builderOptions); + this._hasChildren = []; + this._additionalLevel = 0; + } + /** @inheritdoc */ + declaration(version, encoding, standalone) { + return ""; + } + /** @inheritdoc */ + docType(name, publicId, systemId) { + return ""; + } + /** @inheritdoc */ + comment(data) { + // { "!": "hello" } + return this._comma() + this._beginLine() + "{" + this._sep() + + this._key(this._builderOptions.convert.comment) + this._sep() + + this._val(data) + this._sep() + "}"; + } + /** @inheritdoc */ + text(data) { + // { "#": "hello" } + return this._comma() + this._beginLine() + "{" + this._sep() + + this._key(this._builderOptions.convert.text) + this._sep() + + this._val(data) + this._sep() + "}"; + } + /** @inheritdoc */ + instruction(target, data) { + // { "?": "target hello" } + return this._comma() + this._beginLine() + "{" + this._sep() + + this._key(this._builderOptions.convert.ins) + this._sep() + + this._val(data ? target + " " + data : target) + this._sep() + "}"; + } + /** @inheritdoc */ + cdata(data) { + // { "$": "hello" } + return this._comma() + this._beginLine() + "{" + this._sep() + + this._key(this._builderOptions.convert.cdata) + this._sep() + + this._val(data) + this._sep() + "}"; + } + /** @inheritdoc */ + attribute(name, value) { + // { "@name": "val" } + return this._comma() + this._beginLine(1) + "{" + this._sep() + + this._key(this._builderOptions.convert.att + name) + this._sep() + + this._val(value) + this._sep() + "}"; + } + /** @inheritdoc */ + openTagBegin(name) { + // { "node": { "#": [ + let str = this._comma() + this._beginLine() + "{" + this._sep() + this._key(name) + this._sep() + "{"; + this._additionalLevel++; + this.hasData = true; + str += this._beginLine() + this._key(this._builderOptions.convert.text) + this._sep() + "["; + this._hasChildren.push(false); + return str; + } + /** @inheritdoc */ + openTagEnd(name, selfClosing, voidElement) { + if (selfClosing) { + let str = this._sep() + "]"; + this._additionalLevel--; + str += this._beginLine() + "}" + this._sep() + "}"; + return str; + } + else { + return ""; + } + } + /** @inheritdoc */ + closeTag(name) { + // ] } } + let str = this._beginLine() + "]"; + this._additionalLevel--; + str += this._beginLine() + "}" + this._sep() + "}"; + return str; + } + /** @inheritdoc */ + beginElement(name) { } + /** @inheritdoc */ + endElement(name) { this._hasChildren.pop(); } + /** + * Produces characters to be prepended to a line of string in pretty-print + * mode. + */ + _beginLine(additionalOffset = 0) { + if (this._writerOptions.prettyPrint) { + return (this.hasData ? this._writerOptions.newline : "") + + this._indent(this._writerOptions.offset + this.level + additionalOffset); + } + else { + return ""; + } + } + /** + * Produces an indentation string. + * + * @param level - depth of the tree + */ + _indent(level) { + if (level + this._additionalLevel <= 0) { + return ""; + } + else { + return this._writerOptions.indent.repeat(level + this._additionalLevel); + } + } + /** + * Produces a comma before a child node if it has previous siblings. + */ + _comma() { + const str = (this._hasChildren[this._hasChildren.length - 1] ? "," : ""); + if (this._hasChildren.length > 0) { + this._hasChildren[this._hasChildren.length - 1] = true; + } + return str; + } + /** + * Produces a separator string. + */ + _sep() { + return (this._writerOptions.prettyPrint ? " " : ""); + } + /** + * Produces a JSON key string delimited with double quotes. + */ + _key(key) { + return "\"" + key + "\":"; + } + /** + * Produces a JSON value string delimited with double quotes. + */ + _val(val) { + return "\"" + val + "\""; + } +} +exports.JSONCBWriter = JSONCBWriter; +//# sourceMappingURL=JSONCBWriter.js.map + +/***/ }), + +/***/ 782: +/***/ (function(__unusedmodule, exports) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * Determines if the given number is an ASCII byte. + * + * @param byte - a byte + */ +function isASCIIByte(byte) { + /** + * An ASCII byte is a byte in the range 0x00 (NUL) to 0x7F (DEL), inclusive. + */ + return byte >= 0x00 && byte <= 0x7F; +} +exports.isASCIIByte = isASCIIByte; +//# sourceMappingURL=Byte.js.map + +/***/ }), + +/***/ 783: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const interfaces_1 = __webpack_require__(970); +/** + * Contains user-defined type guards for DOM objects. + */ +class Guard { + /** + * Determines if the given object is a `Node`. + * + * @param a - the object to check + */ + static isNode(a) { + return (!!a && a._nodeType !== undefined); + } + /** + * Determines if the given object is a `Document`. + * + * @param a - the object to check + */ + static isDocumentNode(a) { + return (Guard.isNode(a) && a._nodeType === interfaces_1.NodeType.Document); + } + /** + * Determines if the given object is a `DocumentType`. + * + * @param a - the object to check + */ + static isDocumentTypeNode(a) { + return (Guard.isNode(a) && a._nodeType === interfaces_1.NodeType.DocumentType); + } + /** + * Determines if the given object is a `DocumentFragment`. + * + * @param a - the object to check + */ + static isDocumentFragmentNode(a) { + return (Guard.isNode(a) && a._nodeType === interfaces_1.NodeType.DocumentFragment); + } + /** + * Determines if the given object is a `Attr`. + * + * @param a - the object to check + */ + static isAttrNode(a) { + return (Guard.isNode(a) && a._nodeType === interfaces_1.NodeType.Attribute); + } + /** + * Determines if the given node is a `CharacterData` node. + * + * @param a - the object to check + */ + static isCharacterDataNode(a) { + if (!Guard.isNode(a)) + return false; + const type = a._nodeType; + return (type === interfaces_1.NodeType.Text || + type === interfaces_1.NodeType.ProcessingInstruction || + type === interfaces_1.NodeType.Comment || + type === interfaces_1.NodeType.CData); + } + /** + * Determines if the given object is a `Text` or a `CDATASection`. + * + * @param a - the object to check + */ + static isTextNode(a) { + return (Guard.isNode(a) && (a._nodeType === interfaces_1.NodeType.Text || a._nodeType === interfaces_1.NodeType.CData)); + } + /** + * Determines if the given object is a `Text`. + * + * @param a - the object to check + */ + static isExclusiveTextNode(a) { + return (Guard.isNode(a) && a._nodeType === interfaces_1.NodeType.Text); + } + /** + * Determines if the given object is a `CDATASection`. + * + * @param a - the object to check + */ + static isCDATASectionNode(a) { + return (Guard.isNode(a) && a._nodeType === interfaces_1.NodeType.CData); + } + /** + * Determines if the given object is a `Comment`. + * + * @param a - the object to check + */ + static isCommentNode(a) { + return (Guard.isNode(a) && a._nodeType === interfaces_1.NodeType.Comment); + } + /** + * Determines if the given object is a `ProcessingInstruction`. + * + * @param a - the object to check + */ + static isProcessingInstructionNode(a) { + return (Guard.isNode(a) && a._nodeType === interfaces_1.NodeType.ProcessingInstruction); + } + /** + * Determines if the given object is an `Element`. + * + * @param a - the object to check + */ + static isElementNode(a) { + return (Guard.isNode(a) && a._nodeType === interfaces_1.NodeType.Element); + } + /** + * Determines if the given object is a custom `Element`. + * + * @param a - the object to check + */ + static isCustomElementNode(a) { + return (Guard.isElementNode(a) && a._customElementState === "custom"); + } + /** + * Determines if the given object is a `ShadowRoot`. + * + * @param a - the object to check + */ + static isShadowRoot(a) { + return (!!a && a.host !== undefined); + } + /** + * Determines if the given object is a `MouseEvent`. + * + * @param a - the object to check + */ + static isMouseEvent(a) { + return (!!a && a.screenX !== undefined && a.screenY != undefined); + } + /** + * Determines if the given object is a slotable. + * + * Element and Text nodes are slotables. A slotable has an associated name + * (a string). + * + * @param a - the object to check + */ + static isSlotable(a) { + return (!!a && a._name !== undefined && a._assignedSlot !== undefined && + (Guard.isTextNode(a) || Guard.isElementNode(a))); + } + /** + * Determines if the given object is a slot. + * + * @param a - the object to check + */ + static isSlot(a) { + return (!!a && a._name !== undefined && a._assignedNodes !== undefined && + Guard.isElementNode(a)); + } + /** + * Determines if the given object is a `Window`. + * + * @param a - the object to check + */ + static isWindow(a) { + return (!!a && a.navigator !== undefined); + } + /** + * Determines if the given object is an `EventListener`. + * + * @param a - the object to check + */ + static isEventListener(a) { + return (!!a && a.handleEvent !== undefined); + } + /** + * Determines if the given object is a `RegisteredObserver`. + * + * @param a - the object to check + */ + static isRegisteredObserver(a) { + return (!!a && a.observer !== undefined && a.options !== undefined); + } + /** + * Determines if the given object is a `TransientRegisteredObserver`. + * + * @param a - the object to check + */ + static isTransientRegisteredObserver(a) { + return (!!a && a.source !== undefined && Guard.isRegisteredObserver(a)); + } +} +exports.Guard = Guard; +//# sourceMappingURL=Guard.js.map + +/***/ }), + +/***/ 784: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const EventTargetImpl_1 = __webpack_require__(597); +const algorithm_1 = __webpack_require__(163); +/** + * Represents a signal object that communicates with a DOM request and abort + * it through an AbortController. + */ +class AbortSignalImpl extends EventTargetImpl_1.EventTargetImpl { + /** + * Initializes a new instance of `AbortSignal`. + */ + constructor() { + super(); + this._abortedFlag = false; + this._abortAlgorithms = new Set(); + } + /** @inheritdoc */ + get aborted() { return this._abortedFlag; } + /** @inheritdoc */ + get onabort() { + return algorithm_1.event_getterEventHandlerIDLAttribute(this, "onabort"); + } + set onabort(val) { + algorithm_1.event_setterEventHandlerIDLAttribute(this, "onabort", val); + } + /** + * Creates a new `AbortSignal`. + */ + static _create() { + return new AbortSignalImpl(); + } +} +exports.AbortSignalImpl = AbortSignalImpl; +//# sourceMappingURL=AbortSignalImpl.js.map + +/***/ }), + +/***/ 796: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const interfaces_1 = __webpack_require__(970); +const NodeImpl_1 = __webpack_require__(935); +const WebIDLAlgorithm_1 = __webpack_require__(495); +/** + * Represents a document fragment in the XML tree. + */ +class DocumentFragmentImpl extends NodeImpl_1.NodeImpl { + /** + * Initializes a new instance of `DocumentFragment`. + * + * @param host - shadow root's host element + */ + constructor(host = null) { + super(); + this._children = new Set(); + this._host = host; + } + // MIXIN: NonElementParentNode + /* istanbul ignore next */ + getElementById(elementId) { throw new Error("Mixin: NonElementParentNode not implemented."); } + // MIXIN: ParentNode + /* istanbul ignore next */ + get children() { throw new Error("Mixin: ParentNode not implemented."); } + /* istanbul ignore next */ + get firstElementChild() { throw new Error("Mixin: ParentNode not implemented."); } + /* istanbul ignore next */ + get lastElementChild() { throw new Error("Mixin: ParentNode not implemented."); } + /* istanbul ignore next */ + get childElementCount() { throw new Error("Mixin: ParentNode not implemented."); } + /* istanbul ignore next */ + prepend(...nodes) { throw new Error("Mixin: ParentNode not implemented."); } + /* istanbul ignore next */ + append(...nodes) { throw new Error("Mixin: ParentNode not implemented."); } + /* istanbul ignore next */ + querySelector(selectors) { throw new Error("Mixin: ParentNode not implemented."); } + /* istanbul ignore next */ + querySelectorAll(selectors) { throw new Error("Mixin: ParentNode not implemented."); } + /** + * Creates a new `DocumentFragment`. + * + * @param document - owner document + * @param host - shadow root's host element + */ + static _create(document, host = null) { + const node = new DocumentFragmentImpl(host); + node._nodeDocument = document; + return node; + } +} +exports.DocumentFragmentImpl = DocumentFragmentImpl; +/** + * Initialize prototype properties + */ +WebIDLAlgorithm_1.idl_defineConst(DocumentFragmentImpl.prototype, "_nodeType", interfaces_1.NodeType.DocumentFragment); +//# sourceMappingURL=DocumentFragmentImpl.js.map + +/***/ }), + +/***/ 798: +/***/ (function(__unusedmodule, exports) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * Represents an object with lazy initialization. + */ +class Lazy { + /** + * Initializes a new instance of `Lazy`. + * + * @param initFunc - initializer function + */ + constructor(initFunc) { + this._initialized = false; + this._value = undefined; + this._initFunc = initFunc; + } + /** + * Gets the value of the object. + */ + get value() { + if (!this._initialized) { + this._value = this._initFunc(); + this._initialized = true; + } + return this._value; + } +} +exports.Lazy = Lazy; +//# sourceMappingURL=Lazy.js.map + +/***/ }), + +/***/ 800: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const TraverserImpl_1 = __webpack_require__(487); +const algorithm_1 = __webpack_require__(163); +/** + * Represents an object which can be used to iterate through the nodes + * of a subtree. + */ +class NodeIteratorImpl extends TraverserImpl_1.TraverserImpl { + /** + * Initializes a new instance of `NodeIterator`. + */ + constructor(root, reference, pointerBeforeReference) { + super(root); + this._iteratorCollection = undefined; + this._reference = reference; + this._pointerBeforeReference = pointerBeforeReference; + algorithm_1.nodeIterator_iteratorList().add(this); + } + /** @inheritdoc */ + get referenceNode() { return this._reference; } + /** @inheritdoc */ + get pointerBeforeReferenceNode() { return this._pointerBeforeReference; } + /** @inheritdoc */ + nextNode() { + /** + * The nextNode() method, when invoked, must return the result of + * traversing with the context object and next. + */ + return algorithm_1.nodeIterator_traverse(this, true); + } + /** @inheritdoc */ + previousNode() { + /** + * The previousNode() method, when invoked, must return the result of + * traversing with the context object and previous. + */ + return algorithm_1.nodeIterator_traverse(this, false); + } + /** @inheritdoc */ + detach() { + /** + * The detach() method, when invoked, must do nothing. + * + * since JS lacks weak references, we still use detach + */ + algorithm_1.nodeIterator_iteratorList().delete(this); + } + /** + * Creates a new `NodeIterator`. + * + * @param root - iterator's root node + * @param reference - reference node + * @param pointerBeforeReference - whether the iterator is before or after the + * reference node + */ + static _create(root, reference, pointerBeforeReference) { + return new NodeIteratorImpl(root, reference, pointerBeforeReference); + } +} +exports.NodeIteratorImpl = NodeIteratorImpl; +//# sourceMappingURL=NodeIteratorImpl.js.map + +/***/ }), + +/***/ 811: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result["default"] = mod; + return result; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const core = __importStar(__webpack_require__(470)); +const installer = __importStar(__webpack_require__(923)); +const auth = __importStar(__webpack_require__(331)); +const gpg = __importStar(__webpack_require__(884)); +const path = __importStar(__webpack_require__(622)); +const DEFAULT_ID = 'github'; +const DEFAULT_USERNAME = 'GITHUB_ACTOR'; +const DEFAULT_PASSWORD = 'GITHUB_TOKEN'; +const DEFAULT_GPG_PRIVATE_KEY = undefined; +const DEFAULT_GPG_PASSPHRASE = 'GPG_PASSPHRASE'; +function run() { + return __awaiter(this, void 0, void 0, function* () { + try { + // Set secrets before use + core.setSecret('gpg-private-key'); + let version = core.getInput('version'); + if (!version) { + version = core.getInput('java-version', { required: true }); + } + const arch = core.getInput('architecture', { required: true }); + const javaPackage = core.getInput('java-package', { required: true }); + const jdkFile = core.getInput('jdkFile', { required: false }) || ''; + yield installer.getJava(version, arch, jdkFile, javaPackage); + const matchersPath = path.join(__dirname, '..', '..', '.github'); + console.log(`##[add-matcher]${path.join(matchersPath, 'java.json')}`); + const id = core.getInput('server-id', { required: false }) || DEFAULT_ID; + const username = core.getInput('server-username', { required: false }) || DEFAULT_USERNAME; + const password = core.getInput('server-password', { required: false }) || DEFAULT_PASSWORD; + const gpgPrivateKey = core.getInput('gpg-private-key', { required: false }) || + DEFAULT_GPG_PRIVATE_KEY; + const gpgPassphrase = core.getInput('gpg-passphrase', { required: false }) || + (gpgPrivateKey ? DEFAULT_GPG_PASSPHRASE : undefined); + yield auth.configAuthentication(id, username, password, gpgPassphrase); + if (gpgPrivateKey) { + console.log('importing private key'); + const keyFingerprint = (yield gpg.importKey(gpgPrivateKey)) || ''; + core.saveState('gpg-private-key-fingerprint', keyFingerprint); + } + } + catch (error) { + core.setFailed(error.message); + } + }); +} +run(); + + +/***/ }), + +/***/ 813: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const util_1 = __webpack_require__(724); +const interfaces_1 = __webpack_require__(286); +const infra_1 = __webpack_require__(307); +const url_1 = __webpack_require__(835); +let _validationErrorCallback; +/** + * Default ports for a special URL scheme. + */ +const _defaultPorts = { + "ftp": 21, + "file": null, + "http": 80, + "https": 443, + "ws": 80, + "wss": 443 +}; +/** + * The C0 control percent-encode set are the C0 controls and all code points + * greater than U+007E (~). + */ +const _c0ControlPercentEncodeSet = /[\0-\x1F\x7F-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/; +/** + * The fragment percent-encode set is the C0 control percent-encode set and + * U+0020 SPACE, U+0022 ("), U+003C (<), U+003E (>), and U+0060 (`). + */ +const _fragmentPercentEncodeSet = /[ "<>`]|[\0-\x1F\x7F-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/; +/** + * The path percent-encode set is the fragment percent-encode set and + * U+0023 (#), U+003F (?), U+007B ({), and U+007D (}). + */ +const _pathPercentEncodeSet = /[ "<>`#?{}]|[\0-\x1F\x7F-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/; +/** + * The userinfo percent-encode set is the path percent-encode set and + * U+002F (/), U+003A (:), U+003B (;), U+003D (=), U+0040 (@), U+005B ([), + * U+005C (\), U+005D (]), U+005E (^), and U+007C (|). + */ +const _userInfoPercentEncodeSet = /[ "<>`#?{}/:;=@\[\]\\\^\|]|[\0-\x1F\x7F-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/; +/** + * The URL code points are ASCII alphanumeric, U+0021 (!), U+0024 ($), + * U+0026 (&), U+0027 ('), U+0028 LEFT PARENTHESIS, U+0029 RIGHT PARENTHESIS, + * U+002A (*), U+002B (+), U+002C (,), U+002D (-), U+002E (.), U+002F (/), + * U+003A (:), U+003B (;), U+003D (=), U+003F (?), U+0040 (@), U+005F (_), + * U+007E (~), and code points in the range U+00A0 to U+10FFFD, inclusive, + * excluding surrogates and noncharacters. + */ +const _urlCodePoints = /[0-9A-Za-z!\$&-\/:;=\?@_~\xA0-\uD7FF\uE000-\uFDCF\uFDF0-\uFFFD]|[\uD800-\uD83E\uD840-\uD87E\uD880-\uD8BE\uD8C0-\uD8FE\uD900-\uD93E\uD940-\uD97E\uD980-\uD9BE\uD9C0-\uD9FE\uDA00-\uDA3E\uDA40-\uDA7E\uDA80-\uDABE\uDAC0-\uDAFE\uDB00-\uDB3E\uDB40-\uDB7E\uDB80-\uDBBE\uDBC0-\uDBFE][\uDC00-\uDFFF]|[\uD83F\uD87F\uD8BF\uD8FF\uD93F\uD97F\uD9BF\uD9FF\uDA3F\uDA7F\uDABF\uDAFF\uDB3F\uDB7F\uDBBF\uDBFF][\uDC00-\uDFFD]/; +/** + * A forbidden host code point is U+0000 NULL, U+0009 TAB, U+000A LF, + * U+000D CR, U+0020 SPACE, U+0023 (#), U+0025 (%), U+002F (/), U+003A (:), + * U+003F (?), U+0040 (@), U+005B ([), U+005C (\), or U+005D (]). + */ +const _forbiddenHostCodePoint = /[\0\t\f\r #%/:?@\[\\\]]/; +/** + * Sets the callback function for validation errors. + * + * @param validationErrorCallback - a callback function to be called when a + * validation error occurs + */ +function setValidationErrorCallback(validationErrorCallback) { + _validationErrorCallback = validationErrorCallback; +} +exports.setValidationErrorCallback = setValidationErrorCallback; +/** + * Generates a validation error. + * + * @param message - error message + */ +function validationError(message) { + if (_validationErrorCallback !== undefined) { + _validationErrorCallback.call(null, "Validation Error: " + message); + } +} +/** + * Creates a new URL. + */ +function newURL() { + return { + scheme: '', + username: '', + password: '', + host: null, + port: null, + path: [], + query: null, + fragment: null, + _cannotBeABaseURLFlag: false, + _blobURLEntry: null + }; +} +exports.newURL = newURL; +/** + * Determines if the scheme is a special scheme. + * + * @param scheme - a scheme + */ +function isSpecialScheme(scheme) { + return (scheme in _defaultPorts); +} +exports.isSpecialScheme = isSpecialScheme; +/** + * Determines if the URL has a special scheme. + * + * @param url - an URL + */ +function isSpecial(url) { + return isSpecialScheme(url.scheme); +} +exports.isSpecial = isSpecial; +/** + * Returns the default port for a special scheme. + * + * @param scheme - a scheme + */ +function defaultPort(scheme) { + return _defaultPorts[scheme] || null; +} +exports.defaultPort = defaultPort; +/** + * Determines if the URL has credentials. + * + * @param url - an URL + */ +function includesCredentials(url) { + return url.username !== '' || url.password !== ''; +} +exports.includesCredentials = includesCredentials; +/** + * Determines if an URL cannot have credentials. + * + * @param url - an URL + */ +function cannotHaveAUsernamePasswordPort(url) { + /** + * A URL cannot have a username/password/port if its host is null or the + * empty string, its cannot-be-a-base-URL flag is set, or its scheme is + * "file". + */ + return (url.host === null || url.host === "" || url._cannotBeABaseURLFlag || + url.scheme === "file"); +} +exports.cannotHaveAUsernamePasswordPort = cannotHaveAUsernamePasswordPort; +/** + * Serializes an URL into a string. + * + * @param url - an URL + */ +function urlSerializer(url, excludeFragmentFlag = false) { + /** + * 1. Let output be url’s scheme and U+003A (:) concatenated. + */ + let output = url.scheme + ':'; + /** + * 2. If url’s host is non-null: + */ + if (url.host !== null) { + /** + * 2.1. Append "//" to output. + */ + output += '//'; + /** + * 2.2. If url includes credentials, then: + */ + if (includesCredentials(url)) { + /** + * 2.2.1. Append url’s username to output. + * 2.2.2. If url’s password is not the empty string, then append U+003A (:), + * followed by url’s password, to output. + * 2.2.3. Append U+0040 (@) to output. + */ + output += url.username; + if (url.password !== '') { + output += ':' + url.password; + } + output += '@'; + } + /** + * 2.3. Append url’s host, serialized, to output. + * 2.4. If url’s port is non-null, append U+003A (:) followed by url’s port, + * serialized, to output. + */ + output += hostSerializer(url.host); + if (url.port !== null) { + output += ':' + url.port; + } + } + else if (url.host === null && url.scheme === "file") { + /** + * 3. Otherwise, if url’s host is null and url’s scheme is "file", append "//" to output. + */ + output += '//'; + } + /** + * 4. If url’s cannot-be-a-base-URL flag is set, append url’s path[0] to + * output. + * 5. Otherwise, then for each string in url’s path, append U+002F (/) + * followed by the string to output. + */ + if (url._cannotBeABaseURLFlag) { + output += url.path[0]; + } + else { + for (const str of url.path) { + output += '/' + str; + } + } + /** + * 6. If url’s query is non-null, append U+003F (?), followed by url’s + * query, to output. + * 7. If the exclude fragment flag is unset and url’s fragment is non-null, + * append U+0023 (#), followed by url’s fragment, to output. + * 8. Return output. + */ + if (url.query !== null) { + output += '?' + url.query; + } + if (!excludeFragmentFlag && url.fragment !== null) { + output += '#' + url.fragment; + } + return output; +} +exports.urlSerializer = urlSerializer; +/** + * Serializes a host into a string. + * + * @param host - a host + */ +function hostSerializer(host) { + /** + * 1. If host is an IPv4 address, return the result of running the IPv4 + * serializer on host. + * 2. Otherwise, if host is an IPv6 address, return U+005B ([), followed + * by the result of running the IPv6 serializer on host, followed by + * U+005D (]). + * 3. Otherwise, host is a domain, opaque host, or empty host, return host. + */ + if (util_1.isNumber(host)) { + return iPv4Serializer(host); + } + else if (util_1.isArray(host)) { + return '[' + iPv6Serializer(host) + ']'; + } + else { + return host; + } +} +exports.hostSerializer = hostSerializer; +/** + * Serializes an IPv4 address into a string. + * + * @param address - an IPv4 address + */ +function iPv4Serializer(address) { + /** + * 1. Let output be the empty string. + * 2. Let n be the value of address. + * 3. For each i in the range 1 to 4, inclusive: + * 3.1. Prepend n % 256, serialized, to output. + * 3.2. If i is not 4, then prepend U+002E (.) to output. + * 3.3. Set n to floor(n / 256). + * 4. Return output. + */ + let output = ""; + let n = address; + for (let i = 1; i <= 4; i++) { + output = (n % 256).toString() + output; + if (i !== 4) { + output = '.' + output; + } + n = Math.floor(n / 256); + } + return output; +} +exports.iPv4Serializer = iPv4Serializer; +/** + * Serializes an IPv6 address into a string. + * + * @param address - an IPv6 address represented as a list of eight numbers + */ +function iPv6Serializer(address) { + /** + * 1. Let output be the empty string. + * 2. Let compress be an index to the first IPv6 piece in the first longest + * sequences of address’s IPv6 pieces that are 0. + * In 0:f:0:0:f:f:0:0 it would point to the second 0. + * 3. If there is no sequence of address’s IPv6 pieces that are 0 that is + * longer than 1, then set compress to null. + */ + let output = ""; + let compress = null; + let lastIndex = -1; + let count = 0; + let lastCount = 0; + for (let i = 0; i < 8; i++) { + if (address[i] !== 0) + continue; + count = 1; + for (let j = i + 1; j < 8; j++) { + if (address[j] !== 0) + break; + count++; + continue; + } + if (count > lastCount) { + lastCount = count; + lastIndex = i; + } + } + if (lastCount > 1) + compress = lastIndex; + /** + * 4. Let ignore0 be false. + * 5. For each pieceIndex in the range 0 to 7, inclusive: + */ + let ignore0 = false; + for (let pieceIndex = 0; pieceIndex < 8; pieceIndex++) { + /** + * 5.1. If ignore0 is true and address[pieceIndex] is 0, then continue. + * 5.2. Otherwise, if ignore0 is true, set ignore0 to false. + * 5.3. If compress is pieceIndex, then: + */ + if (ignore0 && address[pieceIndex] === 0) + continue; + if (ignore0) + ignore0 = false; + if (compress === pieceIndex) { + /** + * 5.3.1. Let separator be "::" if pieceIndex is 0, and U+003A (:) otherwise. + * 5.3.2. Append separator to output. + * 5.3.3. Set ignore0 to true and continue. + */ + output += (pieceIndex === 0 ? '::' : ':'); + ignore0 = true; + continue; + } + /** + * 5.4. Append address[pieceIndex], represented as the shortest possible + * lowercase hexadecimal number, to output. + * 5.5. If pieceIndex is not 7, then append U+003A (:) to output. + */ + output += address[pieceIndex].toString(16); + if (pieceIndex !== 7) + output += ':'; + } + /** + * 6. Return output. + */ + return output; +} +exports.iPv6Serializer = iPv6Serializer; +/** + * Parses an URL string. + * + * @param input - input string + * @param baseURL - base URL + * @param encodingOverride - encoding override + */ +function urlParser(input, baseURL, encodingOverride) { + /** + * 1. Let url be the result of running the basic URL parser on input with + * base, and encoding override as provided. + * 2. If url is failure, return failure. + * 3. If url’s scheme is not "blob", return url. + * 4. Set url’s blob URL entry to the result of resolving the blob URL url, + * if that did not return failure, and null otherwise. + * 5. Return url. + */ + const url = basicURLParser(input, baseURL, encodingOverride); + if (url === null) + return null; + if (url.scheme !== "blob") + return url; + const entry = resolveABlobURL(url); + if (entry !== null) { + url._blobURLEntry = entry; + } + else { + url._blobURLEntry = null; + } + return url; +} +exports.urlParser = urlParser; +/** + * Parses an URL string. + * + * @param input - input string + * @param baseURL - base URL + * @param encodingOverride - encoding override + */ +function basicURLParser(input, baseURL, encodingOverride, url, stateOverride) { + /** + * 1. If url is not given: + * 1.1. Set url to a new URL. + * 1.2. If input contains any leading or trailing C0 control or space, + * validation error. + * 1.3. Remove any leading and trailing C0 control or space from input. + */ + if (url === undefined) { + url = newURL(); + // leading + const leadingControlOrSpace = /^[\u0000-\u001F\u0020]+/; + const trailingControlOrSpace = /[\u0000-\u001F\u0020]+$/; + if (leadingControlOrSpace.test(input) || trailingControlOrSpace.test(input)) { + validationError("Input string contains leading or trailing control characters or space."); + } + input = input.replace(leadingControlOrSpace, ''); + input = input.replace(trailingControlOrSpace, ''); + } + /** + * 2. If input contains any ASCII tab or newline, validation error. + * 3. Remove all ASCII tab or newline from input. + */ + const tabOrNewline = /[\u0009\u000A\u000D]/g; + if (tabOrNewline.test(input)) { + validationError("Input string contains tab or newline characters."); + } + input = input.replace(tabOrNewline, ''); + /** + * 4. Let state be state override if given, or scheme start state otherwise. + * 5. If base is not given, set it to null. + * 6. Let encoding be UTF-8. + * 7. If encoding override is given, set encoding to the result of getting + * an output encoding from encoding override. + */ + let state = (stateOverride === undefined ? interfaces_1.ParserState.SchemeStart : stateOverride); + if (baseURL === undefined) + baseURL = null; + let encoding = (encodingOverride === undefined || + encodingOverride === "replacement" || encodingOverride === "UTF-16BE" || + encodingOverride === "UTF-16LE" ? "UTF-8" : encodingOverride); + /** + * 8. Let buffer be the empty string. + * 9. Let the @ flag, [] flag, and passwordTokenSeenFlag be unset. + * 10. Let pointer be a pointer to first code point in input. + */ + let buffer = ""; + let atFlag = false; + let arrayFlag = false; + let passwordTokenSeenFlag = false; + const EOF = ""; + const walker = new util_1.StringWalker(input); + /** + * 11. Keep running the following state machine by switching on state. If + * after a run pointer points to the EOF code point, go to the next step. + * Otherwise, increase pointer by one and continue with the state machine. + */ + while (true) { + switch (state) { + case interfaces_1.ParserState.SchemeStart: + /** + * 1. If c is an ASCII alpha, append c, lowercased, to buffer, and set + * state to scheme state. + * 2. Otherwise, if state override is not given, set state to no scheme + * state, and decrease pointer by one. + * 3. Otherwise, validation error, return failure. + */ + if (infra_1.codePoint.ASCIIAlpha.test(walker.c())) { + buffer += walker.c().toLowerCase(); + state = interfaces_1.ParserState.Scheme; + } + else if (stateOverride === undefined) { + state = interfaces_1.ParserState.NoScheme; + walker.pointer--; + } + else { + validationError("Invalid scheme start character."); + return null; + } + break; + case interfaces_1.ParserState.Scheme: + /** + * 1. If c is an ASCII alphanumeric, U+002B (+), U+002D (-), or U+002E + * (.), append c, lowercased, to buffer. + */ + if (infra_1.codePoint.ASCIIAlphanumeric.test(walker.c()) || + walker.c() === '+' || walker.c() === '-' || walker.c() === '.') { + buffer += walker.c().toLowerCase(); + } + else if (walker.c() === ':') { + /** + * 2. Otherwise, if c is U+003A (:), then: + * 2.1. If state override is given, then: + * 2.1.1. If url’s scheme is a special scheme and buffer is not a + * special scheme, then return. + * 2.1.2. If url’s scheme is not a special scheme and buffer is a + * special scheme, then return. + * 2.1.3. If url includes credentials or has a non-null port, and + * buffer is "file", then return. + * 2.1.4. If url’s scheme is "file" and its host is an empty host or + * null, then return. + */ + if (stateOverride !== undefined) { + if (isSpecialScheme(url.scheme) && !isSpecialScheme(buffer)) + return url; + if (!isSpecialScheme(url.scheme) && isSpecialScheme(buffer)) + return url; + if ((includesCredentials(url) || url.port !== null) && buffer === "file") + return url; + if (url.scheme === "file" && (url.host === "" || url.host === null)) + return url; + } + /** + * 2.2. Set url’s scheme to buffer. + */ + url.scheme = buffer; + /** + * 2.3. If state override is given, then: + * 2.3.1. If url’s port is url’s scheme’s default port, then set + * url’s port to null. + * 2.3.2. Return. + */ + if (stateOverride !== undefined) { + if (url.port === defaultPort(url.scheme)) { + url.port = null; + } + return url; + } + /** + * 2.4. Set buffer to the empty string. + */ + buffer = ""; + if (url.scheme === "file") { + /** + * 2.5. If url’s scheme is "file", then: + * 2.5.1. If remaining does not start with "//", validation error. + * 2.5.2. Set state to file state. + */ + if (!walker.remaining().startsWith("//")) { + validationError("Invalid file URL scheme, '//' expected."); + } + state = interfaces_1.ParserState.File; + } + else if (isSpecial(url) && baseURL !== null && baseURL.scheme === url.scheme) { + /** + * 2.6. Otherwise, if url is special, base is non-null, and base’s + * scheme is equal to url’s scheme, set state to special relative + * or authority state. + */ + state = interfaces_1.ParserState.SpecialRelativeOrAuthority; + } + else if (isSpecial(url)) { + /** + * 2.7. Otherwise, if url is special, set state to special + * authority slashes state. + */ + state = interfaces_1.ParserState.SpecialAuthoritySlashes; + } + else if (walker.remaining().startsWith("/")) { + /** + * 2.8. Otherwise, if remaining starts with an U+002F (/), set state + * to path or authority state and increase pointer by one. + */ + state = interfaces_1.ParserState.PathOrAuthority; + walker.pointer++; + } + else { + /** + * 2.9. Otherwise, set url’s cannot-be-a-base-URL flag, append an + * empty string to url’s path, and set state to + * cannot-be-a-base-URL path state. + */ + url._cannotBeABaseURLFlag = true; + url.path.push(""); + state = interfaces_1.ParserState.CannotBeABaseURLPath; + } + } + else if (stateOverride === undefined) { + /** + * 3. Otherwise, if state override is not given, set buffer to the + * empty string, state to no scheme state, and start over (from the + * first code point in input). + */ + buffer = ""; + state = interfaces_1.ParserState.NoScheme; + walker.pointer = 0; + continue; + } + else { + /** + * 4. Otherwise, validation error, return failure. + */ + validationError("Invalid input string."); + return null; + } + break; + case interfaces_1.ParserState.NoScheme: + /** + * 1. If base is null, or base’s cannot-be-a-base-URL flag is set + * and c is not U+0023 (#), validation error, return failure. + * 2. Otherwise, if base’s cannot-be-a-base-URL flag is set and + * c is U+0023 (#), set url’s scheme to base’s scheme, url’s path to + * a copy of base’s path, url’s query to base’s query, url’s + * fragment to the empty string, set url’s cannot-be-a-base-URL + * flag, and set state to fragment state. + * 3. Otherwise, if base’s scheme is not "file", set state to + * relative state and decrease pointer by one. + * 4. Otherwise, set state to file state and decrease pointer by one. + */ + if (baseURL === null || (baseURL._cannotBeABaseURLFlag && walker.c() !== '#')) { + validationError("Invalid input string."); + return null; + } + else if (baseURL._cannotBeABaseURLFlag && walker.c() === '#') { + url.scheme = baseURL.scheme; + url.path = infra_1.list.clone(baseURL.path); + url.query = baseURL.query; + url.fragment = ""; + url._cannotBeABaseURLFlag = true; + state = interfaces_1.ParserState.Fragment; + } + else if (baseURL.scheme !== "file") { + state = interfaces_1.ParserState.Relative; + walker.pointer--; + } + else { + state = interfaces_1.ParserState.File; + walker.pointer--; + } + break; + case interfaces_1.ParserState.SpecialRelativeOrAuthority: + /** + * If c is U+002F (/) and remaining starts with U+002F (/), then set + * state to special authority ignore slashes state and increase + * pointer by one. + * Otherwise, validation error, set state to relative state and + * decrease pointer by one. + */ + if (walker.c() === '/' && walker.remaining().startsWith('/')) { + state = interfaces_1.ParserState.SpecialAuthorityIgnoreSlashes; + walker.pointer++; + } + else { + validationError("Invalid input string."); + state = interfaces_1.ParserState.Relative; + walker.pointer--; + } + break; + case interfaces_1.ParserState.PathOrAuthority: + /** + * If c is U+002F (/), then set state to authority state. + * Otherwise, set state to path state, and decrease pointer by one. + */ + if (walker.c() === '/') { + state = interfaces_1.ParserState.Authority; + } + else { + state = interfaces_1.ParserState.Path; + walker.pointer--; + } + break; + case interfaces_1.ParserState.Relative: + /** + * Set url’s scheme to base’s scheme, and then, switching on c: + */ + if (baseURL === null) { + throw new Error("Invalid parser state. Base URL is null."); + } + url.scheme = baseURL.scheme; + switch (walker.c()) { + case EOF: // EOF + /** + * Set url’s username to base’s username, url’s password to base’s + * password, url’s host to base’s host, url’s port to base’s port, + * url’s path to a copy of base’s path, and url’s query to base’s + * query. + */ + url.username = baseURL.username; + url.password = baseURL.password; + url.host = baseURL.host; + url.port = baseURL.port; + url.path = infra_1.list.clone(baseURL.path); + url.query = baseURL.query; + break; + case '/': + /** + * Set state to relative slash state. + */ + state = interfaces_1.ParserState.RelativeSlash; + break; + case '?': + /** + * Set url’s username to base’s username, url’s password to base’s + * password, url’s host to base’s host, url’s port to base’s port, + * url’s path to a copy of base’s path, url’s query to the empty + * string, and state to query state. + */ + url.username = baseURL.username; + url.password = baseURL.password; + url.host = baseURL.host; + url.port = baseURL.port; + url.path = infra_1.list.clone(baseURL.path); + url.query = ""; + state = interfaces_1.ParserState.Query; + break; + case '#': + /** + * Set url’s username to base’s username, url’s password to base’s + * password, url’s host to base’s host, url’s port to base’s port, + * url’s path to a copy of base’s path, url’s query to base’s + * query, url’s fragment to the empty string, and state to + * fragment state. + */ + url.username = baseURL.username; + url.password = baseURL.password; + url.host = baseURL.host; + url.port = baseURL.port; + url.path = infra_1.list.clone(baseURL.path); + url.query = baseURL.query; + url.fragment = ""; + state = interfaces_1.ParserState.Fragment; + break; + default: + /** + * If url is special and c is U+005C (\), validation error, + * set state to relative slash state. + * Otherwise, run these steps: + * 1. Set url’s username to base’s username, url’s password to + * base’s password, url’s host to base’s host, url’s port to + * base’s port, url’s path to a copy of base’s path, and then + * remove url’s path’s last item, if any. + * 2. Set state to path state, and decrease pointer by one. + */ + if (isSpecial(url) && walker.c() === '\\') { + validationError("Invalid input string."); + state = interfaces_1.ParserState.RelativeSlash; + } + else { + url.username = baseURL.username; + url.password = baseURL.password; + url.host = baseURL.host; + url.port = baseURL.port; + url.path = infra_1.list.clone(baseURL.path); + if (url.path.length !== 0) + url.path.splice(url.path.length - 1, 1); + state = interfaces_1.ParserState.Path; + walker.pointer--; + } + break; + } + break; + case interfaces_1.ParserState.RelativeSlash: + /** + * 1. If url is special and c is U+002F (/) or U+005C (\), then: + * 1.1. If c is U+005C (\), validation error. + * 1.2. Set state to special authority ignore slashes state. + * 2. Otherwise, if c is U+002F (/), then set state to authority state. + * 3. Otherwise, set url’s username to base’s username, url’s password + * to base’s password, url’s host to base’s host, url’s port to base’s + * port, state to path state, and then, decrease pointer by one. + */ + if (isSpecial(url) && (walker.c() === '/' || walker.c() === '\\')) { + if (walker.c() === '\\') { + validationError("Invalid input string."); + } + state = interfaces_1.ParserState.SpecialAuthorityIgnoreSlashes; + } + else if (walker.c() === '/') { + state = interfaces_1.ParserState.Authority; + } + else { + if (baseURL === null) { + throw new Error("Invalid parser state. Base URL is null."); + } + url.username = baseURL.username; + url.password = baseURL.password; + url.host = baseURL.host; + url.port = baseURL.port; + state = interfaces_1.ParserState.Path; + walker.pointer--; + } + break; + case interfaces_1.ParserState.SpecialAuthoritySlashes: + /** + * If c is U+002F (/) and remaining starts with U+002F (/), then set + * state to special authority ignore slashes state and increase + * pointer by one. + * Otherwise, validation error, set state to special authority ignore + * slashes state, and decrease pointer by one. + */ + if (walker.c() === '/' && walker.remaining().startsWith('/')) { + state = interfaces_1.ParserState.SpecialAuthorityIgnoreSlashes; + walker.pointer++; + } + else { + validationError("Expected '//'."); + state = interfaces_1.ParserState.SpecialAuthorityIgnoreSlashes; + walker.pointer--; + } + break; + case interfaces_1.ParserState.SpecialAuthorityIgnoreSlashes: + /** + * If c is neither U+002F (/) nor U+005C (\), then set state to + * authority state and decrease pointer by one. + * Otherwise, validation error. + */ + if (walker.c() !== '/' && walker.c() !== '\\') { + state = interfaces_1.ParserState.Authority; + walker.pointer--; + } + else { + validationError("Unexpected '/' or '\\'."); + } + break; + case interfaces_1.ParserState.Authority: + /** + * 1. If c is U+0040 (@), then: + */ + if (walker.c() === '@') { + /** + * 1.1. Validation error. + * 1.2. If the @ flag is set, prepend "%40" to buffer. + * 1.3. Set the @ flag. + * 1.4. For each codePoint in buffer: + */ + validationError("Unexpected '@'."); + if (atFlag) + buffer = '%40' + buffer; + atFlag = true; + for (const codePoint of buffer) { + /** + * 1.4.1. If codePoint is U+003A (:) and passwordTokenSeenFlag is + * unset, then set passwordTokenSeenFlag and continue. + * 1.4.2. Let encodedCodePoints be the result of running UTF-8 + * percent encode codePoint using the userinfo percent-encode set. + * 1.4.3. If passwordTokenSeenFlag is set, then append + * encodedCodePoints to url’s password. + * 1.4.4. Otherwise, append encodedCodePoints to url’s username. + */ + if (codePoint === ':' && !passwordTokenSeenFlag) { + passwordTokenSeenFlag = true; + continue; + } + const encodedCodePoints = utf8PercentEncode(codePoint, _userInfoPercentEncodeSet); + if (passwordTokenSeenFlag) { + url.password += encodedCodePoints; + } + else { + url.username += encodedCodePoints; + } + } + /** + * 1.5. Set buffer to the empty string. + */ + buffer = ""; + } + else if (walker.c() === EOF || walker.c() === '/' || walker.c() === '?' || walker.c() === '#' || + (isSpecial(url) && walker.c() === '\\')) { + /** + * 2. Otherwise, if one of the following is true + * - c is the EOF code point, U+002F (/), U+003F (?), or U+0023 (#) + * - url is special and c is U+005C (\) + * then: + * 2.1. If @ flag is set and buffer is the empty string, validation + * error, return failure. + * 2.2. Decrease pointer by the number of code points in buffer plus + * one, set buffer to the empty string, and set state to host state. + */ + if (atFlag && buffer === "") { + validationError("Invalid input string."); + return null; + } + walker.pointer -= (buffer.length + 1); + buffer = ""; + state = interfaces_1.ParserState.Host; + } + else { + /** + * 3. Otherwise, append c to buffer. + */ + buffer += walker.c(); + } + break; + case interfaces_1.ParserState.Host: + case interfaces_1.ParserState.Hostname: + if (stateOverride !== undefined && url.scheme === "file") { + /** + * 1. If state override is given and url’s scheme is "file", then + * decrease pointer by one and set state to file host state. + */ + walker.pointer--; + state = interfaces_1.ParserState.FileHost; + } + else if (walker.c() === ':' && !arrayFlag) { + /** + * 2. Otherwise, if c is U+003A (:) and the [] flag is unset, then: + * 2.1. If buffer is the empty string, validation error, return + * failure. + * 2.2. Let host be the result of host parsing buffer with url is + * not special. + * 2.3. If host is failure, then return failure. + * 2.4. Set url’s host to host, buffer to the empty string, and + * state to port state. + * 2.5. If state override is given and state override is hostname + * state, then return. + */ + if (buffer === "") { + validationError("Invalid input string."); + return null; + } + const host = hostParser(buffer, !isSpecial(url)); + if (host === null) + return null; + url.host = host; + buffer = ""; + state = interfaces_1.ParserState.Port; + if (stateOverride === interfaces_1.ParserState.Hostname) + return url; + } + else if (walker.c() === EOF || walker.c() === '/' || walker.c() === '?' || walker.c() === '#' || + (isSpecial(url) && walker.c() === '\\')) { + /** + * 3. Otherwise, if one of the following is true + * - c is the EOF code point, U+002F (/), U+003F (?), or U+0023 (#) + * - url is special and c is U+005C (\) + * then decrease pointer by one, and then: + * 3.1. If url is special and buffer is the empty string, validation + * error, return failure. + * 3.2. Otherwise, if state override is given, buffer is the empty + * string, and either url includes credentials or url’s port is + * non-null, validation error, return. + * 3.3. Let host be the result of host parsing buffer with url is + * not special. + * 3.4. If host is failure, then return failure. + * 3.5. Set url’s host to host, buffer to the empty string, and + * state to path start state. + * 3.6. If state override is given, then return. + */ + walker.pointer--; + if (isSpecial(url) && buffer === "") { + validationError("Invalid input string."); + return null; + } + else if (stateOverride !== undefined && buffer === "" && + (includesCredentials(url) || url.port !== null)) { + validationError("Invalid input string."); + return url; + } + const host = hostParser(buffer, !isSpecial(url)); + if (host === null) + return null; + url.host = host; + buffer = ""; + state = interfaces_1.ParserState.PathStart; + if (stateOverride !== undefined) + return url; + } + else { + /** + * 4. Otherwise: + * 4.1. If c is U+005B ([), then set the [] flag. + * 4.2. If c is U+005D (]), then unset the [] flag. + * 4.3. Append c to buffer. + */ + if (walker.c() === '[') + arrayFlag = true; + if (walker.c() === ']') + arrayFlag = false; + buffer += walker.c(); + } + break; + case interfaces_1.ParserState.Port: + if (infra_1.codePoint.ASCIIDigit.test(walker.c())) { + /** + * 1. If c is an ASCII digit, append c to buffer. + */ + buffer += walker.c(); + } + else if (walker.c() === EOF || walker.c() === '/' || walker.c() === '?' || walker.c() === '#' || + (isSpecial(url) && walker.c() === '\\') || stateOverride) { + /** + * 2. Otherwise, if one of the following is true + * - c is the EOF code point, U+002F (/), U+003F (?), or U+0023 (#) + * - url is special and c is U+005C (\) + * - state override is given + * then: + */ + if (buffer !== "") { + /** + * 2.1. If buffer is not the empty string, then: + * 2.1.1. Let port be the mathematical integer value that is + * represented by buffer in radix-10 using ASCII digits for digits + * with values 0 through 9. + * 2.1.2. If port is greater than 2**16 − 1, validation error, + * return failure. + * 2.1.3. Set url’s port to null, if port is url’s scheme’s default + * port, and to port otherwise. + * 2.1.4. Set buffer to the empty string. + */ + if (buffer !== "") { + const port = parseInt(buffer, 10); + if (port > Math.pow(2, 16) - 1) { + validationError("Invalid port number."); + return null; + } + url.port = (port === defaultPort(url.scheme) ? null : port); + buffer = ""; + } + } + /** + * 2.2. If state override is given, then return. + * 2.3. Set state to path start state, and decrease pointer by one. + */ + if (stateOverride !== undefined) { + return url; + } + state = interfaces_1.ParserState.PathStart; + walker.pointer--; + } + else { + /** + * 3. Otherwise, validation error, return failure. + */ + validationError("Invalid input string."); + return null; + } + break; + case interfaces_1.ParserState.File: + /** + * 1. Set url’s scheme to "file". + */ + url.scheme = "file"; + if (walker.c() === '/' || walker.c() === '\\') { + /** + * 2. If c is U+002F (/) or U+005C (\), then: + * 2.1. If c is U+005C (\), validation error. + * 2.2. Set state to file slash state. + */ + if (walker.c() === '\\') { + validationError("Invalid input string."); + } + state = interfaces_1.ParserState.FileSlash; + } + else if (baseURL !== null && baseURL.scheme === "file") { + /** + * 3. Otherwise, if base is non-null and base’s scheme is "file", + * switch on c: + */ + switch (walker.c()) { + case EOF: + /** + * Set url’s host to base’s host, url’s path to a copy of base’s + * path, and url’s query to base’s query. + */ + url.host = baseURL.host; + url.path = infra_1.list.clone(baseURL.path); + url.query = baseURL.query; + break; + case '?': + /** + * Set url’s host to base’s host, url’s path to a copy of base’s + * path, url’s query to the empty string, and state to query + * state. + */ + url.host = baseURL.host; + url.path = infra_1.list.clone(baseURL.path); + url.query = ""; + state = interfaces_1.ParserState.Query; + break; + case '#': + /** + * Set url’s host to base’s host, url’s path to a copy of base’s + * path, url’s query to base’s query, url’s fragment to the + * empty string, and state to fragment state. + */ + url.host = baseURL.host; + url.path = infra_1.list.clone(baseURL.path); + url.query = baseURL.query; + url.fragment = ""; + state = interfaces_1.ParserState.Fragment; + break; + default: + /** + * 1. If the substring from pointer in input does not start + * with a Windows drive letter, then set url’s host to base’s + * host, url’s path to a copy of base’s path, and then shorten + * url’s path. + * _Note:_ is a (platform-independent) Windows drive letter + * quirk. + * 2. Otherwise, validation error. + * 3. Set state to path state, and decrease pointer by one. + */ + if (!startsWithAWindowsDriveLetter(walker.substring())) { + url.host = baseURL.host; + url.path = infra_1.list.clone(baseURL.path); + shorten(url); + } + else { + validationError("Unexpected windows drive letter in input string."); + } + state = interfaces_1.ParserState.Path; + walker.pointer--; + break; + } + } + else { + /** + * 4. Otherwise, set state to path state, and decrease pointer by + * one. + */ + state = interfaces_1.ParserState.Path; + walker.pointer--; + } + break; + case interfaces_1.ParserState.FileSlash: + if (walker.c() === '/' || walker.c() === '\\') { + /** + * 1. If c is U+002F (/) or U+005C (\), then: + * 1.1. If c is U+005C (\), validation error. + * 1.2. Set state to file host state. + */ + if (walker.c() === '\\') { + validationError("Invalid input string."); + } + state = interfaces_1.ParserState.FileHost; + } + else { + /** + * 2. Otherwise: + * 2.1. If base is non-null, base’s scheme is "file", and the + * substring from pointer in input does not start with a Windows + * drive letter, then: + * 2.1.1. If base’s path[0] is a normalized Windows drive letter, + * then append base’s path[0] to url’s path. + * _Note:_ is a (platform-independent) Windows drive letter + * quirk. Both url’s and base’s host are null under these conditions + * and therefore not copied. + * 2.1.2. Otherwise, set url’s host to base’s host. + * 2.2. Set state to path state, and decrease pointer by one. + */ + if (baseURL !== null && baseURL.scheme === "file" && + !startsWithAWindowsDriveLetter(walker.substring())) { + if (isNormalizedWindowsDriveLetter(baseURL.path[0])) { + url.path.push(baseURL.path[0]); + } + else { + url.host = baseURL.host; + } + } + state = interfaces_1.ParserState.Path; + walker.pointer--; + } + break; + case interfaces_1.ParserState.FileHost: + if (walker.c() === EOF || walker.c() === '/' || walker.c() === '\\' || + walker.c() === '?' || walker.c() === '#') { + /** + * 1. If c is the EOF code point, U+002F (/), U+005C (\), U+003F (?), + * or U+0023 (#), then decrease pointer by one and then: + */ + walker.pointer--; + if (stateOverride === undefined && isWindowsDriveLetter(buffer)) { + /** + * 1.1. If state override is not given and buffer is a Windows drive + * letter, validation error, set state to path state. + * _Note:_ is a (platform-independent) Windows drive letter + * quirk. buffer is not reset here and instead used in the path state. + */ + validationError("Unexpected windows drive letter in input string."); + state = interfaces_1.ParserState.Path; + } + else if (buffer === "") { + /** + * 1.2. Otherwise, if buffer is the empty string, then: + * 1.2.1. Set url’s host to the empty string. + * 1.2.2. If state override is given, then return. + * 1.2.3. Set state to path start state. + */ + url.host = ""; + if (stateOverride !== undefined) + return url; + state = interfaces_1.ParserState.PathStart; + } + else { + /** + * 1.3. Otherwise, run these steps: + * 1.3.1. Let host be the result of host parsing buffer with url + * is not special. + * 1.3.2. If host is failure, then return failure. + * 1.3.3. If host is "localhost", then set host to the empty + * string. + * 1.3.4. Set url’s host to host. + * 1.3.5. If state override is given, then return. + * 1.3.6. Set buffer to the empty string and state to path start + * state. + */ + let host = hostParser(buffer, !isSpecial(url)); + if (host === null) + return null; + if (host === "localhost") + host = ""; + url.host = host; + if (stateOverride !== undefined) + return url; + buffer = ""; + state = interfaces_1.ParserState.PathStart; + } + } + else { + /** + * 2. Otherwise, append c to buffer. + */ + buffer += walker.c(); + } + break; + case interfaces_1.ParserState.PathStart: + if (isSpecial(url)) { + /** + * 1. If url is special, then: + * 1.1. If c is U+005C (\), validation error. + * 1.2. Set state to path state. + * 1.3. If c is neither U+002F (/) nor U+005C (\), then decrease + * pointer by one. + */ + if (walker.c() === '\\') { + validationError("Invalid input string."); + } + state = interfaces_1.ParserState.Path; + if (walker.c() !== '/' && walker.c() !== '\\') + walker.pointer--; + } + else if (stateOverride === undefined && walker.c() === '?') { + /** + * 2. Otherwise, if state override is not given and c is U+003F (?), + * set url’s query to the empty string and state to query state. + */ + url.query = ""; + state = interfaces_1.ParserState.Query; + } + else if (stateOverride === undefined && walker.c() === '#') { + /** + * 3. Otherwise, if state override is not given and c is U+0023 (#), + * set url’s fragment to the empty string and state to fragment + * state. + */ + url.fragment = ""; + state = interfaces_1.ParserState.Fragment; + } + else if (walker.c() !== EOF) { + /** + * 4. Otherwise, if c is not the EOF code point: + * 4.1. Set state to path state. + * 4.2. If c is not U+002F (/), then decrease pointer by one. + */ + state = interfaces_1.ParserState.Path; + if (walker.c() !== '/') + walker.pointer--; + } + break; + case interfaces_1.ParserState.Path: + if ((walker.c() === EOF || walker.c() === '/') || + (isSpecial(url) && walker.c() === '\\') || + (stateOverride === undefined && (walker.c() === '?' || walker.c() === '#'))) { + /** + * 1. If one of the following is true + * - c is the EOF code point or U+002F (/) + * - url is special and c is U+005C (\) + * - state override is not given and c is U+003F (?) or U+0023 (#) + * then: + */ + if (isSpecial(url) && walker.c() === '\\') { + /** + * 1.1 If url is special and c is U+005C (\), validation error. + */ + validationError("Invalid input string."); + } + if (isDoubleDotPathSegment(buffer)) { + /** + * 1.2. If buffer is a double-dot path segment, shorten url’s path, + * and then if neither c is U+002F (/), nor url is special and c is + * U+005C (\), append the empty string to url’s path. + */ + shorten(url); + if (walker.c() !== '/' && !(isSpecial(url) && walker.c() === '\\')) { + url.path.push(""); + } + } + else if (isSingleDotPathSegment(buffer) && walker.c() !== '/' && + !(isSpecial(url) && walker.c() === '\\')) { + /** + * 1.3. Otherwise, if buffer is a single-dot path segment and if + * neither c is U+002F (/), nor url is special and c is U+005C (\), + * append the empty string to url’s path. + */ + url.path.push(""); + } + else if (!isSingleDotPathSegment(buffer)) { + /** + * 1.4. Otherwise, if buffer is not a single-dot path segment, then: + */ + if (url.scheme === "file" && url.path.length === 0 && + isWindowsDriveLetter(buffer)) { + /** + * 1.4.1. If url’s scheme is "file", url’s path is empty, and + * buffer is a Windows drive letter, then: + * 1.4.1.1. If url’s host is neither the empty string nor null, + * validation error, set url’s host to the empty string. + * 1.4.1.2. Replace the second code point in buffer with U+003A (:). + * _Note:_ is a (platform-independent) Windows drive letter quirk. + */ + if (url.host !== null && url.host !== "") { + validationError("Invalid input string."); + url.host = ""; + } + const bufferCodePoints = Array.from(buffer); + buffer = bufferCodePoints.slice(0, 1) + ':' + bufferCodePoints.slice(2); + } + /** + * 1.4.2. Append buffer to url’s path. + */ + url.path.push(buffer); + } + /** + * 1.5. Set buffer to the empty string. + */ + buffer = ""; + /** + * 1.6. If url’s scheme is "file" and c is the EOF code point, + * U+003F (?), or U+0023 (#), then while url’s path’s size is + * greater than 1 and url’s path[0] is the empty string, validation + * error, remove the first item from url’s path. + */ + if (url.scheme === "file" && (walker.c() === EOF || walker.c() === '?' || walker.c() === '#')) { + while (url.path.length > 1 && url.path[0] === "") { + validationError("Invalid input string."); + url.path.splice(0, 1); + } + } + /** + * 1.7. If c is U+003F (?), then set url’s query to the empty string + * and state to query state. + * 1.8. If c is U+0023 (#), then set url’s fragment to the empty + * string and state to fragment state. + */ + if (walker.c() === '?') { + url.query = ""; + state = interfaces_1.ParserState.Query; + } + if (walker.c() === '#') { + url.fragment = ""; + state = interfaces_1.ParserState.Fragment; + } + } + else { + /** + * 2. Otherwise, run these steps: + * 2.1. If c is not a URL code point and not U+0025 (%), validation + * error. + * 2.2. If c is U+0025 (%) and remaining does not start with two + * ASCII hex digits, validation error. + * 2.3. UTF-8 percent encode c using the path percent-encode set, + * and append the result to buffer. + */ + if (!_urlCodePoints.test(walker.c()) && walker.c() !== '%') { + validationError("Character is not a URL code point or a percent encoded character."); + } + if (walker.c() === '%' && !/^[0-9a-fA-F][0-9a-fA-F]/.test(walker.remaining())) { + validationError("Percent encoded character must be followed by two hex digits."); + } + buffer += utf8PercentEncode(walker.c(), _pathPercentEncodeSet); + } + break; + case interfaces_1.ParserState.CannotBeABaseURLPath: + /** + * 1. If c is U+003F (?), then set url’s query to the empty string and + * state to query state. + * 2. Otherwise, if c is U+0023 (#), then set url’s fragment to the + * empty string and state to fragment state. + * 3. Otherwise: + * 3.1. If c is not the EOF code point, not a URL code point, and not + * U+0025 (%), validation error. + * 3.2. If c is U+0025 (%) and remaining does not start with two ASCII + * hex digits, validation error. + * 3.3. If c is not the EOF code point, UTF-8 percent encode c using + * the C0 control percent-encode set, and append the result to url’s + * path[0]. + */ + if (walker.c() === '?') { + url.query = ""; + state = interfaces_1.ParserState.Query; + } + else if (walker.c() === '#') { + url.fragment = ""; + state = interfaces_1.ParserState.Fragment; + } + else { + if (walker.c() !== EOF && !_urlCodePoints.test(walker.c()) && walker.c() !== '%') { + validationError("Character is not a URL code point or a percent encoded character."); + } + if (walker.c() === '%' && !/^[0-9a-fA-F][0-9a-fA-F]/.test(walker.remaining())) { + validationError("Percent encoded character must be followed by two hex digits."); + } + if (walker.c() !== EOF) { + url.path[0] += utf8PercentEncode(walker.c(), _c0ControlPercentEncodeSet); + } + } + break; + case interfaces_1.ParserState.Query: + /** + * 1. If encoding is not UTF-8 and one of the following is true + * - url is not special + * - url’s scheme is "ws" or "wss" + * then set encoding to UTF-8. + */ + if (encoding !== "UTF-8" && (!isSpecial(url) || + url.scheme === "ws" || url.scheme === "wss")) { + encoding = "UTF-8"; + } + if (stateOverride === undefined && walker.c() === '#') { + /** + * 2. If state override is not given and c is U+0023 (#), then set + * url’s fragment to the empty string and state to fragment state. + */ + url.fragment = ""; + state = interfaces_1.ParserState.Fragment; + } + else if (walker.c() !== EOF) { + /** + * 3. Otherwise, if c is not the EOF code point: + * 3.1. If c is not a URL code point and not U+0025 (%), validation + * error. + */ + if (!_urlCodePoints.test(walker.c()) && walker.c() !== '%') { + validationError("Character is not a URL code point or a percent encoded character."); + } + /** + * 3.2. If c is U+0025 (%) and remaining does not start with two + * ASCII hex digits, validation error. + */ + if (walker.c() === '%' && !/^[0-9a-fA-F][0-9a-fA-F]/.test(walker.remaining())) { + validationError("Percent encoded character must be followed by two hex digits."); + } + /** + * 3.3. Let bytes be the result of encoding c using encoding. + */ + if (encoding.toUpperCase() !== "UTF-8") { + throw new Error("Only UTF-8 encoding is supported."); + } + let bytes = util_1.utf8Encode(walker.c()); + /** + * 3.4. If bytes starts with `&#` and ends with 0x3B (;), then: + */ + if (bytes.length >= 3 && bytes[0] === 38 && bytes[1] === 35 && + bytes[bytes.length - 1] === 59) { + /** + * 3.4.1. Replace `&#` at the start of bytes with `%26%23`. + * 3.4.2. Replace 0x3B (;) at the end of bytes with `%3B`. + * 3.4.4. Append bytes, isomorphic decoded, to url’s query. + * _Note:_ can happen when encoding code points using a + * non-UTF-8 encoding. + */ + bytes = bytes.subarray(2, bytes.length - 1); + url.query += "%26%23" + infra_1.byteSequence.isomorphicDecode(bytes) + "%3B"; + } + else { + /** + * 3.5. Otherwise, for each byte in bytes: + * 3.5.1. If one of the following is true + * - byte is less than 0x21 (!) + * - byte is greater than 0x7E (~) + * - byte is 0x22 ("), 0x23 (#), 0x3C (<), or 0x3E (>) + * - byte is 0x27 (') and url is special + * then append byte, percent encoded, to url’s query. + * 3.5.2. Otherwise, append a code point whose value is byte to + * url’s query. + */ + for (const byte of bytes) { + if (byte < 0x21 || byte > 0x7E || byte === 0x22 || + byte === 0x23 || byte === 0x3C || byte === 0x3E || + (byte === 0x27 && isSpecial(url))) { + url.query += percentEncode(byte); + } + else { + url.query += String.fromCharCode(byte); + } + } + } + } + break; + case interfaces_1.ParserState.Fragment: + /** + * Switching on c: + * - The EOF code point + * Do nothing. + * - U+0000 NULL + * Validation error. + * - Otherwise + * 1. If c is not a URL code point and not U+0025 (%), validation + * error. + * 2. If c is U+0025 (%) and remaining does not start with two ASCII + * hex digits, validation error. + * 3. UTF-8 percent encode c using the fragment percent-encode set and + * append the result to url’s fragment. + */ + if (walker.c() === EOF) { + // + } + else if (walker.c() === "\u0000") { + validationError("NULL character in input string."); + } + else { + if (!_urlCodePoints.test(walker.c()) && walker.c() !== '%') { + validationError("Unexpected character in fragment string."); + } + if (walker.c() === '%' && !/^[A-Za-z0-9][A-Za-z0-9]/.test(walker.remaining())) { + validationError("Unexpected character in fragment string."); + } + url.fragment += utf8PercentEncode(walker.c(), _fragmentPercentEncodeSet); + } + break; + } + if (walker.eof) + break; + else + walker.pointer++; + } + /** + * 12. Return url. + */ + return url; +} +exports.basicURLParser = basicURLParser; +/** + * Sets a URL's username. + * + * @param url - a URL + * @param username - username string + */ +function setTheUsername(url, username) { + /** + * 1. Set url’s username to the empty string. + * 2. For each code point in username, UTF-8 percent encode it using the + * userinfo percent-encode set, and append the result to url’s username. + */ + let result = ""; + for (const codePoint of username) { + result += utf8PercentEncode(codePoint, _userInfoPercentEncodeSet); + } + url.username = result; +} +exports.setTheUsername = setTheUsername; +/** + * Sets a URL's password. + * + * @param url - a URL + * @param username - password string + */ +function setThePassword(url, password) { + /** + * 1. Set url’s password to the empty string. + * 2. For each code point in password, UTF-8 percent encode it using the + * userinfo percent-encode set, and append the result to url’s password. + */ + let result = ""; + for (const codePoint of password) { + result += utf8PercentEncode(codePoint, _userInfoPercentEncodeSet); + } + url.password = result; +} +exports.setThePassword = setThePassword; +/** + * Determines if the string represents a single dot path. + * + * @param str - a string + */ +function isSingleDotPathSegment(str) { + return str === '.' || str.toLowerCase() === "%2e"; +} +exports.isSingleDotPathSegment = isSingleDotPathSegment; +/** + * Determines if the string represents a double dot path. + * + * @param str - a string + */ +function isDoubleDotPathSegment(str) { + const lowerStr = str.toLowerCase(); + return lowerStr === ".." || lowerStr === ".%2e" || + lowerStr === "%2e." || lowerStr === "%2e%2e"; +} +exports.isDoubleDotPathSegment = isDoubleDotPathSegment; +/** + * Shorten's URL's path. + * + * @param url - an URL + */ +function shorten(url) { + /** + * 1. Let path be url’s path. + * 2. If path is empty, then return. + * 3. If url’s scheme is "file", path’s size is 1, and path[0] is a + * normalized Windows drive letter, then return. + * 4. Remove path’s last item. + */ + const path = url.path; + if (path.length === 0) + return; + if (url.scheme === "file" && path.length === 1 && + isNormalizedWindowsDriveLetter(path[0])) + return; + url.path.splice(url.path.length - 1, 1); +} +exports.shorten = shorten; +/** + * Determines if a string is a normalized Windows drive letter. + * + * @param str - a string + */ +function isNormalizedWindowsDriveLetter(str) { + /** + * A normalized Windows drive letter is a Windows drive letter of which the + * second code point is U+003A (:). + */ + return str.length >= 2 && infra_1.codePoint.ASCIIAlpha.test(str[0]) && + str[1] === ':'; +} +exports.isNormalizedWindowsDriveLetter = isNormalizedWindowsDriveLetter; +/** + * Determines if a string is a Windows drive letter. + * + * @param str - a string + */ +function isWindowsDriveLetter(str) { + /** + * A Windows drive letter is two code points, of which the first is an ASCII + * alpha and the second is either U+003A (:) or U+007C (|). + */ + return str.length >= 2 && infra_1.codePoint.ASCIIAlpha.test(str[0]) && + (str[1] === ':' || str[1] === '|'); +} +exports.isWindowsDriveLetter = isWindowsDriveLetter; +/** + * Determines if a string starts with a Windows drive letter. + * + * @param str - a string + */ +function startsWithAWindowsDriveLetter(str) { + /** + * A string starts with a Windows drive letter if all of the following are + * true: + * - its length is greater than or equal to 2 + * - its first two code points are a Windows drive letter + * - its length is 2 or its third code point is U+002F (/), U+005C (\), + * U+003F (?), or U+0023 (#). + */ + return str.length >= 2 && isWindowsDriveLetter(str) && + (str.length === 2 || (str[2] === '/' || str[2] === '\\' || + str[2] === '?' || str[2] === '#')); +} +exports.startsWithAWindowsDriveLetter = startsWithAWindowsDriveLetter; +/** + * Parses a host string. + * + * @param input - input string + * @param isNotSpecial - `true` if the source URL is not special; otherwise + * `false`. + */ +function hostParser(input, isNotSpecial = false) { + /** + * 1. If isNotSpecial is not given, then set isNotSpecial to false. + * 2. If input starts with U+005B ([), then: + * 2.1. If input does not end with U+005D (]), validation error, return + * failure. + * 2.2. Return the result of IPv6 parsing input with its leading U+005B ([) + * and trailing U+005D (]) removed. + */ + if (input.startsWith('[')) { + if (!input.endsWith(']')) { + validationError("Expected ']' after '['."); + return null; + } + return iPv6Parser(input.substring(1, input.length - 1)); + } + /** + * 3. If isNotSpecial is true, then return the result of opaque-host parsing + * input. + */ + if (isNotSpecial) { + return opaqueHostParser(input); + } + /** + * 4. Let domain be the result of running UTF-8 decode without BOM on the + * string percent decoding of input. + * _Note:_ Alternatively UTF-8 decode without BOM or fail can be used, + * coupled with an early return for failure, as domain to ASCII fails + * on U+FFFD REPLACEMENT CHARACTER. + */ + const domain = util_1.utf8Decode(stringPercentDecode(input)); + /** + * 5. Let asciiDomain be the result of running domain to ASCII on domain. + * 6. If asciiDomain is failure, validation error, return failure. + * 7. If asciiDomain contains a forbidden host code point, validation error, + * return failure. + */ + const asciiDomain = domainToASCII(domain); + if (asciiDomain === null) { + validationError("Invalid domain."); + return null; + } + if (_forbiddenHostCodePoint.test(asciiDomain)) { + validationError("Invalid domain."); + return null; + } + /** + * 8. Let ipv4Host be the result of IPv4 parsing asciiDomain. + * 9. If ipv4Host is an IPv4 address or failure, return ipv4Host. + * 10. Return asciiDomain. + */ + const ipv4Host = iPv4Parser(asciiDomain); + if (ipv4Host === null || util_1.isNumber(ipv4Host)) + return ipv4Host; + return asciiDomain; +} +exports.hostParser = hostParser; +/** + * Parses a string containing an IP v4 address. + * + * @param input - input string + * @param isNotSpecial - `true` if the source URL is not special; otherwise + * `false`. + */ +function iPv4NumberParser(input, validationErrorFlag = { value: false }) { + /** + * 1. Let R be 10. + */ + let R = 10; + if (input.startsWith("0x") || input.startsWith("0X")) { + /** + * 2. If input contains at least two code points and the first two code + * points are either "0x" or "0X", then: + * 2.1. Set validationErrorFlag. + * 2.2. Remove the first two code points from input. + * 2.3. Set R to 16. + */ + validationErrorFlag.value = true; + input = input.substr(2); + R = 16; + } + else if (input.length >= 2 && input[0] === '0') { + /** + * 3. Otherwise, if input contains at least two code points and the first + * code point is U+0030 (0), then: + * 3.1. Set validationErrorFlag. + * 3.2. Remove the first code point from input. + * 3.3. Set R to 8. + */ + validationErrorFlag.value = true; + input = input.substr(1); + R = 8; + } + /** + * 4. If input is the empty string, then return zero. + * 5. If input contains a code point that is not a radix-R digit, then + * return failure. + */ + if (input === "") + return 0; + const radixRDigits = (R === 10 ? /^[0-9]+$/ : (R === 16 ? /^[0-9A-Fa-f]+$/ : /^[0-7]+$/)); + if (!radixRDigits.test(input)) + return null; + /** + * 6. Return the mathematical integer value that is represented by input in + * radix-R notation, using ASCII hex digits for digits with values + * 0 through 15. + */ + return parseInt(input, R); +} +exports.iPv4NumberParser = iPv4NumberParser; +/** + * Parses a string containing an IP v4 address. + * + * @param input - input string + */ +function iPv4Parser(input) { + /** + * 1. Let validationErrorFlag be unset. + * 2. Let parts be input split on U+002E (.). + */ + const validationErrorFlag = { value: false }; + const parts = input.split('.'); + /** + * 3. If the last item in parts is the empty string, then: + * 3.1. Set validationErrorFlag. + * 3.2. If parts has more than one item, then remove the last item from + * parts. + */ + if (parts[parts.length - 1] === "") { + validationErrorFlag.value = true; + if (parts.length > 1) + parts.pop(); + } + /** + * 4. If parts has more than four items, return input. + */ + if (parts.length > 4) + return input; + /** + * 5. Let numbers be the empty list. + * 6. For each part in parts: + * 6.1. If part is the empty string, return input. + * 6.2. Let n be the result of parsing part using validationErrorFlag. + * 6.3. If n is failure, return input. + * 6.4. Append n to numbers. + */ + const numbers = []; + for (const part of parts) { + if (part === "") + return input; + const n = iPv4NumberParser(part, validationErrorFlag); + if (n === null) + return input; + numbers.push(n); + } + /** + * 7. If validationErrorFlag is set, validation error. + * 8. If any item in numbers is greater than 255, validation error. + * 9. If any but the last item in numbers is greater than 255, return + * failure. + * 10. If the last item in numbers is greater than or equal to + * 256**(5 − the number of items in numbers), validation error, return failure. + */ + if (validationErrorFlag.value) + validationError("Invalid IP v4 address."); + for (let i = 0; i < numbers.length; i++) { + const item = numbers[i]; + if (item > 255) { + validationError("Invalid IP v4 address."); + if (i < numbers.length - 1) + return null; + } + } + if (numbers[numbers.length - 1] >= Math.pow(256, 5 - numbers.length)) { + validationError("Invalid IP v4 address."); + return null; + } + /** + * 11. Let ipv4 be the last item in numbers. + * 12. Remove the last item from numbers. + */ + let ipv4 = numbers[numbers.length - 1]; + numbers.pop(); + /** + * 13. Let counter be zero. + * 14. For each n in numbers: + * 14.2. Increment ipv4 by n × 256**(3 − counter). + * 14.2. Increment counter by 1. + */ + let counter = 0; + for (const n of numbers) { + ipv4 += n * Math.pow(256, 3 - counter); + counter++; + } + /** + * 15. Return ipv4. + */ + return ipv4; +} +exports.iPv4Parser = iPv4Parser; +/** + * Parses a string containing an IP v6 address. + * + * @param input - input string + */ +function iPv6Parser(input) { + /** + * 1. Let address be a new IPv6 address whose IPv6 pieces are all 0. + * 2. Let pieceIndex be 0. + * 3. Let compress be null. + * 4. Let pointer be a pointer into input, initially 0 (pointing to the + * first code point). + */ + const EOF = ""; + const address = [0, 0, 0, 0, 0, 0, 0, 0]; + let pieceIndex = 0; + let compress = null; + const walker = new util_1.StringWalker(input); + /** + * 5. If c is U+003A (:), then: + * 5.1. If remaining does not start with U+003A (:), validation error, + * return failure. + * 5.2. Increase pointer by 2. + * 5.3. Increase pieceIndex by 1 and then set compress to pieceIndex. + */ + if (walker.c() === ':') { + if (!walker.remaining().startsWith(':')) { + validationError("Invalid IP v6 address."); + return null; + } + walker.pointer += 2; + pieceIndex += 1; + compress = pieceIndex; + } + /** + * 6. While c is not the EOF code point: + */ + while (walker.c() !== EOF) { + /** + * 6.1. If pieceIndex is 8, validation error, return failure. + */ + if (pieceIndex === 8) { + validationError("Invalid IP v6 address."); + return null; + } + /** + * 6.2. If c is U+003A (:), then: + * 6.2.1. If compress is non-null, validation error, return failure. + * 6.2.2. Increase pointer and pieceIndex by 1, set compress to pieceIndex, + * and then continue. + */ + if (walker.c() === ':') { + if (compress !== null) { + validationError("Invalid IP v6 address."); + return null; + } + walker.pointer++; + pieceIndex++; + compress = pieceIndex; + continue; + } + /** + * 6.3. Let value and length be 0. + * 6.4. While length is less than 4 and c is an ASCII hex digit, set value + * to value × 0x10 + c interpreted as hexadecimal number, and increase + * pointer and length by 1. + */ + let value = 0; + let length = 0; + while (length < 4 && infra_1.codePoint.ASCIIHexDigit.test(walker.c())) { + value = value * 0x10 + parseInt(walker.c(), 16); + walker.pointer++; + length++; + } + /** + * 6.5. If c is U+002E (.), then: + */ + if (walker.c() === '.') { + /** + * 6.5.1. If length is 0, validation error, return failure. + * 6.5.2. Decrease pointer by length. + * 6.5.3. If pieceIndex is greater than 6, validation error, return + * failure. + * 6.5.4. Let numbersSeen be 0. + */ + if (length === 0) { + validationError("Invalid IP v6 address."); + return null; + } + walker.pointer -= length; + if (pieceIndex > 6) { + validationError("Invalid IP v6 address."); + return null; + } + let numbersSeen = 0; + /** + * 6.5.5. While c is not the EOF code point: + */ + while (walker.c() !== EOF) { + /** + * 6.5.5.1. Let ipv4Piece be null. + */ + let ipv4Piece = null; + /** + * 6.5.5.2. If numbersSeen is greater than 0, then: + * 6.5.5.2.1. If c is a U+002E (.) and numbersSeen is less than 4, then + * increase pointer by 1. + * 6.5.5.2.1. Otherwise, validation error, return failure. + */ + if (numbersSeen > 0) { + if (walker.c() === '.' && numbersSeen < 4) { + walker.pointer++; + } + else { + validationError("Invalid IP v6 address."); + return null; + } + } + /** + * 6.5.5.3. If c is not an ASCII digit, validation error, return + * failure. + */ + if (!infra_1.codePoint.ASCIIDigit.test(walker.c())) { + validationError("Invalid IP v6 address."); + return null; + } + /** + * 6.5.5.4. While c is an ASCII digit: + */ + while (infra_1.codePoint.ASCIIDigit.test(walker.c())) { + /** + * 6.5.5.4.1. Let number be c interpreted as decimal number. + */ + const number = parseInt(walker.c(), 10); + /** + * 6.5.5.4.2. If ipv4Piece is null, then set ipv4Piece to number. + * Otherwise, if ipv4Piece is 0, validation error, return failure. + * Otherwise, set ipv4Piece to ipv4Piece × 10 + number. + */ + if (ipv4Piece === null) { + ipv4Piece = number; + } + else if (ipv4Piece === 0) { + validationError("Invalid IP v6 address."); + return null; + } + else { + ipv4Piece = ipv4Piece * 10 + number; + } + /** + * 6.5.5.4.3. If ipv4Piece is greater than 255, validation error, return failure. + * 6.5.5.4.4. Increase pointer by 1. + */ + if (ipv4Piece > 255) { + validationError("Invalid IP v6 address."); + return null; + } + walker.pointer++; + } + /** + * 6.5.5.5. Set address[pieceIndex] to address[pieceIndex] × 0x100 + ipv4Piece. + * 6.5.5.6. Increase numbersSeen by 1. + * 6.5.5.7. If numbersSeen is 2 or 4, then increase pieceIndex by 1. + */ + if (ipv4Piece === null) { + validationError("Invalid IP v6 address."); + return null; + } + address[pieceIndex] = address[pieceIndex] * 0x100 + ipv4Piece; + numbersSeen++; + if (numbersSeen === 2 || numbersSeen === 4) + pieceIndex++; + } + /** + * 6.5.6. If numbersSeen is not 4, validation error, return failure. + */ + if (numbersSeen !== 4) { + validationError("Invalid IP v6 address."); + return null; + } + /** + * 6.5.7. Break. + */ + break; + } + else if (walker.c() === ':') { + /** + * 6.6. Otherwise, if c is U+003A (:): + * 6.6.1. Increase pointer by 1. + * 6.6.2. If c is the EOF code point, validation error, return failure. + */ + walker.pointer++; + if (walker.c() === EOF) { + validationError("Invalid IP v6 address."); + return null; + } + } + else if (walker.c() !== EOF) { + /** + * 6.7. Otherwise, if c is not the EOF code point, validation error, + * return failure. + */ + validationError("Invalid IP v6 address."); + return null; + } + /** + * 6.8. Set address[pieceIndex] to value. + * 6.9. Increase pieceIndex by 1. + */ + address[pieceIndex] = value; + pieceIndex++; + } + /** + * 7. If compress is non-null, then: + * 7.1. Let swaps be pieceIndex − compress. + * 7.2. Set pieceIndex to 7. + * 7.3. While pieceIndex is not 0 and swaps is greater than 0, swap + * address[pieceIndex] with address[compress + swaps − 1], and then decrease + * both pieceIndex and swaps by 1. + */ + if (compress !== null) { + let swaps = pieceIndex - compress; + pieceIndex = 7; + while (pieceIndex !== 0 && swaps > 0) { + [address[pieceIndex], address[compress + swaps - 1]] = + [address[compress + swaps - 1], address[pieceIndex]]; + pieceIndex--; + swaps--; + } + } + else if (compress === null && pieceIndex !== 8) { + /** + * 8. Otherwise, if compress is null and pieceIndex is not 8, + * validation error, return failure. + */ + validationError("Invalid IP v6 address."); + return null; + } + /** + * 9. Return address. + */ + return address; +} +exports.iPv6Parser = iPv6Parser; +/** + * Parses an opaque host string. + * + * @param input - a string + */ +function opaqueHostParser(input) { + /** + * 1. If input contains a forbidden host code point excluding U+0025 (%), + * validation error, return failure. + * 2. Let output be the empty string. + * 3. For each code point in input, UTF-8 percent encode it using the C0 + * control percent-encode set, and append the result to output. + * 4. Return output. + */ + const forbiddenChars = /[\x00\t\f\r #/:?@\[\\\]]/; + if (forbiddenChars.test(input)) { + validationError("Invalid host string."); + return null; + } + let output = ""; + for (const codePoint of input) { + output += utf8PercentEncode(codePoint, _c0ControlPercentEncodeSet); + } + return output; +} +exports.opaqueHostParser = opaqueHostParser; +/** + * Resolves a Blob URL from the user agent's Blob URL store. + * function is not implemented. + * See: https://w3c.github.io/FileAPI/#blob-url-resolve + * + * @param url - an url + */ +function resolveABlobURL(url) { + return null; +} +exports.resolveABlobURL = resolveABlobURL; +/** + * Percent encodes a byte. + * + * @param value - a byte + */ +function percentEncode(value) { + /** + * To percent encode a byte into a percent-encoded byte, return a string + * consisting of U+0025 (%), followed by two ASCII upper hex digits + * representing byte. + */ + return '%' + ('00' + value.toString(16).toUpperCase()).slice(-2); +} +exports.percentEncode = percentEncode; +/** + * Percent decodes a byte sequence input. + * + * @param input - a byte sequence + */ +function percentDecode(input) { + const isHexDigit = (byte) => { + return (byte >= 0x30 && byte <= 0x39) || (byte >= 0x41 && byte <= 0x46) || + (byte >= 0x61 && byte <= 0x66); + }; + /** + * 1. Let output be an empty byte sequence. + * 2. For each byte byte in input: + */ + const output = new Uint8Array(input.length); + let n = 0; + for (let i = 0; i < input.length; i++) { + const byte = input[i]; + /** + * 2.1. If byte is not 0x25 (%), then append byte to output. + * 2.2. Otherwise, if byte is 0x25 (%) and the next two bytes after byte + * in input are not in the ranges 0x30 (0) to 0x39 (9), 0x41 (A) + * to 0x46 (F), and 0x61 (a) to 0x66 (f), all inclusive, append byte + * to output. + * 2.3. Otherwise: + * 2.3.1. Let bytePoint be the two bytes after byte in input, decoded, + * and then interpreted as hexadecimal number. + * 2.3.2. Append a byte whose value is bytePoint to output. + * 2.3.3. Skip the next two bytes in input. + */ + if (byte !== 0x25) { + output[n] = byte; + n++; + } + else if (byte === 0x25 && i >= input.length - 2) { + output[n] = byte; + n++; + } + else if (byte === 0x25 && (!isHexDigit(input[i + 1]) || !isHexDigit(input[i + 2]))) { + output[n] = byte; + n++; + } + else { + const bytePoint = parseInt(util_1.utf8Decode(Uint8Array.of(input[i + 1], input[i + 2])), 16); + output[n] = bytePoint; + n++; + i += 2; + } + } + return output.subarray(0, n); +} +exports.percentDecode = percentDecode; +/** + * String percent decodes a string. + * + * @param input - a string + */ +function stringPercentDecode(input) { + /** + * 1. Let bytes be the UTF-8 encoding of input. + * 2. Return the percent decoding of bytes. + */ + return percentDecode(util_1.utf8Encode(input)); +} +exports.stringPercentDecode = stringPercentDecode; +/** + * UTF-8 percent encodes a code point, using a percent encode set. + * + * @param codePoint - a code point + * @param percentEncodeSet - a percent encode set + */ +function utf8PercentEncode(codePoint, percentEncodeSet) { + /** + * 1. If codePoint is not in percentEncodeSet, then return codePoint. + * 2. Let bytes be the result of running UTF-8 encode on codePoint. + * 3. Percent encode each byte in bytes, and then return the results + * concatenated, in the same order. + */ + if (!percentEncodeSet.test(codePoint)) + return codePoint; + const bytes = util_1.utf8Encode(codePoint); + let result = ""; + for (const byte of bytes) { + result += percentEncode(byte); + } + return result; +} +exports.utf8PercentEncode = utf8PercentEncode; +/** + * Determines if two hosts are considered equal. + * + * @param hostA - a host + * @param hostB - a host + */ +function hostEquals(hostA, hostB) { + return hostA === hostB; +} +exports.hostEquals = hostEquals; +/** + * Determines if two URLs are considered equal. + * + * @param urlA - a URL + * @param urlB - a URL + * @param excludeFragmentsFlag - whether to ignore fragments while comparing + */ +function urlEquals(urlA, urlB, excludeFragmentsFlag = false) { + /** + * 1. Let serializedA be the result of serializing A, with the exclude + * fragment flag set if the exclude fragments flag is set. + * 2. Let serializedB be the result of serializing B, with the exclude + * fragment flag set if the exclude fragments flag is set. + * 3. Return true if serializedA is serializedB, and false otherwise. + */ + return urlSerializer(urlA, excludeFragmentsFlag) === + urlSerializer(urlB, excludeFragmentsFlag); +} +exports.urlEquals = urlEquals; +/** + * Parses an `application/x-www-form-urlencoded` string. + * + * @param input - a string + */ +function urlEncodedStringParser(input) { + /** + * The application/x-www-form-urlencoded string parser takes a string input, + * UTF-8 encodes it, and then returns the result of + * application/x-www-form-urlencoded parsing it. + */ + return urlEncodedParser(util_1.utf8Encode(input)); +} +exports.urlEncodedStringParser = urlEncodedStringParser; +/** + * Parses `application/x-www-form-urlencoded` bytes. + * + * @param input - a byte sequence + */ +function urlEncodedParser(input) { + /** + * 1. Let sequences be the result of splitting input on 0x26 (&). + */ + const sequences = []; + let currentSequence = []; + for (const byte of input) { + if (byte === 0x26) { + sequences.push(Uint8Array.from(currentSequence)); + currentSequence = []; + } + else { + currentSequence.push(byte); + } + } + if (currentSequence.length !== 0) { + sequences.push(Uint8Array.from(currentSequence)); + } + /** + * 2. Let output be an initially empty list of name-value tuples where both name and value hold a string. + */ + const output = []; + /** + * 3. For each byte sequence bytes in sequences: + */ + for (const bytes of sequences) { + /** + * 3.1. If bytes is the empty byte sequence, then continue. + */ + if (bytes.length === 0) + continue; + /** + * 3.2. If bytes contains a 0x3D (=), then let name be the bytes from the + * start of bytes up to but excluding its first 0x3D (=), and let value be + * the bytes, if any, after the first 0x3D (=) up to the end of bytes. + * If 0x3D (=) is the first byte, then name will be the empty byte + * sequence. If it is the last, then value will be the empty byte sequence. + * 3.3. Otherwise, let name have the value of bytes and let value be the + * empty byte sequence. + */ + const index = bytes.indexOf(0x3D); + const name = (index !== -1 ? bytes.slice(0, index) : bytes); + const value = (index !== -1 ? bytes.slice(index + 1) : new Uint8Array()); + /** + * 3.4. Replace any 0x2B (+) in name and value with 0x20 (SP). + */ + for (let i = 0; i < name.length; i++) + if (name[i] === 0x2B) + name[i] = 0x20; + for (let i = 0; i < value.length; i++) + if (value[i] === 0x2B) + value[i] = 0x20; + /** + * 3.5. Let nameString and valueString be the result of running UTF-8 + * decode without BOM on the percent decoding of name and value, + * respectively. + */ + const nameString = util_1.utf8Decode(name); + const valueString = util_1.utf8Decode(value); + /** + * 3.6. Append (nameString, valueString) to output. + */ + output.push([nameString, valueString]); + } + /** + * 4. Return output. + */ + return output; +} +exports.urlEncodedParser = urlEncodedParser; +/** + * Serializes `application/x-www-form-urlencoded` bytes. + * + * @param input - a byte sequence + */ +function urlEncodedByteSerializer(input) { + /** + * 1. Let output be the empty string. + * 2. For each byte in input, depending on byte: + * 0x20 (SP) + * Append U+002B (+) to output. + * + * 0x2A (*) + * 0x2D (-) + * 0x2E (.) + * 0x30 (0) to 0x39 (9) + * 0x41 (A) to 0x5A (Z) + * 0x5F (_) + * 0x61 (a) to 0x7A (z) + * Append a code point whose value is byte to output. + * + * Otherwise + * Append byte, percent encoded, to output. + * 3. Return output. + */ + let output = ""; + for (const byte of input) { + if (byte === 0x20) { + output += '+'; + } + else if (byte === 0x2A || byte === 0x2D || byte === 0x2E || + (byte >= 0x30 && byte <= 0x39) || (byte >= 0x41 && byte <= 0x5A) || + byte === 0x5F || (byte >= 0x61 && byte <= 0x7A)) { + output += String.fromCodePoint(byte); + } + else { + output += percentEncode(byte); + } + } + return output; +} +exports.urlEncodedByteSerializer = urlEncodedByteSerializer; +/** + * Serializes `application/x-www-form-urlencoded` tuples. + * + * @param input - input tuple of name/value pairs + * @param encodingOverride: encoding override + */ +function urlEncodedSerializer(tuples, encodingOverride) { + /** + * 1. Let encoding be UTF-8. + * 2. If encoding override is given, set encoding to the result of getting + * an output encoding from encoding override. + */ + const encoding = (encodingOverride === undefined || + encodingOverride === "replacement" || encodingOverride === "UTF-16BE" || + encodingOverride === "UTF-16LE" ? "UTF-8" : encodingOverride); + if (encoding.toUpperCase() !== "UTF-8") { + throw new Error("Only UTF-8 encoding is supported."); + } + /** + * 3. Let output be the empty string. + */ + let output = ""; + /** + * 4. For each tuple in tuples: + */ + for (const tuple of tuples) { + /** + * 4.1. Let name be the result of serializing the result of encoding + * tuple’s name, using encoding. + */ + const name = urlEncodedByteSerializer(util_1.utf8Encode(tuple[0])); + /** + * 4.2. Let value be tuple’s value. + */ + let value = tuple[1]; + /** + * TODO: + * 4.3. If value is a file, then set value to value’s filename. + */ + /** + * 4.4. Set value to the result of serializing the result of encoding + * value, using encoding. + */ + value = urlEncodedByteSerializer(util_1.utf8Encode(value)); + /** + * 4.5. If tuple is not the first pair in tuples, then append U+0026 (&) + * to output. + */ + if (output !== "") + output += '&'; + /** + * 4.6. Append name, followed by U+003D (=), followed by value, to output. + */ + output += name + '=' + value; + } + /** + * 5. Return output. + */ + return output; +} +exports.urlEncodedSerializer = urlEncodedSerializer; +/** + * Returns a URL's origin. + * + * @param url - a URL + */ +function origin(url) { + /** + * A URL’s origin is the origin returned by running these steps, switching + * on URL’s scheme: + * "blob" + * 1. If URL’s blob URL entry is non-null, then return URL’s blob URL + * entry’s environment’s origin. + * 2. Let url be the result of parsing URL’s path[0]. + * 3. Return a new opaque origin, if url is failure, and url’s origin + * otherwise. + * "ftp" + * "http" + * "https" + * "ws" + * "wss" + * Return a tuple consisting of URL’s scheme, URL’s host, URL’s port, and + * null. + * "file" + * Unfortunate as it is, is left as an exercise to the reader. When in + * doubt, return a new opaque origin. + * Otherwise + * Return a new opaque origin. + */ + switch (url.scheme) { + case "blob": + if (url._blobURLEntry !== null) { + // TODO: return URL’s blob URL entry’s environment’s origin. + } + const parsedURL = basicURLParser(url.path[0]); + if (parsedURL === null) + return interfaces_1.OpaqueOrigin; + else + return origin(parsedURL); + case "ftp": + case "http": + case "https": + case "ws": + case "wss": + return [url.scheme, url.host === null ? "" : url.host, url.port, null]; + case "file": + return interfaces_1.OpaqueOrigin; + default: + return interfaces_1.OpaqueOrigin; + } +} +exports.origin = origin; +/** + * Converts a domain string to ASCII. + * + * @param domain - a domain string + */ +function domainToASCII(domain, beStrict = false) { + /** + * 1. If beStrict is not given, set it to false. + * 2. Let result be the result of running Unicode ToASCII with domain_name + * set to domain, UseSTD3ASCIIRules set to beStrict, CheckHyphens set to + * false, CheckBidi set to true, CheckJoiners set to true, + * Transitional_Processing set to false, and VerifyDnsLength set to beStrict. + * 3. If result is a failure value, validation error, return failure. + * 4. Return result. + */ + // Use node.js function + const result = url_1.domainToASCII(domain); + if (result === "") { + validationError("Invalid domain name."); + return null; + } + return result; +} +exports.domainToASCII = domainToASCII; +/** + * Converts a domain string to Unicode. + * + * @param domain - a domain string + */ +function domainToUnicode(domain, beStrict = false) { + /** + * 1. Let result be the result of running Unicode ToUnicode with domain_name + * set to domain, CheckHyphens set to false, CheckBidi set to true, + * CheckJoiners set to true, UseSTD3ASCIIRules set to false, and + * Transitional_Processing set to false. + * 2. Signify validation errors for any returned errors, and then, + * return result. + */ + // Use node.js function + const result = url_1.domainToUnicode(domain); + if (result === "") { + validationError("Invalid domain name."); + } + return result; +} +exports.domainToUnicode = domainToUnicode; +/** + * Serializes an origin. + * function is from the HTML spec: + * https://html.spec.whatwg.org/#ascii-serialisation-of-an-origin + * + * @param origin - an origin + */ +function asciiSerializationOfAnOrigin(origin) { + /** + * 1. If origin is an opaque origin, then return "null". + * 2. Otherwise, let result be origin's scheme. + * 3. Append "://" to result. + * 4. Append origin's host, serialized, to result. + * 5. If origin's port is non-null, append a U+003A COLON character (:), + * and origin's port, serialized, to result. + * 6. Return result. + */ + if (origin[0] === "" && origin[1] === "" && origin[2] === null && origin[3] === null) { + return "null"; + } + let result = origin[0] + "://" + hostSerializer(origin[1]); + if (origin[2] !== null) + result += ":" + origin[2].toString(); + return result; +} +exports.asciiSerializationOfAnOrigin = asciiSerializationOfAnOrigin; +//# sourceMappingURL=URLAlgorithm.js.map + +/***/ }), + +/***/ 820: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const interfaces_1 = __webpack_require__(970); +const CharacterDataImpl_1 = __webpack_require__(43); +const algorithm_1 = __webpack_require__(163); +const WebIDLAlgorithm_1 = __webpack_require__(495); +/** + * Represents a text node. + */ +class TextImpl extends CharacterDataImpl_1.CharacterDataImpl { + /** + * Initializes a new instance of `Text`. + * + * @param data - the text content + */ + constructor(data = '') { + super(data); + this._name = ''; + this._assignedSlot = null; + } + /** @inheritdoc */ + get wholeText() { + /** + * The wholeText attribute’s getter must return the concatenation of the + * data of the contiguous Text nodes of the context object, in tree order. + */ + let text = ''; + for (const node of algorithm_1.text_contiguousTextNodes(this, true)) { + text = text + node._data; + } + return text; + } + /** @inheritdoc */ + splitText(offset) { + /** + * The splitText(offset) method, when invoked, must split context object + * with offset offset. + */ + return algorithm_1.text_split(this, offset); + } + // MIXIN: Slotable + /* istanbul ignore next */ + get assignedSlot() { throw new Error("Mixin: Slotable not implemented."); } + /** + * Creates a `Text`. + * + * @param document - owner document + * @param data - the text content + */ + static _create(document, data = '') { + const node = new TextImpl(data); + node._nodeDocument = document; + return node; + } +} +exports.TextImpl = TextImpl; +/** + * Initialize prototype properties + */ +WebIDLAlgorithm_1.idl_defineConst(TextImpl.prototype, "_nodeType", interfaces_1.NodeType.Text); +//# sourceMappingURL=TextImpl.js.map + +/***/ }), + +/***/ 826: +/***/ (function(module, __unusedexports, __webpack_require__) { + +var rng = __webpack_require__(139); +var bytesToUuid = __webpack_require__(722); + +function v4(options, buf, offset) { + var i = buf && offset || 0; + + if (typeof(options) == 'string') { + buf = options === 'binary' ? new Array(16) : null; + options = null; + } + options = options || {}; + + var rnds = options.random || (options.rng || rng)(); + + // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` + rnds[6] = (rnds[6] & 0x0f) | 0x40; + rnds[8] = (rnds[8] & 0x3f) | 0x80; + + // Copy bytes to buffer, if provided + if (buf) { + for (var ii = 0; ii < 16; ++ii) { + buf[i + ii] = rnds[ii]; + } + } + + return buf || bytesToUuid(rnds); +} + +module.exports = v4; + + +/***/ }), + +/***/ 835: +/***/ (function(module) { + +module.exports = require("url"); + +/***/ }), + +/***/ 844: +/***/ (function(__unusedmodule, exports) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * Represents a set of objects with a size limit. + */ +class FixedSizeSet { + /** + * Initializes a new instance of `FixedSizeSet`. + * + * @param limit - maximum number of items to keep in the set. When the limit + * is exceeded the first item is removed from the set. + */ + constructor(limit = 1000) { + this._items = new Set(); + this._limit = limit; + } + /** + * Adds a new item to the set. + * + * @param item - an item + */ + add(item) { + this._items.add(item); + if (this._items.size > this._limit) { + const it = this._items.values().next(); + /* istanbul ignore else */ + if (!it.done) { + this._items.delete(it.value); + } + } + return this; + } + /** + * Removes an item from the set. + * + * @param item - an item + */ + delete(item) { + return this._items.delete(item); + } + /** + * Determines if an item is in the set. + * + * @param item - an item + */ + has(item) { + return this._items.has(item); + } + /** + * Removes all items from the set. + */ + clear() { + this._items.clear(); + } + /** + * Gets the number of items in the set. + */ + get size() { return this._items.size; } + /** + * Applies the given callback function to all elements of the set. + */ + forEach(callback, thisArg) { + this._items.forEach(e => callback.call(thisArg, e, e, this)); + } + /** + * Iterates through the items in the set. + */ + *keys() { + yield* this._items.keys(); + } + /** + * Iterates through the items in the set. + */ + *values() { + yield* this._items.values(); + } + /** + * Iterates through the items in the set. + */ + *entries() { + yield* this._items.entries(); + } + /** + * Iterates through the items in the set. + */ + *[Symbol.iterator]() { + yield* this._items; + } + /** + * Returns the string tag of the set. + */ + get [Symbol.toStringTag]() { + return "FixedSizeSet"; + } +} +exports.FixedSizeSet = FixedSizeSet; +//# sourceMappingURL=FixedSizeSet.js.map + +/***/ }), + +/***/ 859: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const util_1 = __webpack_require__(42); +const util_2 = __webpack_require__(457); +/** + * Parses the given byte sequence representing a JSON string into an object. + * + * @param bytes - a byte sequence + */ +function parseJSONFromBytes(bytes) { + /** + * 1. Let jsonText be the result of running UTF-8 decode on bytes. [ENCODING] + * 2. Return ? Call(%JSONParse%, undefined, « jsonText »). + */ + const jsonText = util_2.utf8Decode(bytes); + return JSON.parse.call(undefined, jsonText); +} +exports.parseJSONFromBytes = parseJSONFromBytes; +/** + * Serialize the given JavaScript value into a byte sequence. + * + * @param value - a JavaScript value + */ +function serializeJSONToBytes(value) { + /** + * 1. Let jsonString be ? Call(%JSONStringify%, undefined, « value »). + * 2. Return the result of running UTF-8 encode on jsonString. [ENCODING] + */ + const jsonString = JSON.stringify.call(undefined, value); + return util_2.utf8Encode(jsonString); +} +exports.serializeJSONToBytes = serializeJSONToBytes; +/** + * Parses the given JSON string into a Realm-independent JavaScript value. + * + * @param jsonText - a JSON string + */ +function parseJSONIntoInfraValues(jsonText) { + /** + * 1. Let jsValue be ? Call(%JSONParse%, undefined, « jsonText »). + * 2. Return the result of converting a JSON-derived JavaScript value to an + * Infra value, given jsValue. + */ + const jsValue = JSON.parse.call(undefined, jsonText); + return convertAJSONDerivedJavaScriptValueToAnInfraValue(jsValue); +} +exports.parseJSONIntoInfraValues = parseJSONIntoInfraValues; +/** + * Parses the value into a Realm-independent JavaScript value. + * + * @param jsValue - a JavaScript value + */ +function convertAJSONDerivedJavaScriptValueToAnInfraValue(jsValue) { + /** + * 1. If Type(jsValue) is Null, String, or Number, then return jsValue. + */ + if (jsValue === null || util_1.isString(jsValue) || util_1.isNumber(jsValue)) + return jsValue; + /** + * 2. If IsArray(jsValue) is true, then: + * 2.1. Let result be an empty list. + * 2.2. Let length be ! ToLength(! Get(jsValue, "length")). + * 2.3. For each index of the range 0 to length − 1, inclusive: + * 2.3.1. Let indexName be ! ToString(index). + * 2.3.2. Let jsValueAtIndex be ! Get(jsValue, indexName). + * 2.3.3. Let infraValueAtIndex be the result of converting a JSON-derived + * JavaScript value to an Infra value, given jsValueAtIndex. + * 2.3.4. Append infraValueAtIndex to result. + * 2.8. Return result. + */ + if (util_1.isArray(jsValue)) { + const result = new Array(); + for (const jsValueAtIndex of jsValue) { + result.push(convertAJSONDerivedJavaScriptValueToAnInfraValue(jsValueAtIndex)); + } + return result; + } + else if (util_1.isObject(jsValue)) { + /** + * 3. Let result be an empty ordered map. + * 4. For each key of ! jsValue.[[OwnPropertyKeys]](): + * 4.1. Let jsValueAtKey be ! Get(jsValue, key). + * 4.2. Let infraValueAtKey be the result of converting a JSON-derived + * JavaScript value to an Infra value, given jsValueAtKey. + * 4.3. Set result[key] to infraValueAtKey. + * 5. Return result. + */ + const result = new Map(); + for (const key in jsValue) { + /* istanbul ignore else */ + if (jsValue.hasOwnProperty(key)) { + const jsValueAtKey = jsValue[key]; + result.set(key, convertAJSONDerivedJavaScriptValueToAnInfraValue(jsValueAtKey)); + } + } + return result; + } + /* istanbul ignore next */ + return jsValue; +} +exports.convertAJSONDerivedJavaScriptValueToAnInfraValue = convertAJSONDerivedJavaScriptValueToAnInfraValue; +//# sourceMappingURL=JSON.js.map + +/***/ }), + +/***/ 866: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const interfaces_1 = __webpack_require__(970); +const NodeImpl_1 = __webpack_require__(935); +const algorithm_1 = __webpack_require__(163); +const WebIDLAlgorithm_1 = __webpack_require__(495); +/** + * Represents an attribute of an element node. + */ +class AttrImpl extends NodeImpl_1.NodeImpl { + /** + * Initializes a new instance of `Attr`. + * + * @param localName - local name + */ + constructor(localName) { + super(); + this._namespace = null; + this._namespacePrefix = null; + this._element = null; + this._value = ''; + this._localName = localName; + } + /** @inheritdoc */ + get ownerElement() { return this._element; } + /** @inheritdoc */ + get namespaceURI() { return this._namespace; } + /** @inheritdoc */ + get prefix() { return this._namespacePrefix; } + /** @inheritdoc */ + get localName() { return this._localName; } + /** @inheritdoc */ + get name() { return this._qualifiedName; } + /** @inheritdoc */ + get value() { return this._value; } + set value(value) { + /** + * The value attribute’s setter must set an existing attribute value with + * context object and the given value. + */ + algorithm_1.attr_setAnExistingAttributeValue(this, value); + } + /** + * Returns the qualified name. + */ + get _qualifiedName() { + /** + * An attribute’s qualified name is its local name if its namespace prefix + * is null, and its namespace prefix, followed by ":", followed by its + * local name, otherwise. + */ + return (this._namespacePrefix !== null ? + this._namespacePrefix + ':' + this._localName : + this._localName); + } + /** + * Creates an `Attr`. + * + * @param document - owner document + * @param localName - local name + */ + static _create(document, localName) { + const node = new AttrImpl(localName); + node._nodeDocument = document; + return node; + } +} +exports.AttrImpl = AttrImpl; +/** + * Initialize prototype properties + */ +WebIDLAlgorithm_1.idl_defineConst(AttrImpl.prototype, "_nodeType", interfaces_1.NodeType.Attribute); +WebIDLAlgorithm_1.idl_defineConst(AttrImpl.prototype, "specified", true); +//# sourceMappingURL=AttrImpl.js.map + +/***/ }), + +/***/ 873: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const util_1 = __webpack_require__(918); +const interfaces_1 = __webpack_require__(970); +/** + * Gets the next descendant of the given node of the tree rooted at `root` + * in depth-first pre-order. + * + * @param root - root node of the tree + * @param node - a node + * @param shadow - whether to visit shadow tree nodes + */ +function _getNextDescendantNode(root, node, shadow = false) { + // traverse shadow tree + if (shadow && util_1.Guard.isElementNode(node) && util_1.Guard.isShadowRoot(node.shadowRoot)) { + if (node.shadowRoot._firstChild) + return node.shadowRoot._firstChild; + } + // traverse child nodes + if (node._firstChild) + return node._firstChild; + if (node === root) + return null; + // traverse siblings + if (node._nextSibling) + return node._nextSibling; + // traverse parent's next sibling + let parent = node._parent; + while (parent && parent !== root) { + if (parent._nextSibling) + return parent._nextSibling; + parent = parent._parent; + } + return null; +} +function _emptyIterator() { + return { + [Symbol.iterator]: () => { + return { + next: () => { + return { done: true, value: null }; + } + }; + } + }; +} +/** + * Returns the first descendant node of the tree rooted at `node` in + * depth-first pre-order. + * + * @param node - root node of the tree + * @param self - whether to include `node` in traversal + * @param shadow - whether to visit shadow tree nodes + * @param filter - a function to filter nodes + */ +function tree_getFirstDescendantNode(node, self = false, shadow = false, filter) { + let firstNode = (self ? node : _getNextDescendantNode(node, node, shadow)); + while (firstNode && filter && !filter(firstNode)) { + firstNode = _getNextDescendantNode(node, firstNode, shadow); + } + return firstNode; +} +exports.tree_getFirstDescendantNode = tree_getFirstDescendantNode; +/** + * Returns the next descendant node of the tree rooted at `node` in + * depth-first pre-order. + * + * @param node - root node of the tree + * @param currentNode - current descendant node + * @param self - whether to include `node` in traversal + * @param shadow - whether to visit shadow tree nodes + * @param filter - a function to filter nodes + */ +function tree_getNextDescendantNode(node, currentNode, self = false, shadow = false, filter) { + let nextNode = _getNextDescendantNode(node, currentNode, shadow); + while (nextNode && filter && !filter(nextNode)) { + nextNode = _getNextDescendantNode(node, nextNode, shadow); + } + return nextNode; +} +exports.tree_getNextDescendantNode = tree_getNextDescendantNode; +/** + * Traverses through all descendant nodes of the tree rooted at + * `node` in depth-first pre-order. + * + * @param node - root node of the tree + * @param self - whether to include `node` in traversal + * @param shadow - whether to visit shadow tree nodes + * @param filter - a function to filter nodes + */ +function tree_getDescendantNodes(node, self = false, shadow = false, filter) { + if (!self && node._children.size === 0) { + return _emptyIterator(); + } + return { + [Symbol.iterator]: () => { + let currentNode = (self ? node : _getNextDescendantNode(node, node, shadow)); + return { + next: () => { + while (currentNode && filter && !filter(currentNode)) { + currentNode = _getNextDescendantNode(node, currentNode, shadow); + } + if (currentNode === null) { + return { done: true, value: null }; + } + else { + const result = { done: false, value: currentNode }; + currentNode = _getNextDescendantNode(node, currentNode, shadow); + return result; + } + } + }; + } + }; +} +exports.tree_getDescendantNodes = tree_getDescendantNodes; +/** + * Traverses through all descendant element nodes of the tree rooted at + * `node` in depth-first preorder. + * + * @param node - root node of the tree + * @param self - whether to include `node` in traversal + * @param shadow - whether to visit shadow tree nodes + * @param filter - a function to filter nodes + */ +function tree_getDescendantElements(node, self = false, shadow = false, filter) { + if (!self && node._children.size === 0) { + return _emptyIterator(); + } + return { + [Symbol.iterator]: () => { + const it = tree_getDescendantNodes(node, self, shadow, (e) => util_1.Guard.isElementNode(e))[Symbol.iterator](); + let currentNode = it.next().value; + return { + next() { + while (currentNode && filter && !filter(currentNode)) { + currentNode = it.next().value; + } + if (currentNode === null) { + return { done: true, value: null }; + } + else { + const result = { done: false, value: currentNode }; + currentNode = it.next().value; + return result; + } + } + }; + } + }; +} +exports.tree_getDescendantElements = tree_getDescendantElements; +/** + * Traverses through all sibling nodes of `node`. + * + * @param node - root node of the tree + * @param self - whether to include `node` in traversal + * @param filter - a function to filter nodes + */ +function tree_getSiblingNodes(node, self = false, filter) { + if (!node._parent || node._parent._children.size === 0) { + return _emptyIterator(); + } + return { + [Symbol.iterator]() { + let currentNode = node._parent ? node._parent._firstChild : null; + return { + next() { + while (currentNode && (filter && !filter(currentNode) || (!self && currentNode === node))) { + currentNode = currentNode._nextSibling; + } + if (currentNode === null) { + return { done: true, value: null }; + } + else { + const result = { done: false, value: currentNode }; + currentNode = currentNode._nextSibling; + return result; + } + } + }; + } + }; +} +exports.tree_getSiblingNodes = tree_getSiblingNodes; +/** + * Gets the first ancestor of `node` in reverse tree order. + * + * @param node - root node of the tree + * @param self - whether to include `node` in traversal + * @param filter - a function to filter nodes + */ +function tree_getFirstAncestorNode(node, self = false, filter) { + let firstNode = self ? node : node._parent; + while (firstNode && filter && !filter(firstNode)) { + firstNode = firstNode._parent; + } + return firstNode; +} +exports.tree_getFirstAncestorNode = tree_getFirstAncestorNode; +/** + * Gets the first ancestor of `node` in reverse tree order. + * + * @param node - root node of the tree + * @param self - whether to include `node` in traversal + * @param filter - a function to filter nodes + */ +function tree_getNextAncestorNode(node, currentNode, self = false, filter) { + let nextNode = currentNode._parent; + while (nextNode && filter && !filter(nextNode)) { + nextNode = nextNode._parent; + } + return nextNode; +} +exports.tree_getNextAncestorNode = tree_getNextAncestorNode; +/** + * Traverses through all ancestor nodes `node` in reverse tree order. + * + * @param node - root node of the tree + * @param self - whether to include `node` in traversal + * @param filter - a function to filter nodes + */ +function tree_getAncestorNodes(node, self = false, filter) { + if (!self && !node._parent) { + return _emptyIterator(); + } + return { + [Symbol.iterator]() { + let currentNode = tree_getFirstAncestorNode(node, self, filter); + return { + next() { + if (currentNode === null) { + return { done: true, value: null }; + } + else { + const result = { done: false, value: currentNode }; + currentNode = tree_getNextAncestorNode(node, currentNode, self, filter); + return result; + } + } + }; + } + }; +} +exports.tree_getAncestorNodes = tree_getAncestorNodes; +/** + * Returns the common ancestor of the given nodes. + * + * @param nodeA - a node + * @param nodeB - a node + */ +function tree_getCommonAncestor(nodeA, nodeB) { + if (nodeA === nodeB) { + return nodeA._parent; + } + // lists of parent nodes + const parentsA = []; + const parentsB = []; + let pA = tree_getFirstAncestorNode(nodeA, true); + while (pA !== null) { + parentsA.push(pA); + pA = tree_getNextAncestorNode(nodeA, pA, true); + } + let pB = tree_getFirstAncestorNode(nodeB, true); + while (pB !== null) { + parentsB.push(pB); + pB = tree_getNextAncestorNode(nodeB, pB, true); + } + // walk through parents backwards until they differ + let pos1 = parentsA.length; + let pos2 = parentsB.length; + let parent = null; + for (let i = Math.min(pos1, pos2); i > 0; i--) { + const parent1 = parentsA[--pos1]; + const parent2 = parentsB[--pos2]; + if (parent1 !== parent2) { + break; + } + parent = parent1; + } + return parent; +} +exports.tree_getCommonAncestor = tree_getCommonAncestor; +/** + * Returns the node following `node` in depth-first preorder. + * + * @param root - root of the subtree + * @param node - a node + */ +function tree_getFollowingNode(root, node) { + if (node._firstChild) { + return node._firstChild; + } + else if (node._nextSibling) { + return node._nextSibling; + } + else { + while (true) { + const parent = node._parent; + if (parent === null || parent === root) { + return null; + } + else if (parent._nextSibling) { + return parent._nextSibling; + } + else { + node = parent; + } + } + } +} +exports.tree_getFollowingNode = tree_getFollowingNode; +/** + * Returns the node preceding `node` in depth-first preorder. + * + * @param root - root of the subtree + * @param node - a node + */ +function tree_getPrecedingNode(root, node) { + if (node === root) { + return null; + } + if (node._previousSibling) { + node = node._previousSibling; + if (node._lastChild) { + return node._lastChild; + } + else { + return node; + } + } + else { + return node._parent; + } +} +exports.tree_getPrecedingNode = tree_getPrecedingNode; +/** + * Determines if the node tree is constrained. A node tree is + * constrained as follows, expressed as a relationship between the + * type of node and its allowed children: + * - Document (In tree order) + * * Zero or more nodes each of which is ProcessingInstruction + * or Comment. + * * Optionally one DocumentType node. + * * Zero or more nodes each of which is ProcessingInstruction + * or Comment. + * * Optionally one Element node. + * * Zero or more nodes each of which is ProcessingInstruction + * or Comment. + * - DocumentFragment, Element + * * Zero or more nodes each of which is Element, Text, + * ProcessingInstruction, or Comment. + * - DocumentType, Text, ProcessingInstruction, Comment + * * None. + * + * @param node - the root of the tree + */ +function tree_isConstrained(node) { + switch (node._nodeType) { + case interfaces_1.NodeType.Document: + let hasDocType = false; + let hasElement = false; + for (const childNode of node._children) { + switch (childNode._nodeType) { + case interfaces_1.NodeType.ProcessingInstruction: + case interfaces_1.NodeType.Comment: + break; + case interfaces_1.NodeType.DocumentType: + if (hasDocType || hasElement) + return false; + hasDocType = true; + break; + case interfaces_1.NodeType.Element: + if (hasElement) + return false; + hasElement = true; + break; + default: + return false; + } + } + break; + case interfaces_1.NodeType.DocumentFragment: + case interfaces_1.NodeType.Element: + for (const childNode of node._children) { + switch (childNode._nodeType) { + case interfaces_1.NodeType.Element: + case interfaces_1.NodeType.Text: + case interfaces_1.NodeType.ProcessingInstruction: + case interfaces_1.NodeType.CData: + case interfaces_1.NodeType.Comment: + break; + default: + return false; + } + } + break; + case interfaces_1.NodeType.DocumentType: + case interfaces_1.NodeType.Text: + case interfaces_1.NodeType.ProcessingInstruction: + case interfaces_1.NodeType.CData: + case interfaces_1.NodeType.Comment: + return (!node.hasChildNodes()); + } + for (const childNode of node._children) { + // recursively check child nodes + if (!tree_isConstrained(childNode)) + return false; + } + return true; +} +exports.tree_isConstrained = tree_isConstrained; +/** + * Returns the length of a node. + * + * @param node - a node to check + */ +function tree_nodeLength(node) { + /** + * To determine the length of a node node, switch on node: + * - DocumentType + * Zero. + * - Text + * - ProcessingInstruction + * - Comment + * Its data’s length. + * - Any other node + * Its number of children. + */ + if (util_1.Guard.isDocumentTypeNode(node)) { + return 0; + } + else if (util_1.Guard.isCharacterDataNode(node)) { + return node._data.length; + } + else { + return node._children.size; + } +} +exports.tree_nodeLength = tree_nodeLength; +/** + * Determines if a node is empty. + * + * @param node - a node to check + */ +function tree_isEmpty(node) { + /** + * A node is considered empty if its length is zero. + */ + return (tree_nodeLength(node) === 0); +} +exports.tree_isEmpty = tree_isEmpty; +/** + * Returns the root node of a tree. The root of an object is itself, + * if its parent is `null`, or else it is the root of its parent. + * The root of a tree is any object participating in that tree + * whose parent is `null`. + * + * @param node - a node of the tree + * @param shadow - `true` to return shadow-including root, otherwise + * `false` + */ +function tree_rootNode(node, shadow = false) { + /** + * The root of an object is itself, if its parent is null, or else it is the + * root of its parent. The root of a tree is any object participating in + * that tree whose parent is null. + */ + if (shadow) { + const root = tree_rootNode(node, false); + if (util_1.Guard.isShadowRoot(root)) + return tree_rootNode(root._host, true); + else + return root; + } + else { + if (!node._parent) + return node; + else + return tree_rootNode(node._parent); + } +} +exports.tree_rootNode = tree_rootNode; +/** + * Determines whether `other` is a descendant of `node`. An object + * A is called a descendant of an object B, if either A is a child + * of B or A is a child of an object C that is a descendant of B. + * + * @param node - a node + * @param other - the node to check + * @param self - if `true`, traversal includes `node` itself + * @param shadow - if `true`, traversal includes the + * node's and its descendant's shadow trees as well. + */ +function tree_isDescendantOf(node, other, self = false, shadow = false) { + /** + * An object A is called a descendant of an object B, if either A is a + * child of B or A is a child of an object C that is a descendant of B. + * + * An inclusive descendant is an object or one of its descendants. + */ + let child = tree_getFirstDescendantNode(node, self, shadow); + while (child !== null) { + if (child === other) { + return true; + } + child = tree_getNextDescendantNode(node, child, self, shadow); + } + return false; +} +exports.tree_isDescendantOf = tree_isDescendantOf; +/** + * Determines whether `other` is an ancestor of `node`. An object A + * is called an ancestor of an object B if and only if B is a + * descendant of A. + * + * @param node - a node + * @param other - the node to check + * @param self - if `true`, traversal includes `node` itself + * @param shadow - if `true`, traversal includes the + * node's and its descendant's shadow trees as well. + */ +function tree_isAncestorOf(node, other, self = false, shadow = false) { + let ancestor = self ? node : shadow && util_1.Guard.isShadowRoot(node) ? + node._host : node._parent; + while (ancestor !== null) { + if (ancestor === other) + return true; + ancestor = shadow && util_1.Guard.isShadowRoot(ancestor) ? + ancestor._host : ancestor._parent; + } + return false; +} +exports.tree_isAncestorOf = tree_isAncestorOf; +/** + * Determines whether `other` is a host-including ancestor of `node`. An + * object A is a host-including inclusive ancestor of an object B, if either + * A is an inclusive ancestor of B, or if B’s root has a non-null host and + * A is a host-including inclusive ancestor of B’s root’s host. + * + * @param node - a node + * @param other - the node to check + * @param self - if `true`, traversal includes `node` itself + */ +function tree_isHostIncludingAncestorOf(node, other, self = false) { + if (tree_isAncestorOf(node, other, self)) + return true; + const root = tree_rootNode(node); + if (util_1.Guard.isDocumentFragmentNode(root) && root._host !== null && + tree_isHostIncludingAncestorOf(root._host, other, self)) + return true; + return false; +} +exports.tree_isHostIncludingAncestorOf = tree_isHostIncludingAncestorOf; +/** + * Determines whether `other` is a sibling of `node`. An object A is + * called a sibling of an object B, if and only if B and A share + * the same non-null parent. + * + * @param node - a node + * @param other - the node to check + * @param self - if `true`, traversal includes `node` itself + */ +function tree_isSiblingOf(node, other, self = false) { + /** + * An object A is called a sibling of an object B, if and only if B and A + * share the same non-null parent. + * + * An inclusive sibling is an object or one of its siblings. + */ + if (node === other) { + if (self) + return true; + } + else { + return (node._parent !== null && node._parent === other._parent); + } + return false; +} +exports.tree_isSiblingOf = tree_isSiblingOf; +/** + * Determines whether `other` is preceding `node`. An object A is + * preceding an object B if A and B are in the same tree and A comes + * before B in tree order. + * + * @param node - a node + * @param other - the node to check + */ +function tree_isPreceding(node, other) { + /** + * An object A is preceding an object B if A and B are in the same tree and + * A comes before B in tree order. + */ + const nodePos = tree_treePosition(node); + const otherPos = tree_treePosition(other); + if (nodePos === -1 || otherPos === -1) + return false; + else if (tree_rootNode(node) !== tree_rootNode(other)) + return false; + else + return otherPos < nodePos; +} +exports.tree_isPreceding = tree_isPreceding; +/** + * Determines whether `other` is following `node`. An object A is + * following an object B if A and B are in the same tree and A comes + * after B in tree order. + * + * @param node - a node + * @param other - the node to check + */ +function tree_isFollowing(node, other) { + /** + * An object A is following an object B if A and B are in the same tree and + * A comes after B in tree order. + */ + const nodePos = tree_treePosition(node); + const otherPos = tree_treePosition(other); + if (nodePos === -1 || otherPos === -1) + return false; + else if (tree_rootNode(node) !== tree_rootNode(other)) + return false; + else + return otherPos > nodePos; +} +exports.tree_isFollowing = tree_isFollowing; +/** + * Determines whether `other` is the parent node of `node`. + * + * @param node - a node + * @param other - the node to check + */ +function tree_isParentOf(node, other) { + /** + * An object that participates in a tree has a parent, which is either + * null or an object, and has children, which is an ordered set of objects. + * An object A whose parent is object B is a child of B. + */ + return (node._parent === other); +} +exports.tree_isParentOf = tree_isParentOf; +/** + * Determines whether `other` is a child node of `node`. + * + * @param node - a node + * @param other - the node to check + */ +function tree_isChildOf(node, other) { + /** + * An object that participates in a tree has a parent, which is either + * null or an object, and has children, which is an ordered set of objects. + * An object A whose parent is object B is a child of B. + */ + return (other._parent === node); +} +exports.tree_isChildOf = tree_isChildOf; +/** + * Returns the previous sibling node of `node` or null if it has no + * preceding sibling. + * + * @param node + */ +function tree_previousSibling(node) { + /** + * The previous sibling of an object is its first preceding sibling or null + * if it has no preceding sibling. + */ + return node._previousSibling; +} +exports.tree_previousSibling = tree_previousSibling; +/** + * Returns the next sibling node of `node` or null if it has no + * following sibling. + * + * @param node + */ +function tree_nextSibling(node) { + /** + * The next sibling of an object is its first following sibling or null + * if it has no following sibling. + */ + return node._nextSibling; +} +exports.tree_nextSibling = tree_nextSibling; +/** + * Returns the first child node of `node` or null if it has no + * children. + * + * @param node + */ +function tree_firstChild(node) { + /** + * The first child of an object is its first child or null if it has no + * children. + */ + return node._firstChild; +} +exports.tree_firstChild = tree_firstChild; +/** + * Returns the last child node of `node` or null if it has no + * children. + * + * @param node + */ +function tree_lastChild(node) { + /** + * The last child of an object is its last child or null if it has no + * children. + */ + return node._lastChild; +} +exports.tree_lastChild = tree_lastChild; +/** + * Returns the zero-based index of `node` when counted preorder in + * the tree rooted at `root`. Returns `-1` if `node` is not in + * the tree. + * + * @param node - the node to get the index of + */ +function tree_treePosition(node) { + const root = tree_rootNode(node); + let pos = 0; + let childNode = tree_getFirstDescendantNode(root); + while (childNode !== null) { + pos++; + if (childNode === node) + return pos; + childNode = tree_getNextDescendantNode(root, childNode); + } + return -1; +} +exports.tree_treePosition = tree_treePosition; +/** + * Determines the index of `node`. The index of an object is its number of + * preceding siblings, or 0 if it has none. + * + * @param node - a node + * @param other - the node to check + */ +function tree_index(node) { + /** + * The index of an object is its number of preceding siblings, or 0 if it + * has none. + */ + let n = 0; + while (node._previousSibling !== null) { + n++; + node = node._previousSibling; + } + return n; +} +exports.tree_index = tree_index; +/** + * Retargets an object against another object. + * + * @param a - an object to retarget + * @param b - an object to retarget against + */ +function tree_retarget(a, b) { + /** + * To retarget an object A against an object B, repeat these steps until + * they return an object: + * 1. If one of the following is true + * - A is not a node + * - A's root is not a shadow root + * - B is a node and A's root is a shadow-including inclusive ancestor + * of B + * then return A. + * 2. Set A to A's root's host. + */ + while (true) { + if (!a || !util_1.Guard.isNode(a)) { + return a; + } + const rootOfA = tree_rootNode(a); + if (!util_1.Guard.isShadowRoot(rootOfA)) { + return a; + } + if (b && util_1.Guard.isNode(b) && tree_isAncestorOf(rootOfA, b, true, true)) { + return a; + } + a = rootOfA.host; + } +} +exports.tree_retarget = tree_retarget; +//# sourceMappingURL=TreeAlgorithm.js.map + +/***/ }), + +/***/ 879: +/***/ (function(__unusedmodule, exports) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * Represents a cache for storing order between equal objects. + * + * This cache is used when an algorithm compares two objects and finds them to + * be equal but still needs to establish an order between those two objects. + * When two such objects `a` and `b` are passed to the `check` method, a random + * number is generated with `Math.random()`. If the random number is less than + * `0.5` it is assumed that `a < b` otherwise `a > b`. The random number along + * with `a` and `b` is stored in the cache, so that subsequent checks result + * in the same consistent result. + * + * The cache has a size limit which is defined on initialization. + */ +class CompareCache { + /** + * Initializes a new instance of `CompareCache`. + * + * @param limit - maximum number of items to keep in the cache. When the limit + * is exceeded the first item is removed from the cache. + */ + constructor(limit = 1000) { + this._items = new Map(); + this._limit = limit; + } + /** + * Compares and caches the given objects. Returns `true` if `objA < objB` and + * `false` otherwise. + * + * @param objA - an item to compare + * @param objB - an item to compare + */ + check(objA, objB) { + if (this._items.get(objA) === objB) + return true; + else if (this._items.get(objB) === objA) + return false; + const result = (Math.random() < 0.5); + if (result) { + this._items.set(objA, objB); + } + else { + this._items.set(objB, objA); + } + if (this._items.size > this._limit) { + const it = this._items.keys().next(); + /* istanbul ignore else */ + if (!it.done) { + this._items.delete(it.value); + } + } + return result; + } +} +exports.CompareCache = CompareCache; +//# sourceMappingURL=CompareCache.js.map + +/***/ }), + +/***/ 884: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result["default"] = mod; + return result; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const fs = __importStar(__webpack_require__(747)); +const path = __importStar(__webpack_require__(622)); +const io = __importStar(__webpack_require__(1)); +const exec = __importStar(__webpack_require__(986)); +const util = __importStar(__webpack_require__(322)); +exports.PRIVATE_KEY_FILE = path.join(util.getTempDir(), 'private-key.asc'); +const PRIVATE_KEY_FINGERPRINT_REGEX = /\w{40}/; +function importKey(privateKey) { + return __awaiter(this, void 0, void 0, function* () { + fs.writeFileSync(exports.PRIVATE_KEY_FILE, privateKey, { + encoding: 'utf-8', + flag: 'w' + }); + let output = ''; + const options = { + silent: true, + listeners: { + stdout: (data) => { + output += data.toString(); + } + } + }; + yield exec.exec('gpg', [ + '--batch', + '--import-options', + 'import-show', + '--import', + exports.PRIVATE_KEY_FILE + ], options); + yield io.rmRF(exports.PRIVATE_KEY_FILE); + const match = output.match(PRIVATE_KEY_FINGERPRINT_REGEX); + return match && match[0]; + }); +} +exports.importKey = importKey; +function deleteKey(keyFingerprint) { + return __awaiter(this, void 0, void 0, function* () { + yield exec.exec('gpg', ['--batch', '--yes', '--delete-secret-keys', keyFingerprint], { silent: true }); + yield exec.exec('gpg', ['--batch', '--yes', '--delete-keys', keyFingerprint], { silent: true }); + }); +} +exports.deleteKey = deleteKey; + + +/***/ }), + +/***/ 889: +/***/ (function(__unusedmodule, exports) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * Represents a cache of objects with a size limit. + */ +class ObjectCache { + /** + * Initializes a new instance of `ObjectCache`. + * + * @param limit - maximum number of items to keep in the cache. When the limit + * is exceeded the first item is removed from the cache. + */ + constructor(limit = 1000) { + this._items = new Map(); + this._limit = limit; + } + /** + * Gets an item from the cache. + * + * @param key - object key + */ + get(key) { + return this._items.get(key); + } + /** + * Adds a new item to the cache. + * + * @param key - object key + * @param value - object value + */ + set(key, value) { + this._items.set(key, value); + if (this._items.size > this._limit) { + const it = this._items.keys().next(); + /* istanbul ignore else */ + if (!it.done) { + this._items.delete(it.value); + } + } + } + /** + * Removes an item from the cache. + * + * @param item - an item + */ + delete(key) { + return this._items.delete(key); + } + /** + * Determines if an item is in the cache. + * + * @param item - an item + */ + has(key) { + return this._items.has(key); + } + /** + * Removes all items from the cache. + */ + clear() { + this._items.clear(); + } + /** + * Gets the number of items in the cache. + */ + get size() { return this._items.size; } + /** + * Applies the given callback function to all elements of the cache. + */ + forEach(callback, thisArg) { + this._items.forEach((v, k) => callback.call(thisArg, k, v)); + } + /** + * Iterates through the items in the set. + */ + *keys() { + yield* this._items.keys(); + } + /** + * Iterates through the items in the set. + */ + *values() { + yield* this._items.values(); + } + /** + * Iterates through the items in the set. + */ + *entries() { + yield* this._items.entries(); + } + /** + * Iterates through the items in the set. + */ + *[Symbol.iterator]() { + yield* this._items; + } + /** + * Returns the string tag of the cache. + */ + get [Symbol.toStringTag]() { + return "ObjectCache"; + } +} +exports.ObjectCache = ObjectCache; +//# sourceMappingURL=ObjectCache.js.map + +/***/ }), + +/***/ 904: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const Guard_1 = __webpack_require__(783); +/** + * Contains type casts for DOM objects. + */ +class Cast { + /** + * Casts the given object to a `Node`. + * + * @param a - the object to cast + */ + static asNode(a) { + if (Guard_1.Guard.isNode(a)) { + return a; + } + else { + throw new Error("Invalid object. Node expected."); + } + } +} +exports.Cast = Cast; +//# sourceMappingURL=Cast.js.map + +/***/ }), + +/***/ 911: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const interfaces_1 = __webpack_require__(172); +/** + * Represents a lexer for XML content in a string. + */ +class XMLStringLexer { + /** + * Initializes a new instance of `XMLStringLexer`. + * + * @param str - the string to tokenize and lex + * @param options - lexer options + */ + constructor(str, options) { + this._options = { + skipWhitespaceOnlyText: false + }; + this.err = { line: -1, col: -1, index: -1, str: "" }; + this._str = str; + this._index = 0; + this._length = str.length; + if (options) { + this._options.skipWhitespaceOnlyText = options.skipWhitespaceOnlyText || false; + } + } + /** + * Returns the next token. + */ + nextToken() { + if (this.eof()) { + return { type: interfaces_1.TokenType.EOF }; + } + let token = (this.skipIfStartsWith('<') ? this.openBracket() : this.text()); + if (this._options.skipWhitespaceOnlyText) { + if (token.type === interfaces_1.TokenType.Text && + XMLStringLexer.isWhiteSpaceToken(token)) { + token = this.nextToken(); + } + } + return token; + } + /** + * Branches from an opening bracket (`<`). + */ + openBracket() { + if (this.skipIfStartsWith('?')) { + if (this.skipIfStartsWith('xml')) { + if (XMLStringLexer.isSpace(this._str[this._index])) { + return this.declaration(); + } + else { + // a processing instruction starting with xml. e.g. + this.seek(-3); + return this.pi(); + } + } + else { + return this.pi(); + } + } + else if (this.skipIfStartsWith('!')) { + if (this.skipIfStartsWith('--')) { + return this.comment(); + } + else if (this.skipIfStartsWith('[CDATA[')) { + return this.cdata(); + } + else if (this.skipIfStartsWith('DOCTYPE')) { + return this.doctype(); + } + else { + this.throwError("Invalid '!' in opening tag."); + } + } + else if (this.skipIfStartsWith('/')) { + return this.closeTag(); + } + else { + return this.openTag(); + } + } + /** + * Produces an XML declaration token. + */ + declaration() { + let version = ''; + let encoding = ''; + let standalone = ''; + while (!this.eof()) { + this.skipSpace(); + if (this.skipIfStartsWith('?>')) { + return { type: interfaces_1.TokenType.Declaration, version: version, encoding: encoding, standalone: standalone }; + } + else { + // attribute name + const [attName, attValue] = this.attribute(); + if (attName === 'version') + version = attValue; + else if (attName === 'encoding') + encoding = attValue; + else if (attName === 'standalone') + standalone = attValue; + else + this.throwError('Invalid attribute name: ' + attName); + } + } + this.throwError('Missing declaration end symbol `?>`'); + } + /** + * Produces a doc type token. + */ + doctype() { + let pubId = ''; + let sysId = ''; + // name + this.skipSpace(); + const name = this.takeUntil2('[', '>', true); + this.skipSpace(); + if (this.skipIfStartsWith('PUBLIC')) { + pubId = this.quotedString(); + sysId = this.quotedString(); + } + else if (this.skipIfStartsWith('SYSTEM')) { + sysId = this.quotedString(); + } + // skip internal subset + this.skipSpace(); + if (this.skipIfStartsWith('[')) { + // skip internal subset nodes + this.skipUntil(']'); + if (!this.skipIfStartsWith(']')) { + this.throwError('Missing end bracket of DTD internal subset'); + } + } + this.skipSpace(); + if (!this.skipIfStartsWith('>')) { + this.throwError('Missing doctype end symbol `>`'); + } + return { type: interfaces_1.TokenType.DocType, name: name, pubId: pubId, sysId: sysId }; + } + /** + * Produces a processing instruction token. + */ + pi() { + const target = this.takeUntilStartsWith('?>', true); + if (this.eof()) { + this.throwError('Missing processing instruction end symbol `?>`'); + } + this.skipSpace(); + if (this.skipIfStartsWith('?>')) { + return { type: interfaces_1.TokenType.PI, target: target, data: '' }; + } + const data = this.takeUntilStartsWith('?>'); + if (this.eof()) { + this.throwError('Missing processing instruction end symbol `?>`'); + } + this.seek(2); + return { type: interfaces_1.TokenType.PI, target: target, data: data }; + } + /** + * Produces a text token. + * + */ + text() { + const data = this.takeUntil('<'); + return { type: interfaces_1.TokenType.Text, data: data }; + } + /** + * Produces a comment token. + * + */ + comment() { + const data = this.takeUntilStartsWith('-->'); + if (this.eof()) { + this.throwError('Missing comment end symbol `-->`'); + } + this.seek(3); + return { type: interfaces_1.TokenType.Comment, data: data }; + } + /** + * Produces a CDATA token. + * + */ + cdata() { + const data = this.takeUntilStartsWith(']]>'); + if (this.eof()) { + this.throwError('Missing CDATA end symbol `]>`'); + } + this.seek(3); + return { type: interfaces_1.TokenType.CDATA, data: data }; + } + /** + * Produces an element token. + */ + openTag() { + // element name + this.skipSpace(); + const name = this.takeUntil2('>', '/', true); + this.skipSpace(); + if (this.skipIfStartsWith('>')) { + return { type: interfaces_1.TokenType.Element, name: name, attributes: [], selfClosing: false }; + } + else if (this.skipIfStartsWith('/>')) { + return { type: interfaces_1.TokenType.Element, name: name, attributes: [], selfClosing: true }; + } + // attributes + const attributes = []; + while (!this.eof()) { + // end tag + this.skipSpace(); + if (this.skipIfStartsWith('>')) { + return { type: interfaces_1.TokenType.Element, name: name, attributes: attributes, selfClosing: false }; + } + else if (this.skipIfStartsWith('/>')) { + return { type: interfaces_1.TokenType.Element, name: name, attributes: attributes, selfClosing: true }; + } + const attr = this.attribute(); + attributes.push(attr); + } + this.throwError('Missing opening element tag end symbol `>`'); + } + /** + * Produces a closing tag token. + * + */ + closeTag() { + this.skipSpace(); + const name = this.takeUntil('>', true); + this.skipSpace(); + if (!this.skipIfStartsWith('>')) { + this.throwError('Missing closing element tag end symbol `>`'); + } + return { type: interfaces_1.TokenType.ClosingTag, name: name }; + } + /** + * Reads an attribute name, value pair + */ + attribute() { + // attribute name + this.skipSpace(); + const name = this.takeUntil('=', true); + this.skipSpace(); + if (!this.skipIfStartsWith('=')) { + this.throwError('Missing equals sign before attribute value'); + } + // attribute value + const value = this.quotedString(); + return [name, value]; + } + /** + * Reads a string between double or single quotes. + */ + quotedString() { + this.skipSpace(); + const startQuote = this.take(1); + if (!XMLStringLexer.isQuote(startQuote)) { + this.throwError('Missing start quote character before quoted value'); + } + const value = this.takeUntil(startQuote); + if (!this.skipIfStartsWith(startQuote)) { + this.throwError('Missing end quote character after quoted value'); + } + return value; + } + /** + * Determines if the current index is at or past the end of input string. + */ + eof() { return this._index >= this._length; } + /** + * Skips the length of the given string if the string from current position + * starts with the given string. + * + * @param str - the string to match + */ + skipIfStartsWith(str) { + const strLength = str.length; + if (strLength === 1) { + if (this._str[this._index] === str) { + this._index++; + return true; + } + else { + return false; + } + } + for (let i = 0; i < strLength; i++) { + if (this._str[this._index + i] !== str[i]) + return false; + } + this._index += strLength; + return true; + } + /** + * Seeks a number of character codes. + * + * @param count - number of characters to skip + */ + seek(count) { + this._index += count; + if (this._index < 0) + this._index = 0; + if (this._index > this._length) + this._index = this._length; + } + /** + * Skips space characters. + */ + skipSpace() { + while (!this.eof() && (XMLStringLexer.isSpace(this._str[this._index]))) { + this._index++; + } + } + /** + * Takes a given number of characters. + * + * @param count - character count + */ + take(count) { + if (count === 1) { + return this._str[this._index++]; + } + const startIndex = this._index; + this.seek(count); + return this._str.slice(startIndex, this._index); + } + /** + * Takes characters until the next character matches `char`. + * + * @param char - a character to match + * @param space - whether a space character stops iteration + */ + takeUntil(char, space = false) { + const startIndex = this._index; + while (this._index < this._length) { + const c = this._str[this._index]; + if (c !== char && (!space || !XMLStringLexer.isSpace(c))) { + this._index++; + } + else { + break; + } + } + return this._str.slice(startIndex, this._index); + } + /** + * Takes characters until the next character matches `char1` or `char1`. + * + * @param char1 - a character to match + * @param char2 - a character to match + * @param space - whether a space character stops iteration + */ + takeUntil2(char1, char2, space = false) { + const startIndex = this._index; + while (this._index < this._length) { + const c = this._str[this._index]; + if (c !== char1 && c !== char2 && (!space || !XMLStringLexer.isSpace(c))) { + this._index++; + } + else { + break; + } + } + return this._str.slice(startIndex, this._index); + } + /** + * Takes characters until the next characters matches `str`. + * + * @param str - a string to match + * @param space - whether a space character stops iteration + */ + takeUntilStartsWith(str, space = false) { + const startIndex = this._index; + const strLength = str.length; + while (this._index < this._length) { + let match = true; + for (let i = 0; i < strLength; i++) { + const c = this._str[this._index + i]; + const char = str[i]; + if (space && XMLStringLexer.isSpace(c)) { + return this._str.slice(startIndex, this._index); + } + else if (c !== char) { + this._index++; + match = false; + break; + } + } + if (match) + return this._str.slice(startIndex, this._index); + } + this._index = this._length; + return this._str.slice(startIndex); + } + /** + * Skips characters until the next character matches `char`. + * + * @param char - a character to match + */ + skipUntil(char) { + while (this._index < this._length) { + const c = this._str[this._index]; + if (c !== char) { + this._index++; + } + else { + break; + } + } + } + /** + * Determines if the given token is entirely whitespace. + * + * @param token - the token to check + */ + static isWhiteSpaceToken(token) { + const str = token.data; + for (let i = 0; i < str.length; i++) { + const c = str[i]; + if (c !== ' ' && c !== '\n' && c !== '\r' && c !== '\t' && c !== '\f') + return false; + } + return true; + } + /** + * Determines if the given character is whitespace. + * + * @param char - the character to check + */ + static isSpace(char) { + return char === ' ' || char === '\n' || char === '\r' || char === '\t'; + } + /** + * Determines if the given character is a quote character. + * + * @param char - the character to check + */ + static isQuote(char) { + return (char === '"' || char === '\''); + } + /** + * Throws a parser error and records the line and column numbers in the parsed + * string. + * + * @param msg - error message + */ + throwError(msg) { + const regexp = /\r\n|\r|\n/g; + let match = null; + let line = 0; + let firstNewLineIndex = 0; + let lastNewlineIndex = this._str.length; + while ((match = regexp.exec(this._str)) !== null) { + if (match === null) + break; + line++; + if (match.index < this._index) + firstNewLineIndex = regexp.lastIndex; + if (match.index > this._index) { + lastNewlineIndex = match.index; + break; + } + } + this.err = { + line: line, + col: this._index - firstNewLineIndex, + index: this._index, + str: this._str.substring(firstNewLineIndex, lastNewlineIndex) + }; + throw new Error(msg + "\nIndex: " + this.err.index + + "\nLn: " + this.err.line + ", Col: " + this.err.col + + "\nInput: " + this.err.str); + } + /** + * Returns an iterator for the lexer. + */ + [Symbol.iterator]() { + this._index = 0; + return { + next: function () { + const token = this.nextToken(); + if (token.type === interfaces_1.TokenType.EOF) { + return { done: true, value: null }; + } + else { + return { done: false, value: token }; + } + }.bind(this) + }; + } +} +exports.XMLStringLexer = XMLStringLexer; +//# sourceMappingURL=XMLStringLexer.js.map + +/***/ }), + +/***/ 916: +/***/ (function(__unusedmodule, exports) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +exports.HTML = "http://www.w3.org/1999/xhtml"; +exports.XML = "http://www.w3.org/XML/1998/namespace"; +exports.XMLNS = "http://www.w3.org/2000/xmlns/"; +exports.MathML = "http://www.w3.org/1998/Math/MathML"; +exports.SVG = "http://www.w3.org/2000/svg"; +exports.XLink = "http://www.w3.org/1999/xlink"; +//# sourceMappingURL=Namespace.js.map + +/***/ }), + +/***/ 918: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +var Cast_1 = __webpack_require__(904); +exports.Cast = Cast_1.Cast; +var Guard_1 = __webpack_require__(783); +exports.Guard = Guard_1.Guard; +var EmptySet_1 = __webpack_require__(968); +exports.EmptySet = EmptySet_1.EmptySet; +//# sourceMappingURL=index.js.map + +/***/ }), + +/***/ 920: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const TextImpl_1 = __webpack_require__(820); +const interfaces_1 = __webpack_require__(970); +const WebIDLAlgorithm_1 = __webpack_require__(495); +/** + * Represents a CDATA node. + */ +class CDATASectionImpl extends TextImpl_1.TextImpl { + /** + * Initializes a new instance of `CDATASection`. + * + * @param data - node contents + */ + constructor(data) { + super(data); + } + /** + * Creates a new `CDATASection`. + * + * @param document - owner document + * @param data - node contents + */ + static _create(document, data = '') { + const node = new CDATASectionImpl(data); + node._nodeDocument = document; + return node; + } +} +exports.CDATASectionImpl = CDATASectionImpl; +/** + * Initialize prototype properties + */ +WebIDLAlgorithm_1.idl_defineConst(CDATASectionImpl.prototype, "_nodeType", interfaces_1.NodeType.CData); +//# sourceMappingURL=CDATASectionImpl.js.map + +/***/ }), + +/***/ 923: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result["default"] = mod; + return result; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const core = __importStar(__webpack_require__(470)); +const io = __importStar(__webpack_require__(1)); +const exec = __importStar(__webpack_require__(986)); +const httpm = __importStar(__webpack_require__(539)); +const tc = __importStar(__webpack_require__(533)); +const fs = __importStar(__webpack_require__(747)); +const path = __importStar(__webpack_require__(622)); +const semver = __importStar(__webpack_require__(280)); +const util = __importStar(__webpack_require__(322)); +const tempDirectory = util.getTempDir(); +const IS_WINDOWS = util.isWindows(); +function getJava(version, arch, jdkFile, javaPackage) { + return __awaiter(this, void 0, void 0, function* () { + let toolPath = tc.find(javaPackage, version); + if (toolPath) { + core.debug(`Tool found in cache ${toolPath}`); + } + else { + let compressedFileExtension = ''; + if (!jdkFile) { + core.debug('Downloading JDK from Azul'); + const http = new httpm.HttpClient('setup-java', undefined, { + allowRetries: true, + maxRetries: 3 + }); + const url = 'https://static.azul.com/zulu/bin/'; + const response = yield http.get(url); + const statusCode = response.message.statusCode || 0; + if (statusCode < 200 || statusCode > 299) { + let body = ''; + try { + body = yield response.readBody(); + } + catch (err) { + core.debug(`Unable to read body: ${err.message}`); + } + const message = `Unexpected HTTP status code '${response.message.statusCode}' when retrieving versions from '${url}'. ${body}`.trim(); + throw new Error(message); + } + const contents = yield response.readBody(); + const refs = contents.match(//gi) || []; + const downloadInfo = getDownloadInfo(refs, version, javaPackage); + jdkFile = yield tc.downloadTool(downloadInfo.url); + version = downloadInfo.version; + compressedFileExtension = IS_WINDOWS ? '.zip' : '.tar.gz'; + } + else { + core.debug('Retrieving Jdk from local path'); + } + compressedFileExtension = compressedFileExtension || getFileEnding(jdkFile); + let tempDir = path.join(tempDirectory, 'temp_' + Math.floor(Math.random() * 2000000000)); + const jdkDir = yield unzipJavaDownload(jdkFile, compressedFileExtension, tempDir); + core.debug(`jdk extracted to ${jdkDir}`); + toolPath = yield tc.cacheDir(jdkDir, javaPackage, getCacheVersionString(version), arch); + } + let extendedJavaHome = 'JAVA_HOME_' + version + '_' + arch; + core.exportVariable('JAVA_HOME', toolPath); + core.exportVariable(extendedJavaHome, toolPath); + core.addPath(path.join(toolPath, 'bin')); + }); +} +exports.getJava = getJava; +function getCacheVersionString(version) { + const versionArray = version.split('.'); + const major = versionArray[0]; + const minor = versionArray.length > 1 ? versionArray[1] : '0'; + const patch = versionArray.length > 2 ? versionArray[2] : '0'; + return `${major}.${minor}.${patch}`; +} +function getFileEnding(file) { + let fileEnding = ''; + if (file.endsWith('.tar')) { + fileEnding = '.tar'; + } + else if (file.endsWith('.tar.gz')) { + fileEnding = '.tar.gz'; + } + else if (file.endsWith('.zip')) { + fileEnding = '.zip'; + } + else if (file.endsWith('.7z')) { + fileEnding = '.7z'; + } + else { + throw new Error(`${file} has an unsupported file extension`); + } + return fileEnding; +} +function extractFiles(file, fileEnding, destinationFolder) { + return __awaiter(this, void 0, void 0, function* () { + const stats = fs.statSync(file); + if (!stats) { + throw new Error(`Failed to extract ${file} - it doesn't exist`); + } + else if (stats.isDirectory()) { + throw new Error(`Failed to extract ${file} - it is a directory`); + } + if ('.tar' === fileEnding || '.tar.gz' === fileEnding) { + yield tc.extractTar(file, destinationFolder); + } + else if ('.zip' === fileEnding) { + yield tc.extractZip(file, destinationFolder); + } + else { + // fall through and use sevenZip + yield tc.extract7z(file, destinationFolder); + } + }); +} +// This method recursively finds all .pack files under fsPath and unpacks them with the unpack200 tool +function unpackJars(fsPath, javaBinPath) { + return __awaiter(this, void 0, void 0, function* () { + if (fs.existsSync(fsPath)) { + if (fs.lstatSync(fsPath).isDirectory()) { + for (const file in fs.readdirSync(fsPath)) { + const curPath = path.join(fsPath, file); + yield unpackJars(curPath, javaBinPath); + } + } + else if (path.extname(fsPath).toLowerCase() === '.pack') { + // Unpack the pack file synchonously + const p = path.parse(fsPath); + const toolName = IS_WINDOWS ? 'unpack200.exe' : 'unpack200'; + const args = IS_WINDOWS ? '-r -v -l ""' : ''; + const name = path.join(p.dir, p.name); + yield exec.exec(`"${path.join(javaBinPath, toolName)}"`, [ + `${args} "${name}.pack" "${name}.jar"` + ]); + } + } + }); +} +function unzipJavaDownload(repoRoot, fileEnding, destinationFolder, extension) { + return __awaiter(this, void 0, void 0, function* () { + // Create the destination folder if it doesn't exist + yield io.mkdirP(destinationFolder); + const jdkFile = path.normalize(repoRoot); + const stats = fs.statSync(jdkFile); + if (stats.isFile()) { + yield extractFiles(jdkFile, fileEnding, destinationFolder); + const jdkDirectory = path.join(destinationFolder, fs.readdirSync(destinationFolder)[0]); + yield unpackJars(jdkDirectory, path.join(jdkDirectory, 'bin')); + return jdkDirectory; + } + else { + throw new Error(`Jdk argument ${jdkFile} is not a file`); + } + }); +} +function getDownloadInfo(refs, version, javaPackage) { + version = normalizeVersion(version); + let extension = ''; + if (IS_WINDOWS) { + extension = `-win_x64.zip`; + } + else { + if (process.platform === 'darwin') { + extension = `-macosx_x64.tar.gz`; + } + else { + extension = `-linux_x64.tar.gz`; + } + } + let pkgRegexp = new RegExp(''); + let pkgTypeLength = 0; + if (javaPackage === 'jdk') { + pkgRegexp = /jdk.*-/gi; + pkgTypeLength = 'jdk'.length; + } + else if (javaPackage == 'jre') { + pkgRegexp = /jre.*-/gi; + pkgTypeLength = 'jre'.length; + } + else if (javaPackage == 'jdk+fx') { + pkgRegexp = /fx-jdk.*-/gi; + pkgTypeLength = 'fx-jdk'.length; + } + else { + throw new Error(`package argument ${javaPackage} is not in [jdk | jre | jdk+fx]`); + } + // Maps version to url + let versionMap = new Map(); + // Filter by platform + refs.forEach(ref => { + if (!ref.endsWith(extension + '">')) { + return; + } + // If we haven't returned, means we're looking at the correct platform + let versions = ref.match(pkgRegexp) || []; + if (versions.length > 1) { + throw new Error(`Invalid ref received from https://static.azul.com/zulu/bin/: ${ref}`); + } + if (versions.length == 0) { + return; + } + const refVersion = versions[0].slice(pkgTypeLength, versions[0].length - 1); + if (semver.satisfies(refVersion, version)) { + versionMap.set(refVersion, 'https://static.azul.com/zulu/bin/' + + ref.slice(''.length)); + } + }); + // Choose the most recent satisfying version + let curVersion = '0.0.0'; + let curUrl = ''; + for (const entry of versionMap.entries()) { + const entryVersion = entry[0]; + const entryUrl = entry[1]; + if (semver.gt(entryVersion, curVersion)) { + curUrl = entryUrl; + curVersion = entryVersion; + } + } + if (curUrl == '') { + throw new Error(`No valid download found for version ${version} and package ${javaPackage}. Check https://static.azul.com/zulu/bin/ for a list of valid versions or download your own jdk file and add the jdkFile argument`); + } + return { version: curVersion, url: curUrl }; +} +function normalizeVersion(version) { + if (version.slice(0, 2) === '1.') { + // Trim leading 1. for versions like 1.8 + version = version.slice(2); + if (!version) { + throw new Error('1. is not a valid version'); + } + } + if (version.endsWith('-ea')) { + // convert e.g. 14-ea to 14.0.0-ea + if (version.indexOf('.') == -1) { + version = version.slice(0, version.length - 3) + '.0.0-ea'; + } + // match anything in -ea.X (semver won't do .x matching on pre-release versions) + if (version[0] >= '0' && version[0] <= '9') { + version = '>=' + version; + } + } + else if (version.split('.').length < 3) { + // For non-ea versions, add trailing .x if it is missing + if (version[version.length - 1] != 'x') { + version = version + '.x'; + } + } + return version; +} + + +/***/ }), + +/***/ 932: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const EventTargetImpl_1 = __webpack_require__(597); +const util_1 = __webpack_require__(337); +const algorithm_1 = __webpack_require__(163); +/** + * Represents a window containing a DOM document. + */ +class WindowImpl extends EventTargetImpl_1.EventTargetImpl { + /** + * Initializes a new instance of `Window`. + */ + constructor() { + super(); + this._signalSlots = new Set(); + this._mutationObserverMicrotaskQueued = false; + this._mutationObservers = new Set(); + this._iteratorList = new util_1.FixedSizeSet(); + this._associatedDocument = algorithm_1.create_document(); + } + /** @inheritdoc */ + get document() { return this._associatedDocument; } + /** @inheritdoc */ + get event() { return this._currentEvent; } + /** + * Creates a new window with a blank document. + */ + static _create() { + return new WindowImpl(); + } +} +exports.WindowImpl = WindowImpl; +//# sourceMappingURL=WindowImpl.js.map + +/***/ }), + +/***/ 934: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const util_1 = __webpack_require__(918); +const algorithm_1 = __webpack_require__(163); +/** + * Represents a mixin that extends parent nodes that can have children. + * This mixin is implemented by {@link Element}, {@link Document} and + * {@link DocumentFragment}. + */ +class ParentNodeImpl { + /** @inheritdoc */ + get children() { + /** + * The children attribute’s getter must return an HTMLCollection collection + * rooted at context object matching only element children. + */ + return algorithm_1.create_htmlCollection(util_1.Cast.asNode(this)); + } + /** @inheritdoc */ + get firstElementChild() { + /** + * The firstElementChild attribute’s getter must return the first child + * that is an element, and null otherwise. + */ + let node = util_1.Cast.asNode(this)._firstChild; + while (node) { + if (util_1.Guard.isElementNode(node)) + return node; + else + node = node._nextSibling; + } + return null; + } + /** @inheritdoc */ + get lastElementChild() { + /** + * The lastElementChild attribute’s getter must return the last child that + * is an element, and null otherwise. + */ + let node = util_1.Cast.asNode(this)._lastChild; + while (node) { + if (util_1.Guard.isElementNode(node)) + return node; + else + node = node._previousSibling; + } + return null; + } + /** @inheritdoc */ + get childElementCount() { + /** + * The childElementCount attribute’s getter must return the number of + * children of context object that are elements. + */ + let count = 0; + for (const childNode of util_1.Cast.asNode(this)._children) { + if (util_1.Guard.isElementNode(childNode)) + count++; + } + return count; + } + /** @inheritdoc */ + prepend(...nodes) { + /** + * 1. Let node be the result of converting nodes into a node given nodes + * and context object’s node document. + * 2. Pre-insert node into context object before the context object’s first + * child. + */ + const node = util_1.Cast.asNode(this); + const childNode = algorithm_1.parentNode_convertNodesIntoANode(nodes, node._nodeDocument); + algorithm_1.mutation_preInsert(childNode, node, node._firstChild); + } + /** @inheritdoc */ + append(...nodes) { + /** + * 1. Let node be the result of converting nodes into a node given nodes + * and context object’s node document. + * 2. Append node to context object. + */ + const node = util_1.Cast.asNode(this); + const childNode = algorithm_1.parentNode_convertNodesIntoANode(nodes, node._nodeDocument); + algorithm_1.mutation_append(childNode, node); + } + /** @inheritdoc */ + querySelector(selectors) { + /** + * The querySelector(selectors) method, when invoked, must return the first + * result of running scope-match a selectors string selectors against + * context object, if the result is not an empty list, and null otherwise. + */ + const node = util_1.Cast.asNode(this); + const result = algorithm_1.selectors_scopeMatchASelectorsString(selectors, node); + return (result.length === 0 ? null : result[0]); + } + /** @inheritdoc */ + querySelectorAll(selectors) { + /** + * The querySelectorAll(selectors) method, when invoked, must return the + * static result of running scope-match a selectors string selectors against + * context object. + */ + const node = util_1.Cast.asNode(this); + const result = algorithm_1.selectors_scopeMatchASelectorsString(selectors, node); + return algorithm_1.create_nodeListStatic(node, result); + } +} +exports.ParentNodeImpl = ParentNodeImpl; +//# sourceMappingURL=ParentNodeImpl.js.map + +/***/ }), + +/***/ 935: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const _1 = __webpack_require__(113); +const interfaces_1 = __webpack_require__(970); +const EventTargetImpl_1 = __webpack_require__(597); +const util_1 = __webpack_require__(918); +const DOMException_1 = __webpack_require__(35); +const algorithm_1 = __webpack_require__(163); +const URLAlgorithm_1 = __webpack_require__(813); +const WebIDLAlgorithm_1 = __webpack_require__(495); +/** + * Represents a generic XML node. + */ +class NodeImpl extends EventTargetImpl_1.EventTargetImpl { + /** + * Initializes a new instance of `Node`. + */ + constructor() { + super(); + this._parent = null; + this._firstChild = null; + this._lastChild = null; + this._previousSibling = null; + this._nextSibling = null; + } + get _childNodes() { + return this.__childNodes || (this.__childNodes = algorithm_1.create_nodeList(this)); + } + get _nodeDocument() { return this._nodeDocumentOverride || _1.dom.window._associatedDocument; } + set _nodeDocument(val) { this._nodeDocumentOverride = val; } + get _registeredObserverList() { + return this.__registeredObserverList || (this.__registeredObserverList = []); + } + /** @inheritdoc */ + get nodeType() { return this._nodeType; } + /** + * Returns a string appropriate for the type of node. + */ + get nodeName() { + if (util_1.Guard.isElementNode(this)) { + return this._htmlUppercasedQualifiedName; + } + else if (util_1.Guard.isAttrNode(this)) { + return this._qualifiedName; + } + else if (util_1.Guard.isExclusiveTextNode(this)) { + return "#text"; + } + else if (util_1.Guard.isCDATASectionNode(this)) { + return "#cdata-section"; + } + else if (util_1.Guard.isProcessingInstructionNode(this)) { + return this._target; + } + else if (util_1.Guard.isCommentNode(this)) { + return "#comment"; + } + else if (util_1.Guard.isDocumentNode(this)) { + return "#document"; + } + else if (util_1.Guard.isDocumentTypeNode(this)) { + return this._name; + } + else if (util_1.Guard.isDocumentFragmentNode(this)) { + return "#document-fragment"; + } + else { + return ""; + } + } + /** + * Gets the absolute base URL of the node. + */ + get baseURI() { + /** + * The baseURI attribute’s getter must return node document’s document + * base URL, serialized. + * TODO: Implement in HTML DOM + * https://html.spec.whatwg.org/multipage/urls-and-fetching.html#document-base-url + */ + return URLAlgorithm_1.urlSerializer(this._nodeDocument._URL); + } + /** + * Returns whether the node is rooted to a document node. + */ + get isConnected() { + /** + * The isConnected attribute’s getter must return true, if context object + * is connected, and false otherwise. + */ + return util_1.Guard.isElementNode(this) && algorithm_1.shadowTree_isConnected(this); + } + /** + * Returns the parent document. + */ + get ownerDocument() { + /** + * The ownerDocument attribute’s getter must return null, if the context + * object is a document, and the context object’s node document otherwise. + * _Note:_ The node document of a document is that document itself. All + * nodes have a node document at all times. + */ + if (this._nodeType === interfaces_1.NodeType.Document) + return null; + else + return this._nodeDocument; + } + /** + * Returns the root node. + * + * @param options - if options has `composed = true` this function + * returns the node's shadow-including root, otherwise it returns + * the node's root node. + */ + getRootNode(options) { + /** + * The getRootNode(options) method, when invoked, must return context + * object’s shadow-including root if options’s composed is true, + * and context object’s root otherwise. + */ + return algorithm_1.tree_rootNode(this, !!options && options.composed); + } + /** + * Returns the parent node. + */ + get parentNode() { + /** + * The parentNode attribute’s getter must return the context object’s parent. + * _Note:_ An Attr node has no parent. + */ + if (this._nodeType === interfaces_1.NodeType.Attribute) { + return null; + } + else { + return this._parent; + } + } + /** + * Returns the parent element. + */ + get parentElement() { + /** + * The parentElement attribute’s getter must return the context object’s + * parent element. + */ + if (this._parent && util_1.Guard.isElementNode(this._parent)) { + return this._parent; + } + else { + return null; + } + } + /** + * Determines whether a node has any children. + */ + hasChildNodes() { + /** + * The hasChildNodes() method, when invoked, must return true if the context + * object has children, and false otherwise. + */ + return (this._firstChild !== null); + } + /** + * Returns a {@link NodeList} of child nodes. + */ + get childNodes() { + /** + * The childNodes attribute’s getter must return a NodeList rooted at the + * context object matching only children. + */ + return this._childNodes; + } + /** + * Returns the first child node. + */ + get firstChild() { + /** + * The firstChild attribute’s getter must return the context object’s first + * child. + */ + return this._firstChild; + } + /** + * Returns the last child node. + */ + get lastChild() { + /** + * The lastChild attribute’s getter must return the context object’s last + * child. + */ + return this._lastChild; + } + /** + * Returns the previous sibling node. + */ + get previousSibling() { + /** + * The previousSibling attribute’s getter must return the context object’s + * previous sibling. + * _Note:_ An Attr node has no siblings. + */ + return this._previousSibling; + } + /** + * Returns the next sibling node. + */ + get nextSibling() { + /** + * The nextSibling attribute’s getter must return the context object’s + * next sibling. + */ + return this._nextSibling; + } + /** + * Gets or sets the data associated with a {@link CharacterData} node or the + * value of an {@link @Attr} node. For other node types returns `null`. + */ + get nodeValue() { + if (util_1.Guard.isAttrNode(this)) { + return this._value; + } + else if (util_1.Guard.isCharacterDataNode(this)) { + return this._data; + } + else { + return null; + } + } + set nodeValue(value) { + if (value === null) { + value = ''; + } + if (util_1.Guard.isAttrNode(this)) { + algorithm_1.attr_setAnExistingAttributeValue(this, value); + } + else if (util_1.Guard.isCharacterDataNode(this)) { + algorithm_1.characterData_replaceData(this, 0, this._data.length, value); + } + } + /** + * Returns the concatenation of data of all the {@link Text} + * node descendants in tree order. When set, replaces the text + * contents of the node with the given value. + */ + get textContent() { + if (util_1.Guard.isDocumentFragmentNode(this) || util_1.Guard.isElementNode(this)) { + return algorithm_1.text_descendantTextContent(this); + } + else if (util_1.Guard.isAttrNode(this)) { + return this._value; + } + else if (util_1.Guard.isCharacterDataNode(this)) { + return this._data; + } + else { + return null; + } + } + set textContent(value) { + if (value === null) { + value = ''; + } + if (util_1.Guard.isDocumentFragmentNode(this) || util_1.Guard.isElementNode(this)) { + algorithm_1.node_stringReplaceAll(value, this); + } + else if (util_1.Guard.isAttrNode(this)) { + algorithm_1.attr_setAnExistingAttributeValue(this, value); + } + else if (util_1.Guard.isCharacterDataNode(this)) { + algorithm_1.characterData_replaceData(this, 0, algorithm_1.tree_nodeLength(this), value); + } + } + /** + * Puts all {@link Text} nodes in the full depth of the sub-tree + * underneath this node into a "normal" form where only markup + * (e.g., tags, comments, processing instructions, CDATA sections, + * and entity references) separates {@link Text} nodes, i.e., there + * are no adjacent Text nodes. + */ + normalize() { + /** + * The normalize() method, when invoked, must run these steps for each + * descendant exclusive Text node node of context object: + */ + const descendantNodes = []; + let node = algorithm_1.tree_getFirstDescendantNode(this, false, false, (e) => util_1.Guard.isExclusiveTextNode(e)); + while (node !== null) { + descendantNodes.push(node); + node = algorithm_1.tree_getNextDescendantNode(this, node, false, false, (e) => util_1.Guard.isExclusiveTextNode(e)); + } + for (let i = 0; i < descendantNodes.length; i++) { + const node = descendantNodes[i]; + if (node._parent === null) + continue; + /** + * 1. Let length be node’s length. + * 2. If length is zero, then remove node and continue with the next + * exclusive Text node, if any. + */ + let length = algorithm_1.tree_nodeLength(node); + if (length === 0) { + algorithm_1.mutation_remove(node, node._parent); + continue; + } + /** + * 3. Let data be the concatenation of the data of node’s contiguous + * exclusive Text nodes (excluding itself), in tree order. + */ + const textSiblings = []; + let data = ''; + for (const sibling of algorithm_1.text_contiguousExclusiveTextNodes(node)) { + textSiblings.push(sibling); + data += sibling._data; + } + /** + * 4. Replace data with node node, offset length, count 0, and data data. + */ + algorithm_1.characterData_replaceData(node, length, 0, data); + /** + * 5. Let currentNode be node’s next sibling. + * 6. While currentNode is an exclusive Text node: + */ + if (_1.dom.rangeList.size !== 0) { + let currentNode = node._nextSibling; + while (currentNode !== null && util_1.Guard.isExclusiveTextNode(currentNode)) { + /** + * 6.1. For each live range whose start node is currentNode, add length + * to its start offset and set its start node to node. + * 6.2. For each live range whose end node is currentNode, add length to + * its end offset and set its end node to node. + * 6.3. For each live range whose start node is currentNode’s parent and + * start offset is currentNode’s index, set its start node to node and + * its start offset to length. + * 6.4. For each live range whose end node is currentNode’s parent and + * end offset is currentNode’s index, set its end node to node and its + * end offset to length. + */ + const cn = currentNode; + const index = algorithm_1.tree_index(cn); + for (const range of _1.dom.rangeList) { + if (range._start[0] === cn) { + range._start[0] = node; + range._start[1] += length; + } + if (range._end[0] === cn) { + range._end[0] = node; + range._end[1] += length; + } + if (range._start[0] === cn._parent && range._start[1] === index) { + range._start[0] = node; + range._start[1] = length; + } + if (range._end[0] === cn._parent && range._end[1] === index) { + range._end[0] = node; + range._end[1] = length; + } + } + /** + * 6.5. Add currentNode’s length to length. + * 6.6. Set currentNode to its next sibling. + */ + length += algorithm_1.tree_nodeLength(currentNode); + currentNode = currentNode._nextSibling; + } + } + /** + * 7. Remove node’s contiguous exclusive Text nodes (excluding itself), + * in tree order. + */ + for (let i = 0; i < textSiblings.length; i++) { + const sibling = textSiblings[i]; + if (sibling._parent === null) + continue; + algorithm_1.mutation_remove(sibling, sibling._parent); + } + } + } + /** + * Returns a duplicate of this node, i.e., serves as a generic copy + * constructor for nodes. The duplicate node has no parent + * ({@link parentNode} returns `null`). + * + * @param deep - if `true`, recursively clone the subtree under the + * specified node. If `false`, clone only the node itself (and its + * attributes, if it is an {@link Element}). + */ + cloneNode(deep = false) { + /** + * 1. If context object is a shadow root, then throw a "NotSupportedError" + * DOMException. + * 2. Return a clone of the context object, with the clone children flag set + * if deep is true. + */ + if (util_1.Guard.isShadowRoot(this)) + throw new DOMException_1.NotSupportedError(); + return algorithm_1.node_clone(this, null, deep); + } + /** + * Determines if the given node is equal to this one. + * + * @param node - the node to compare with + */ + isEqualNode(node = null) { + /** + * The isEqualNode(otherNode) method, when invoked, must return true if + * otherNode is non-null and context object equals otherNode, and false + * otherwise. + */ + return (node !== null && algorithm_1.node_equals(this, node)); + } + /** + * Determines if the given node is reference equal to this one. + * + * @param node - the node to compare with + */ + isSameNode(node = null) { + /** + * The isSameNode(otherNode) method, when invoked, must return true if + * otherNode is context object, and false otherwise. + */ + return (this === node); + } + /** + * Returns a bitmask indicating the position of the given `node` + * relative to this node. + */ + compareDocumentPosition(other) { + /** + * 1. If context object is other, then return zero. + * 2. Let node1 be other and node2 be context object. + * 3. Let attr1 and attr2 be null. + * attr1’s element. + */ + if (other === this) + return 0; + let node1 = other; + let node2 = this; + let attr1 = null; + let attr2 = null; + /** + * 4. If node1 is an attribute, then set attr1 to node1 and node1 to + * attr1’s element. + */ + if (util_1.Guard.isAttrNode(node1)) { + attr1 = node1; + node1 = attr1._element; + } + /** + * 5. If node2 is an attribute, then: + */ + if (util_1.Guard.isAttrNode(node2)) { + /** + * 5.1. Set attr2 to node2 and node2 to attr2’s element. + */ + attr2 = node2; + node2 = attr2._element; + /** + * 5.2. If attr1 and node1 are non-null, and node2 is node1, then: + */ + if (attr1 && node1 && (node1 === node2)) { + /** + * 5.2. For each attr in node2’s attribute list: + */ + for (let i = 0; i < node2._attributeList.length; i++) { + const attr = node2._attributeList[i]; + /** + * 5.2.1. If attr equals attr1, then return the result of adding + * DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC and + * DOCUMENT_POSITION_PRECEDING. + * 5.2.2. If attr equals attr2, then return the result of adding + * DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC and + * DOCUMENT_POSITION_FOLLOWING. + */ + if (algorithm_1.node_equals(attr, attr1)) { + return interfaces_1.Position.ImplementationSpecific | interfaces_1.Position.Preceding; + } + else if (algorithm_1.node_equals(attr, attr2)) { + return interfaces_1.Position.ImplementationSpecific | interfaces_1.Position.Following; + } + } + } + } + /** + * 6. If node1 or node2 is null, or node1’s root is not node2’s root, then + * return the result of adding DOCUMENT_POSITION_DISCONNECTED, + * DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC, and either + * DOCUMENT_POSITION_PRECEDING or DOCUMENT_POSITION_FOLLOWING, + * with the constraint that this is to be consistent, together. + */ + if (node1 === null || node2 === null || + algorithm_1.tree_rootNode(node1) !== algorithm_1.tree_rootNode(node2)) { + // nodes are disconnected + // return a random result but cache the value for consistency + return interfaces_1.Position.Disconnected | interfaces_1.Position.ImplementationSpecific | + (_1.dom.compareCache.check(this, other) ? interfaces_1.Position.Preceding : interfaces_1.Position.Following); + } + /** + * 7. If node1 is an ancestor of node2 and attr1 is null, or node1 is node2 + * and attr2 is non-null, then return the result of adding + * DOCUMENT_POSITION_CONTAINS to DOCUMENT_POSITION_PRECEDING. + */ + if ((!attr1 && algorithm_1.tree_isAncestorOf(node2, node1)) || + (attr2 && (node1 === node2))) { + return interfaces_1.Position.Contains | interfaces_1.Position.Preceding; + } + /** + * 8. If node1 is a descendant of node2 and attr2 is null, or node1 is node2 + * and attr1 is non-null, then return the result of adding + * DOCUMENT_POSITION_CONTAINED_BY to DOCUMENT_POSITION_FOLLOWING. + */ + if ((!attr2 && algorithm_1.tree_isDescendantOf(node2, node1)) || + (attr1 && (node1 === node2))) { + return interfaces_1.Position.ContainedBy | interfaces_1.Position.Following; + } + /** + * 9. If node1 is preceding node2, then return DOCUMENT_POSITION_PRECEDING. + */ + if (algorithm_1.tree_isPreceding(node2, node1)) + return interfaces_1.Position.Preceding; + /** + * 10. Return DOCUMENT_POSITION_FOLLOWING. + */ + return interfaces_1.Position.Following; + } + /** + * Returns `true` if given node is an inclusive descendant of this + * node, and `false` otherwise (including when other node is `null`). + * + * @param other - the node to check + */ + contains(other) { + /** + * The contains(other) method, when invoked, must return true if other is an + * inclusive descendant of context object, and false otherwise (including + * when other is null). + */ + if (other === null) + return false; + return algorithm_1.tree_isDescendantOf(this, other, true); + } + /** + * Returns the prefix for a given namespace URI, if present, and + * `null` if not. + * + * @param namespace - the namespace to search + */ + lookupPrefix(namespace) { + /** + * 1. If namespace is null or the empty string, then return null. + * 2. Switch on the context object: + */ + if (!namespace) + return null; + if (util_1.Guard.isElementNode(this)) { + /** + * Return the result of locating a namespace prefix for it using + * namespace. + */ + return algorithm_1.node_locateANamespacePrefix(this, namespace); + } + else if (util_1.Guard.isDocumentNode(this)) { + /** + * Return the result of locating a namespace prefix for its document + * element, if its document element is non-null, and null otherwise. + */ + if (this.documentElement === null) { + return null; + } + else { + return algorithm_1.node_locateANamespacePrefix(this.documentElement, namespace); + } + } + else if (util_1.Guard.isDocumentTypeNode(this) || util_1.Guard.isDocumentFragmentNode(this)) { + return null; + } + else if (util_1.Guard.isAttrNode(this)) { + /** + * Return the result of locating a namespace prefix for its element, + * if its element is non-null, and null otherwise. + */ + if (this._element === null) { + return null; + } + else { + return algorithm_1.node_locateANamespacePrefix(this._element, namespace); + } + } + else { + /** + * Return the result of locating a namespace prefix for its parent + * element, if its parent element is non-null, and null otherwise. + */ + if (this._parent !== null && util_1.Guard.isElementNode(this._parent)) { + return algorithm_1.node_locateANamespacePrefix(this._parent, namespace); + } + else { + return null; + } + } + } + /** + * Returns the namespace URI for a given prefix if present, and `null` + * if not. + * + * @param prefix - the prefix to search + */ + lookupNamespaceURI(prefix) { + /** + * 1. If prefix is the empty string, then set it to null. + * 2. Return the result of running locate a namespace for the context object + * using prefix. + */ + return algorithm_1.node_locateANamespace(this, prefix || null); + } + /** + * Returns `true` if the namespace is the default namespace on this + * node or `false` if not. + * + * @param namespace - the namespace to check + */ + isDefaultNamespace(namespace) { + /** + * 1. If namespace is the empty string, then set it to null. + * 2. Let defaultNamespace be the result of running locate a namespace for + * context object using null. + * 3. Return true if defaultNamespace is the same as namespace, and false otherwise. + */ + if (!namespace) + namespace = null; + const defaultNamespace = algorithm_1.node_locateANamespace(this, null); + return (defaultNamespace === namespace); + } + /** + * Inserts the node `newChild` before the existing child node + * `refChild`. If `refChild` is `null`, inserts `newChild` at the end + * of the list of children. + * + * If `newChild` is a {@link DocumentFragment} object, all of its + * children are inserted, in the same order, before `refChild`. + * + * If `newChild` is already in the tree, it is first removed. + * + * @param newChild - the node to insert + * @param refChild - the node before which the new node must be + * inserted + * + * @returns the newly inserted child node + */ + insertBefore(newChild, refChild) { + /** + * The insertBefore(node, child) method, when invoked, must return the + * result of pre-inserting node into context object before child. + */ + return algorithm_1.mutation_preInsert(newChild, this, refChild); + } + /** + * Adds the node `newChild` to the end of the list of children of this + * node, and returns it. If `newChild` is already in the tree, it is + * first removed. + * + * If `newChild` is a {@link DocumentFragment} object, the entire + * contents of the document fragment are moved into the child list of + * this node. + * + * @param newChild - the node to add + * + * @returns the newly inserted child node + */ + appendChild(newChild) { + /** + * The appendChild(node) method, when invoked, must return the result of + * appending node to context object. + */ + return algorithm_1.mutation_append(newChild, this); + } + /** + * Replaces the child node `oldChild` with `newChild` in the list of + * children, and returns the `oldChild` node. If `newChild` is already + * in the tree, it is first removed. + * + * @param newChild - the new node to put in the child list + * @param oldChild - the node being replaced in the list + * + * @returns the removed child node + */ + replaceChild(newChild, oldChild) { + /** + * The replaceChild(node, child) method, when invoked, must return the + * result of replacing child with node within context object. + */ + return algorithm_1.mutation_replace(oldChild, newChild, this); + } + /** + * Removes the child node indicated by `oldChild` from the list of + * children, and returns it. + * + * @param oldChild - the node being removed from the list + * + * @returns the removed child node + */ + removeChild(oldChild) { + /** + * The removeChild(child) method, when invoked, must return the result of + * pre-removing child from context object. + */ + return algorithm_1.mutation_preRemove(oldChild, this); + } + /** + * Gets the parent event target for the given event. + * + * @param event - an event + */ + _getTheParent(event) { + /** + * A node’s get the parent algorithm, given an event, returns the node’s + * assigned slot, if node is assigned, and node’s parent otherwise. + */ + if (util_1.Guard.isSlotable(this) && algorithm_1.shadowTree_isAssigned(this)) { + return this._assignedSlot; + } + else { + return this._parent; + } + } +} +exports.NodeImpl = NodeImpl; +NodeImpl.ELEMENT_NODE = 1; +NodeImpl.ATTRIBUTE_NODE = 2; +NodeImpl.TEXT_NODE = 3; +NodeImpl.CDATA_SECTION_NODE = 4; +NodeImpl.ENTITY_REFERENCE_NODE = 5; +NodeImpl.ENTITY_NODE = 6; +NodeImpl.PROCESSING_INSTRUCTION_NODE = 7; +NodeImpl.COMMENT_NODE = 8; +NodeImpl.DOCUMENT_NODE = 9; +NodeImpl.DOCUMENT_TYPE_NODE = 10; +NodeImpl.DOCUMENT_FRAGMENT_NODE = 11; +NodeImpl.NOTATION_NODE = 12; +NodeImpl.DOCUMENT_POSITION_DISCONNECTED = 0x01; +NodeImpl.DOCUMENT_POSITION_PRECEDING = 0x02; +NodeImpl.DOCUMENT_POSITION_FOLLOWING = 0x04; +NodeImpl.DOCUMENT_POSITION_CONTAINS = 0x08; +NodeImpl.DOCUMENT_POSITION_CONTAINED_BY = 0x10; +NodeImpl.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20; +/** + * A performance tweak to share an empty set between all node classes. This will + * be overwritten by element, document and document fragment nodes to supply an + * actual set of nodes. + */ +NodeImpl.prototype._children = new util_1.EmptySet(); +/** + * Define constants on prototype. + */ +WebIDLAlgorithm_1.idl_defineConst(NodeImpl.prototype, "ELEMENT_NODE", 1); +WebIDLAlgorithm_1.idl_defineConst(NodeImpl.prototype, "ATTRIBUTE_NODE", 2); +WebIDLAlgorithm_1.idl_defineConst(NodeImpl.prototype, "TEXT_NODE", 3); +WebIDLAlgorithm_1.idl_defineConst(NodeImpl.prototype, "CDATA_SECTION_NODE", 4); +WebIDLAlgorithm_1.idl_defineConst(NodeImpl.prototype, "ENTITY_REFERENCE_NODE", 5); +WebIDLAlgorithm_1.idl_defineConst(NodeImpl.prototype, "ENTITY_NODE", 6); +WebIDLAlgorithm_1.idl_defineConst(NodeImpl.prototype, "PROCESSING_INSTRUCTION_NODE", 7); +WebIDLAlgorithm_1.idl_defineConst(NodeImpl.prototype, "COMMENT_NODE", 8); +WebIDLAlgorithm_1.idl_defineConst(NodeImpl.prototype, "DOCUMENT_NODE", 9); +WebIDLAlgorithm_1.idl_defineConst(NodeImpl.prototype, "DOCUMENT_TYPE_NODE", 10); +WebIDLAlgorithm_1.idl_defineConst(NodeImpl.prototype, "DOCUMENT_FRAGMENT_NODE", 11); +WebIDLAlgorithm_1.idl_defineConst(NodeImpl.prototype, "NOTATION_NODE", 12); +WebIDLAlgorithm_1.idl_defineConst(NodeImpl.prototype, "DOCUMENT_POSITION_DISCONNECTED", 0x01); +WebIDLAlgorithm_1.idl_defineConst(NodeImpl.prototype, "DOCUMENT_POSITION_PRECEDING", 0x02); +WebIDLAlgorithm_1.idl_defineConst(NodeImpl.prototype, "DOCUMENT_POSITION_FOLLOWING", 0x04); +WebIDLAlgorithm_1.idl_defineConst(NodeImpl.prototype, "DOCUMENT_POSITION_CONTAINS", 0x08); +WebIDLAlgorithm_1.idl_defineConst(NodeImpl.prototype, "DOCUMENT_POSITION_CONTAINED_BY", 0x10); +WebIDLAlgorithm_1.idl_defineConst(NodeImpl.prototype, "DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC", 0x20); +//# sourceMappingURL=NodeImpl.js.map + +/***/ }), + +/***/ 938: +/***/ (function(__unusedmodule, exports) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * Represents a cache for storing order between equal objects. + * + * This cache is used when an algorithm compares two objects and finds them to + * be equal but still needs to establish an order between those two objects. + * When two such objects `a` and `b` are passed to the `check` method, a random + * number is generated with `Math.random()`. If the random number is less than + * `0.5` it is assumed that `a < b` otherwise `a > b`. The random number along + * with `a` and `b` is stored in the cache, so that subsequent checks result + * in the same consistent result. + * + * The cache has a size limit which is defined on initialization. + */ +class CompareCache { + /** + * Initializes a new instance of `CompareCache`. + * + * @param limit - maximum number of items to keep in the cache. When the limit + * is exceeded the first item is removed from the cache. + */ + constructor(limit = 1000) { + this._items = new Map(); + this._limit = limit; + } + /** + * Compares and caches the given objects. Returns `true` if `objA < objB` and + * `false` otherwise. + * + * @param objA - an item to compare + * @param objB - an item to compare + */ + check(objA, objB) { + if (this._items.get(objA) === objB) + return true; + else if (this._items.get(objB) === objA) + return false; + const result = (Math.random() < 0.5); + if (result) { + this._items.set(objA, objB); + } + else { + this._items.set(objB, objA); + } + if (this._items.size > this._limit) { + const it = this._items.keys().next(); + /* istanbul ignore else */ + if (!it.done) { + this._items.delete(it.value); + } + } + return result; + } +} +exports.CompareCache = CompareCache; +//# sourceMappingURL=CompareCache.js.map + +/***/ }), + +/***/ 947: +/***/ (function(__unusedmodule, exports) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * Represents an object with lazy initialization. + */ +class Lazy { + /** + * Initializes a new instance of `Lazy`. + * + * @param initFunc - initializer function + */ + constructor(initFunc) { + this._initialized = false; + this._value = undefined; + this._initFunc = initFunc; + } + /** + * Gets the value of the object. + */ + get value() { + if (!this._initialized) { + this._value = this._initFunc(); + this._initialized = true; + } + return this._value; + } +} +exports.Lazy = Lazy; +//# sourceMappingURL=Lazy.js.map + +/***/ }), + +/***/ 950: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const url = __webpack_require__(835); +function getProxyUrl(reqUrl) { + let usingSsl = reqUrl.protocol === 'https:'; + let proxyUrl; + if (checkBypass(reqUrl)) { + return proxyUrl; + } + let proxyVar; + if (usingSsl) { + proxyVar = process.env["https_proxy"] || + process.env["HTTPS_PROXY"]; + } + else { + proxyVar = process.env["http_proxy"] || + process.env["HTTP_PROXY"]; + } + if (proxyVar) { + proxyUrl = url.parse(proxyVar); + } + return proxyUrl; +} +exports.getProxyUrl = getProxyUrl; +function checkBypass(reqUrl) { + if (!reqUrl.hostname) { + return false; + } + let noProxy = process.env["no_proxy"] || process.env["NO_PROXY"] || ''; + if (!noProxy) { + return false; + } + // Determine the request port + let reqPort; + if (reqUrl.port) { + reqPort = Number(reqUrl.port); + } + else if (reqUrl.protocol === 'http:') { + reqPort = 80; + } + else if (reqUrl.protocol === 'https:') { + reqPort = 443; + } + // Format the request hostname and hostname with port + let upperReqHosts = [reqUrl.hostname.toUpperCase()]; + if (typeof reqPort === 'number') { + upperReqHosts.push(`${upperReqHosts[0]}:${reqPort}`); + } + // Compare request host against noproxy + for (let upperNoProxyItem of noProxy.split(',').map(x => x.trim().toUpperCase()).filter(x => x)) { + if (upperReqHosts.some(x => x === upperNoProxyItem)) { + return true; + } + } + return false; +} +exports.checkBypass = checkBypass; + + +/***/ }), + +/***/ 968: +/***/ (function(__unusedmodule, exports) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +class EmptySet { + get size() { + return 0; + } + add(value) { + throw new Error("Cannot add to an empty set."); + } + clear() { + // no-op + } + delete(value) { + return false; + } + forEach(callbackfn, thisArg) { + // no-op + } + has(value) { + return false; + } + [Symbol.iterator]() { + return new EmptySetIterator(); + } + entries() { + return new EmptySetIterator(); + } + keys() { + return new EmptySetIterator(); + } + values() { + return new EmptySetIterator(); + } + get [Symbol.toStringTag]() { + return "EmptySet"; + } +} +exports.EmptySet = EmptySet; +class EmptySetIterator { + [Symbol.iterator]() { + return this; + } + next() { + return { done: true, value: null }; + } +} +//# sourceMappingURL=EmptySet.js.map + +/***/ }), + +/***/ 970: +/***/ (function(__unusedmodule, exports) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * Defines the position of a boundary point relative to another. + */ +var BoundaryPosition; +(function (BoundaryPosition) { + BoundaryPosition[BoundaryPosition["Before"] = 0] = "Before"; + BoundaryPosition[BoundaryPosition["Equal"] = 1] = "Equal"; + BoundaryPosition[BoundaryPosition["After"] = 2] = "After"; +})(BoundaryPosition = exports.BoundaryPosition || (exports.BoundaryPosition = {})); +/** + * Defines the event phase. + */ +var EventPhase; +(function (EventPhase) { + EventPhase[EventPhase["None"] = 0] = "None"; + EventPhase[EventPhase["Capturing"] = 1] = "Capturing"; + EventPhase[EventPhase["AtTarget"] = 2] = "AtTarget"; + EventPhase[EventPhase["Bubbling"] = 3] = "Bubbling"; +})(EventPhase = exports.EventPhase || (exports.EventPhase = {})); +/** + * Defines the type of a node object. + */ +var NodeType; +(function (NodeType) { + NodeType[NodeType["Element"] = 1] = "Element"; + NodeType[NodeType["Attribute"] = 2] = "Attribute"; + NodeType[NodeType["Text"] = 3] = "Text"; + NodeType[NodeType["CData"] = 4] = "CData"; + NodeType[NodeType["EntityReference"] = 5] = "EntityReference"; + NodeType[NodeType["Entity"] = 6] = "Entity"; + NodeType[NodeType["ProcessingInstruction"] = 7] = "ProcessingInstruction"; + NodeType[NodeType["Comment"] = 8] = "Comment"; + NodeType[NodeType["Document"] = 9] = "Document"; + NodeType[NodeType["DocumentType"] = 10] = "DocumentType"; + NodeType[NodeType["DocumentFragment"] = 11] = "DocumentFragment"; + NodeType[NodeType["Notation"] = 12] = "Notation"; // historical +})(NodeType = exports.NodeType || (exports.NodeType = {})); +/** + * Defines the position of a node in the document relative to another + * node. + */ +var Position; +(function (Position) { + Position[Position["Disconnected"] = 1] = "Disconnected"; + Position[Position["Preceding"] = 2] = "Preceding"; + Position[Position["Following"] = 4] = "Following"; + Position[Position["Contains"] = 8] = "Contains"; + Position[Position["ContainedBy"] = 16] = "ContainedBy"; + Position[Position["ImplementationSpecific"] = 32] = "ImplementationSpecific"; +})(Position = exports.Position || (exports.Position = {})); +/** + * Defines the return value of a filter callback. + */ +var FilterResult; +(function (FilterResult) { + FilterResult[FilterResult["Accept"] = 1] = "Accept"; + FilterResult[FilterResult["Reject"] = 2] = "Reject"; + FilterResult[FilterResult["Skip"] = 3] = "Skip"; +})(FilterResult = exports.FilterResult || (exports.FilterResult = {})); +/** + * Defines what to show in node filter. + */ +var WhatToShow; +(function (WhatToShow) { + WhatToShow[WhatToShow["All"] = 4294967295] = "All"; + WhatToShow[WhatToShow["Element"] = 1] = "Element"; + WhatToShow[WhatToShow["Attribute"] = 2] = "Attribute"; + WhatToShow[WhatToShow["Text"] = 4] = "Text"; + WhatToShow[WhatToShow["CDataSection"] = 8] = "CDataSection"; + WhatToShow[WhatToShow["EntityReference"] = 16] = "EntityReference"; + WhatToShow[WhatToShow["Entity"] = 32] = "Entity"; + WhatToShow[WhatToShow["ProcessingInstruction"] = 64] = "ProcessingInstruction"; + WhatToShow[WhatToShow["Comment"] = 128] = "Comment"; + WhatToShow[WhatToShow["Document"] = 256] = "Document"; + WhatToShow[WhatToShow["DocumentType"] = 512] = "DocumentType"; + WhatToShow[WhatToShow["DocumentFragment"] = 1024] = "DocumentFragment"; + WhatToShow[WhatToShow["Notation"] = 2048] = "Notation"; +})(WhatToShow = exports.WhatToShow || (exports.WhatToShow = {})); +/** + * Defines how boundary points are compared. + */ +var HowToCompare; +(function (HowToCompare) { + HowToCompare[HowToCompare["StartToStart"] = 0] = "StartToStart"; + HowToCompare[HowToCompare["StartToEnd"] = 1] = "StartToEnd"; + HowToCompare[HowToCompare["EndToEnd"] = 2] = "EndToEnd"; + HowToCompare[HowToCompare["EndToStart"] = 3] = "EndToStart"; +})(HowToCompare = exports.HowToCompare || (exports.HowToCompare = {})); +//# sourceMappingURL=interfaces.js.map + +/***/ }), + +/***/ 973: +/***/ (function(__unusedmodule, exports) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * Represents a cache of objects with a size limit. + */ +class ObjectCache { + /** + * Initializes a new instance of `ObjectCache`. + * + * @param limit - maximum number of items to keep in the cache. When the limit + * is exceeded the first item is removed from the cache. + */ + constructor(limit = 1000) { + this._items = new Map(); + this._limit = limit; + } + /** + * Gets an item from the cache. + * + * @param key - object key + */ + get(key) { + return this._items.get(key); + } + /** + * Adds a new item to the cache. + * + * @param key - object key + * @param value - object value + */ + set(key, value) { + this._items.set(key, value); + if (this._items.size > this._limit) { + const it = this._items.keys().next(); + /* istanbul ignore else */ + if (!it.done) { + this._items.delete(it.value); + } + } + } + /** + * Removes an item from the cache. + * + * @param item - an item + */ + delete(key) { + return this._items.delete(key); + } + /** + * Determines if an item is in the cache. + * + * @param item - an item + */ + has(key) { + return this._items.has(key); + } + /** + * Removes all items from the cache. + */ + clear() { + this._items.clear(); + } + /** + * Gets the number of items in the cache. + */ + get size() { return this._items.size; } + /** + * Applies the given callback function to all elements of the cache. + */ + forEach(callback, thisArg) { + this._items.forEach((v, k) => callback.call(thisArg, k, v)); + } + /** + * Iterates through the items in the set. + */ + *keys() { + yield* this._items.keys(); + } + /** + * Iterates through the items in the set. + */ + *values() { + yield* this._items.values(); + } + /** + * Iterates through the items in the set. + */ + *entries() { + yield* this._items.entries(); + } + /** + * Iterates through the items in the set. + */ + *[Symbol.iterator]() { + yield* this._items; + } + /** + * Returns the string tag of the cache. + */ + get [Symbol.toStringTag]() { + return "ObjectCache"; + } +} +exports.ObjectCache = ObjectCache; +//# sourceMappingURL=ObjectCache.js.map + +/***/ }), + +/***/ 983: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const util_1 = __webpack_require__(918); +const algorithm_1 = __webpack_require__(163); +/** + * Represents a mixin that extends child nodes that can have siblings + * including doctypes. This mixin is implemented by {@link Element}, + * {@link CharacterData} and {@link DocumentType}. + */ +class ChildNodeImpl { + /** @inheritdoc */ + before(...nodes) { + /** + * 1. Let parent be context object’s parent. + * 2. If parent is null, then return. + */ + const context = util_1.Cast.asNode(this); + const parent = context._parent; + if (parent === null) + return; + /** + * 3. Let viablePreviousSibling be context object’s first preceding + * sibling not in nodes, and null otherwise. + */ + let viablePreviousSibling = context._previousSibling; + let flag = true; + while (flag && viablePreviousSibling) { + flag = false; + for (let i = 0; i < nodes.length; i++) { + const child = nodes[i]; + if (child === viablePreviousSibling) { + viablePreviousSibling = viablePreviousSibling._previousSibling; + flag = true; + break; + } + } + } + /** + * 4. Let node be the result of converting nodes into a node, given nodes + * and context object’s node document. + */ + const node = algorithm_1.parentNode_convertNodesIntoANode(nodes, context._nodeDocument); + /** + * 5. If viablePreviousSibling is null, set it to parent’s first child, + * and to viablePreviousSibling’s next sibling otherwise. + */ + if (viablePreviousSibling === null) + viablePreviousSibling = parent._firstChild; + else + viablePreviousSibling = viablePreviousSibling._nextSibling; + /** + * 6. Pre-insert node into parent before viablePreviousSibling. + */ + algorithm_1.mutation_preInsert(node, parent, viablePreviousSibling); + } + /** @inheritdoc */ + after(...nodes) { + /** + * 1. Let parent be context object’s parent. + * 2. If parent is null, then return. + */ + const context = util_1.Cast.asNode(this); + const parent = context._parent; + if (!parent) + return; + /** + * 3. Let viableNextSibling be context object’s first following sibling not + * in nodes, and null otherwise. + */ + let viableNextSibling = context._nextSibling; + let flag = true; + while (flag && viableNextSibling) { + flag = false; + for (let i = 0; i < nodes.length; i++) { + const child = nodes[i]; + if (child === viableNextSibling) { + viableNextSibling = viableNextSibling._nextSibling; + flag = true; + break; + } + } + } + /** + * 4. Let node be the result of converting nodes into a node, given nodes + * and context object’s node document. + */ + const node = algorithm_1.parentNode_convertNodesIntoANode(nodes, context._nodeDocument); + /** + * 5. Pre-insert node into parent before viableNextSibling. + */ + algorithm_1.mutation_preInsert(node, parent, viableNextSibling); + } + /** @inheritdoc */ + replaceWith(...nodes) { + /** + * 1. Let parent be context object’s parent. + * 2. If parent is null, then return. + */ + const context = util_1.Cast.asNode(this); + const parent = context._parent; + if (!parent) + return; + /** + * 3. Let viableNextSibling be context object’s first following sibling not + * in nodes, and null otherwise. + */ + let viableNextSibling = context._nextSibling; + let flag = true; + while (flag && viableNextSibling) { + flag = false; + for (let i = 0; i < nodes.length; i++) { + const child = nodes[i]; + if (child === viableNextSibling) { + viableNextSibling = viableNextSibling._nextSibling; + flag = true; + break; + } + } + } + /** + * 4. Let node be the result of converting nodes into a node, given nodes + * and context object’s node document. + */ + const node = algorithm_1.parentNode_convertNodesIntoANode(nodes, context._nodeDocument); + /** + * 5. If context object’s parent is parent, replace the context object with + * node within parent. + * _Note:_ Context object could have been inserted into node. + * 6. Otherwise, pre-insert node into parent before viableNextSibling. + */ + if (context._parent === parent) + algorithm_1.mutation_replace(context, node, parent); + else + algorithm_1.mutation_preInsert(node, parent, viableNextSibling); + } + /** @inheritdoc */ + remove() { + /** + * 1. If context object’s parent is null, then return. + * 2. Remove the context object from context object’s parent. + */ + const context = util_1.Cast.asNode(this); + const parent = context._parent; + if (!parent) + return; + algorithm_1.mutation_remove(context, parent); + } +} +exports.ChildNodeImpl = ChildNodeImpl; +//# sourceMappingURL=ChildNodeImpl.js.map + +/***/ }), + +/***/ 986: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const tr = __webpack_require__(9); +/** + * Exec a command. + * Output will be streamed to the live console. + * Returns promise with return code + * + * @param commandLine command to execute (can include additional args). Must be correctly escaped. + * @param args optional arguments for tool. Escaping is handled by the lib. + * @param options optional exec options. See ExecOptions + * @returns Promise exit code + */ +function exec(commandLine, args, options) { + return __awaiter(this, void 0, void 0, function* () { + const commandArgs = tr.argStringToArray(commandLine); + if (commandArgs.length === 0) { + throw new Error(`Parameter 'commandLine' cannot be null or empty.`); + } + // Path to tool to execute should be first arg + const toolPath = commandArgs[0]; + args = commandArgs.slice(1).concat(args || []); + const runner = new tr.ToolRunner(toolPath, args, options); + return runner.exec(); + }); +} +exports.exec = exec; +//# sourceMappingURL=exec.js.map + +/***/ }), + +/***/ 990: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const algorithm_1 = __webpack_require__(163); +/** + * Represents a controller that allows to abort DOM requests. + */ +class AbortControllerImpl { + /** + * Initializes a new instance of `AbortController`. + */ + constructor() { + /** + * 1. Let signal be a new AbortSignal object. + * 2. Let controller be a new AbortController object whose signal is signal. + * 3. Return controller. + */ + this._signal = algorithm_1.create_abortSignal(); + } + /** @inheritdoc */ + get signal() { return this._signal; } + /** @inheritdoc */ + abort() { + algorithm_1.abort_signalAbort(this._signal); + } +} +exports.AbortControllerImpl = AbortControllerImpl; +//# sourceMappingURL=AbortControllerImpl.js.map + +/***/ }), + +/***/ 995: +/***/ (function(__unusedmodule, exports) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * Represents a cache of objects with a size limit. + */ +class ObjectCache { + /** + * Initializes a new instance of `ObjectCache`. + * + * @param limit - maximum number of items to keep in the cache. When the limit + * is exceeded the first item is removed from the cache. + */ + constructor(limit = 1000) { + this._items = new Map(); + this._limit = limit; + } + /** + * Gets an item from the cache. + * + * @param key - object key + */ + get(key) { + return this._items.get(key); + } + /** + * Adds a new item to the cache. + * + * @param key - object key + * @param value - object value + */ + set(key, value) { + this._items.set(key, value); + if (this._items.size > this._limit) { + const it = this._items.keys().next(); + /* istanbul ignore else */ + if (!it.done) { + this._items.delete(it.value); + } + } + } + /** + * Removes an item from the cache. + * + * @param item - an item + */ + delete(key) { + return this._items.delete(key); + } + /** + * Determines if an item is in the cache. + * + * @param item - an item + */ + has(key) { + return this._items.has(key); + } + /** + * Removes all items from the cache. + */ + clear() { + this._items.clear(); + } + /** + * Gets the number of items in the cache. + */ + get size() { return this._items.size; } + /** + * Applies the given callback function to all elements of the cache. + */ + forEach(callback, thisArg) { + this._items.forEach((v, k) => callback.call(thisArg, k, v)); + } + /** + * Iterates through the items in the set. + */ + *keys() { + yield* this._items.keys(); + } + /** + * Iterates through the items in the set. + */ + *values() { + yield* this._items.values(); + } + /** + * Iterates through the items in the set. + */ + *entries() { + yield* this._items.entries(); + } + /** + * Iterates through the items in the set. + */ + *[Symbol.iterator]() { + yield* this._items; + } + /** + * Returns the string tag of the cache. + */ + get [Symbol.toStringTag]() { + return "ObjectCache"; + } +} +exports.ObjectCache = ObjectCache; +//# sourceMappingURL=ObjectCache.js.map + +/***/ }) + +/******/ }); \ No newline at end of file diff --git a/dist/unzip b/dist/setup/unzip similarity index 100% rename from dist/unzip rename to dist/setup/unzip diff --git a/package-lock.json b/package-lock.json index 66e0b6d..b534287 100644 --- a/package-lock.json +++ b/package-lock.json @@ -430,6 +430,74 @@ "@types/yargs": "^13.0.0" } }, + "@oozcitak/dom": { + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/@oozcitak/dom/-/dom-1.15.5.tgz", + "integrity": "sha512-L6v3Mwb0TaYBYgeYlIeBaHnc+2ZEaDSbFiRm5KmqZQSoBlbPlf+l6aIH/sD5GUf2MYwULw00LT7+dOnEuAEC0A==", + "requires": { + "@oozcitak/infra": "1.0.5", + "@oozcitak/url": "1.0.0", + "@oozcitak/util": "8.0.0" + }, + "dependencies": { + "@oozcitak/util": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@oozcitak/util/-/util-8.0.0.tgz", + "integrity": "sha512-+9Hq6yuoq/3TRV/n/xcpydGBq2qN2/DEDMqNTG7rm95K6ZE2/YY/sPyx62+1n8QsE9O26e5M1URlXsk+AnN9Jw==" + } + } + }, + "@oozcitak/infra": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@oozcitak/infra/-/infra-1.0.5.tgz", + "integrity": "sha512-o+zZH7M6l5e3FaAWy3ojaPIVN5eusaYPrKm6MZQt0DKNdgXa2wDYExjpP0t/zx+GoQgQKzLu7cfD8rHCLt8JrQ==", + "requires": { + "@oozcitak/util": "8.0.0" + }, + "dependencies": { + "@oozcitak/util": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@oozcitak/util/-/util-8.0.0.tgz", + "integrity": "sha512-+9Hq6yuoq/3TRV/n/xcpydGBq2qN2/DEDMqNTG7rm95K6ZE2/YY/sPyx62+1n8QsE9O26e5M1URlXsk+AnN9Jw==" + } + } + }, + "@oozcitak/url": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@oozcitak/url/-/url-1.0.0.tgz", + "integrity": "sha512-LGrMeSxeLzsdaitxq3ZmBRVOrlRRQIgNNci6L0VRnOKlJFuRIkNm4B+BObXPCJA6JT5bEJtrrwjn30jueHJYZQ==", + "requires": { + "@oozcitak/infra": "1.0.3", + "@oozcitak/util": "1.0.2" + }, + "dependencies": { + "@oozcitak/infra": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@oozcitak/infra/-/infra-1.0.3.tgz", + "integrity": "sha512-9O2wxXGnRzy76O1XUxESxDGsXT5kzETJPvYbreO4mv6bqe1+YSuux2cZTagjJ/T4UfEwFJz5ixanOqB0QgYAag==", + "requires": { + "@oozcitak/util": "1.0.1" + }, + "dependencies": { + "@oozcitak/util": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@oozcitak/util/-/util-1.0.1.tgz", + "integrity": "sha512-dFwFqcKrQnJ2SapOmRD1nQWEZUtbtIy9Y6TyJquzsalWNJsKIPxmTI0KG6Ypyl8j7v89L2wixH9fQDNrF78hKg==" + } + } + }, + "@oozcitak/util": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@oozcitak/util/-/util-1.0.2.tgz", + "integrity": "sha512-4n8B1cWlJleSOSba5gxsMcN4tO8KkkcvXhNWW+ADqvq9Xj+Lrl9uCa90GRpjekqQJyt84aUX015DG81LFpZYXA==" + } + } + }, + "@oozcitak/util": { + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/@oozcitak/util/-/util-8.3.3.tgz", + "integrity": "sha512-Ufpab7G5PfnEhQyy5kDg9C8ltWJjsVT1P/IYqacjstaqydG4Q21HAT2HUZQYBrC/a1ZLKCz87pfydlDvv8y97w==" + }, "@types/babel__core": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.3.tgz", @@ -4955,6 +5023,16 @@ "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", "dev": true }, + "xmlbuilder2": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/xmlbuilder2/-/xmlbuilder2-2.1.2.tgz", + "integrity": "sha512-PI710tmtVlQ5VmwzbRTuhmVhKnj9pM8Si+iOZCV2g2SNo3gCrpzR2Ka9wNzZtqfD+mnP+xkrqoNy0sjKZqP4Dg==", + "requires": { + "@oozcitak/dom": "1.15.5", + "@oozcitak/infra": "1.0.5", + "@oozcitak/util": "8.3.3" + } + }, "y18n": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", diff --git a/package.json b/package.json index 57a69f5..02526b7 100644 --- a/package.json +++ b/package.json @@ -5,11 +5,11 @@ "description": "setup java action", "main": "dist/index.js", "scripts": { - "build": "ncc build src/setup-java.ts", + "build": "ncc build -o dist/setup src/setup-java.ts && ncc build -o dist/cleanup src/cleanup-java.ts", "format": "prettier --write **/*.ts", "format-check": "prettier --check **/*.ts", "prerelease": "npm run-script build", - "release": "git add -f dist/index.js", + "release": "git add -f dist/setup/index.js dist/cleanup/index.js", "test": "jest" }, "repository": { @@ -29,7 +29,8 @@ "@actions/http-client": "^1.0.6", "@actions/io": "^1.0.0", "@actions/tool-cache": "^1.3.1", - "semver": "^6.1.1" + "semver": "^6.1.1", + "xmlbuilder2": "^2.1.2" }, "devDependencies": { "@types/jest": "^24.0.13", diff --git a/src/auth.ts b/src/auth.ts index 2e7c6e8..9a5807a 100644 --- a/src/auth.ts +++ b/src/auth.ts @@ -3,60 +3,72 @@ import * as os from 'os'; import * as path from 'path'; import * as core from '@actions/core'; import * as io from '@actions/io'; +import {create as xmlCreate} from 'xmlbuilder2'; export const M2_DIR = '.m2'; export const SETTINGS_FILE = 'settings.xml'; -export const DEFAULT_ID = 'github'; -export const DEFAULT_USERNAME = 'GITHUB_ACTOR'; -export const DEFAULT_PASSWORD = 'GITHUB_TOKEN'; - export async function configAuthentication( - id = DEFAULT_ID, - username = DEFAULT_USERNAME, - password = DEFAULT_PASSWORD + id: string, + username: string, + password: string, + gpgPassphrase: string | undefined = undefined ) { console.log( `creating ${SETTINGS_FILE} with server-id: ${id};`, - `environment variables: username=\$${username} and password=\$${password}` + 'environment variables:', + `username=\$${username},`, + `password=\$${password},`, + `and gpg-passphrase=${gpgPassphrase ? '$' + gpgPassphrase : null}` ); // when an alternate m2 location is specified use only that location (no .m2 directory) // otherwise use the home/.m2/ path - const directory: string = path.join( + const settingsDirectory: string = path.join( core.getInput('settings-path') || os.homedir(), core.getInput('settings-path') ? '' : M2_DIR ); - await io.mkdirP(directory); - core.debug(`created directory ${directory}`); - await write(directory, generate(id, username, password)); -} - -function escapeXML(value: string) { - return value - .replace(/&/g, '&') - .replace(//g, '>') - .replace(/"/g, '"') - .replace(/'/g, '''); + await io.mkdirP(settingsDirectory); + core.debug(`created directory ${settingsDirectory}`); + await write( + settingsDirectory, + generate(id, username, password, gpgPassphrase) + ); } // only exported for testing purposes export function generate( - id = DEFAULT_ID, - username = DEFAULT_USERNAME, - password = DEFAULT_PASSWORD + id: string, + username: string, + password: string, + gpgPassphrase: string | undefined = undefined ) { - return ` - - - - ${escapeXML(id)} - \${env.${escapeXML(username)}} - \${env.${escapeXML(password)}} - - - - `; + const xmlObj: {[key: string]: any} = { + settings: { + '@xmlns': 'http://maven.apache.org/SETTINGS/1.0.0', + '@xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance', + '@xsi:schemaLocation': + 'http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd', + servers: { + server: [ + { + id: id, + username: `\${env.${username}}`, + password: `\${env.${password}}` + } + ] + } + } + }; + + if (gpgPassphrase) { + const gpgServer = { + id: 'gpg.passphrase', + passphrase: `\${env.${gpgPassphrase}}` + }; + xmlObj.settings.servers.server.push(gpgServer); + } + + return xmlCreate(xmlObj).end({headless: true, prettyPrint: true, width: 80}); } async function write(directory: string, settings: string) { diff --git a/src/cleanup-java.ts b/src/cleanup-java.ts new file mode 100644 index 0000000..9c057b6 --- /dev/null +++ b/src/cleanup-java.ts @@ -0,0 +1,16 @@ +import * as core from '@actions/core'; +import * as gpg from './gpg'; + +async function run() { + if (core.getInput('gpg-private-key', {required: false})) { + console.log('removing private key from keychain'); + try { + const keyFingerprint = core.getState('gpg-private-key-fingerprint'); + await gpg.deleteKey(keyFingerprint); + } catch (error) { + core.setFailed(error.message); + } + } +} + +run(); diff --git a/src/gpg.ts b/src/gpg.ts new file mode 100644 index 0000000..c8e5d7b --- /dev/null +++ b/src/gpg.ts @@ -0,0 +1,58 @@ +import * as fs from 'fs'; +import * as path from 'path'; +import * as io from '@actions/io'; +import * as exec from '@actions/exec'; +import * as util from './util'; +import {ExecOptions} from '@actions/exec/lib/interfaces'; + +export const PRIVATE_KEY_FILE = path.join(util.getTempDir(), 'private-key.asc'); + +const PRIVATE_KEY_FINGERPRINT_REGEX = /\w{40}/; + +export async function importKey(privateKey: string) { + fs.writeFileSync(PRIVATE_KEY_FILE, privateKey, { + encoding: 'utf-8', + flag: 'w' + }); + + let output = ''; + + const options: ExecOptions = { + silent: true, + listeners: { + stdout: (data: Buffer) => { + output += data.toString(); + } + } + }; + + await exec.exec( + 'gpg', + [ + '--batch', + '--import-options', + 'import-show', + '--import', + PRIVATE_KEY_FILE + ], + options + ); + + await io.rmRF(PRIVATE_KEY_FILE); + + const match = output.match(PRIVATE_KEY_FINGERPRINT_REGEX); + return match && match[0]; +} + +export async function deleteKey(keyFingerprint: string) { + await exec.exec( + 'gpg', + ['--batch', '--yes', '--delete-secret-keys', keyFingerprint], + {silent: true} + ); + await exec.exec( + 'gpg', + ['--batch', '--yes', '--delete-keys', keyFingerprint], + {silent: true} + ); +} diff --git a/src/installer.ts b/src/installer.ts index cce8fa3..d7a4471 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -1,5 +1,3 @@ -let tempDirectory = process.env['RUNNER_TEMP'] || ''; - import * as core from '@actions/core'; import * as io from '@actions/io'; import * as exec from '@actions/exec'; @@ -8,23 +6,10 @@ import * as tc from '@actions/tool-cache'; import * as fs from 'fs'; import * as path from 'path'; import * as semver from 'semver'; +import * as util from './util'; -const IS_WINDOWS = process.platform === 'win32'; - -if (!tempDirectory) { - let baseLocation; - if (IS_WINDOWS) { - // On windows use the USERPROFILE env variable - baseLocation = process.env['USERPROFILE'] || 'C:\\'; - } else { - if (process.platform === 'darwin') { - baseLocation = '/Users'; - } else { - baseLocation = '/home'; - } - } - tempDirectory = path.join(baseLocation, 'actions', 'temp'); -} +const tempDirectory = util.getTempDir(); +const IS_WINDOWS = util.isWindows(); export async function getJava( version: string, diff --git a/src/setup-java.ts b/src/setup-java.ts index d039217..04e3bf1 100644 --- a/src/setup-java.ts +++ b/src/setup-java.ts @@ -1,10 +1,20 @@ import * as core from '@actions/core'; import * as installer from './installer'; import * as auth from './auth'; +import * as gpg from './gpg'; import * as path from 'path'; +const DEFAULT_ID = 'github'; +const DEFAULT_USERNAME = 'GITHUB_ACTOR'; +const DEFAULT_PASSWORD = 'GITHUB_TOKEN'; +const DEFAULT_GPG_PRIVATE_KEY = undefined; +const DEFAULT_GPG_PASSPHRASE = 'GPG_PASSPHRASE'; + async function run() { try { + // Set secrets before use + core.setSecret('gpg-private-key'); + let version = core.getInput('version'); if (!version) { version = core.getInput('java-version', {required: true}); @@ -15,16 +25,28 @@ async function run() { await installer.getJava(version, arch, jdkFile, javaPackage); - const matchersPath = path.join(__dirname, '..', '.github'); + const matchersPath = path.join(__dirname, '..', '..', '.github'); console.log(`##[add-matcher]${path.join(matchersPath, 'java.json')}`); - const id = core.getInput('server-id', {required: false}) || undefined; + const id = core.getInput('server-id', {required: false}) || DEFAULT_ID; const username = - core.getInput('server-username', {required: false}) || undefined; + core.getInput('server-username', {required: false}) || DEFAULT_USERNAME; const password = - core.getInput('server-password', {required: false}) || undefined; + core.getInput('server-password', {required: false}) || DEFAULT_PASSWORD; + const gpgPrivateKey = + core.getInput('gpg-private-key', {required: false}) || + DEFAULT_GPG_PRIVATE_KEY; + const gpgPassphrase = + core.getInput('gpg-passphrase', {required: false}) || + (gpgPrivateKey ? DEFAULT_GPG_PASSPHRASE : undefined); - await auth.configAuthentication(id, username, password); + await auth.configAuthentication(id, username, password, gpgPassphrase); + + if (gpgPrivateKey) { + console.log('importing private key'); + const keyFingerprint = (await gpg.importKey(gpgPrivateKey)) || ''; + core.saveState('gpg-private-key-fingerprint', keyFingerprint); + } } catch (error) { core.setFailed(error.message); } diff --git a/src/util.ts b/src/util.ts new file mode 100644 index 0000000..671727c --- /dev/null +++ b/src/util.ts @@ -0,0 +1,26 @@ +import * as path from 'path'; + +export function getTempDir() { + let tempDirectory = process.env.RUNNER_TEMP; + if (tempDirectory === undefined) { + let baseLocation; + if (isWindows()) { + // On windows use the USERPROFILE env variable + baseLocation = process.env['USERPROFILE'] + ? process.env['USERPROFILE'] + : 'C:\\'; + } else { + if (process.platform === 'darwin') { + baseLocation = '/Users'; + } else { + baseLocation = '/home'; + } + } + tempDirectory = path.join(baseLocation, 'actions', 'temp'); + } + return tempDirectory; +} + +export function isWindows() { + return process.platform === 'win32'; +}